Allow to load next and previous chapter for horizontal readers

This commit is contained in:
inorichi 2015-11-15 21:21:12 +01:00
parent a055cc07d8
commit e6c230cbe3
8 changed files with 134 additions and 32 deletions

View File

@ -167,6 +167,34 @@ public class DatabaseHelper {
.prepare();
}
public PreparedGetListOfObjects<Chapter> getNextChapter(Chapter chapter) {
return db.get()
.listOfObjects(Chapter.class)
.withQuery(Query.builder()
.table(ChaptersTable.TABLE)
.where(ChaptersTable.COLUMN_MANGA_ID + "=? AND " +
ChaptersTable.COLUMN_CHAPTER_NUMBER + ">?")
.whereArgs(chapter.manga_id, chapter.chapter_number)
.orderBy(ChaptersTable.COLUMN_CHAPTER_NUMBER)
.limit(1)
.build())
.prepare();
}
public PreparedGetListOfObjects<Chapter> getPreviousChapter(Chapter chapter) {
return db.get()
.listOfObjects(Chapter.class)
.withQuery(Query.builder()
.table(ChaptersTable.TABLE)
.where(ChaptersTable.COLUMN_MANGA_ID + "=? AND " +
ChaptersTable.COLUMN_CHAPTER_NUMBER + "<?")
.whereArgs(chapter.manga_id, chapter.chapter_number)
.orderBy(ChaptersTable.COLUMN_CHAPTER_NUMBER + " DESC")
.limit(1)
.build())
.prepare();
}
public PreparedPutObject<Chapter> insertChapter(Chapter chapter) {
return db.put()
.object(chapter)

View File

@ -9,15 +9,16 @@ import javax.inject.Inject;
import de.greenrobot.event.EventBus;
import eu.kanade.mangafeed.data.database.DatabaseHelper;
import eu.kanade.mangafeed.data.database.models.Chapter;
import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.data.download.DownloadManager;
import eu.kanade.mangafeed.data.preference.PreferencesHelper;
import eu.kanade.mangafeed.data.source.SourceManager;
import eu.kanade.mangafeed.data.database.models.Chapter;
import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.data.source.base.Source;
import eu.kanade.mangafeed.data.source.model.Page;
import eu.kanade.mangafeed.event.ChapterCountEvent;
import eu.kanade.mangafeed.event.DownloadChaptersEvent;
import eu.kanade.mangafeed.event.SourceMangaChapterEvent;
import eu.kanade.mangafeed.data.source.base.Source;
import eu.kanade.mangafeed.ui.base.presenter.BasePresenter;
import eu.kanade.mangafeed.util.EventBusHook;
import eu.kanade.mangafeed.util.PostResult;
@ -123,6 +124,7 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
.subscribeOn(Schedulers.io())
.map(chapter -> {
chapter.read = read;
if (!read) chapter.last_page_read = 0;
return chapter;
})
.toList()
@ -153,10 +155,9 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
public void checkIsChapterDownloaded(Chapter chapter) {
File dir = downloadManager.getAbsoluteChapterDirectory(source, manga, chapter);
File pageList = new File(dir, DownloadManager.PAGE_LIST_FILE);
List<Page> pageList = downloadManager.getSavedPageList(source, manga, chapter);
if (dir.exists() && pageList.exists() && downloadManager
.getSavedPageList(source, manga, chapter).size() + 1 == dir.listFiles().length) {
if (pageList != null && pageList.size() + 1 == dir.listFiles().length) {
chapter.downloaded = Chapter.DOWNLOADED;
} else {
chapter.downloaded = Chapter.NOT_DOWNLOADED;

View File

@ -32,7 +32,7 @@ import nucleus.factory.RequiresPresenter;
public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
@Bind(R.id.page_number) TextView pageNumber;
@Bind(R.id.viewer) FrameLayout container;
@Bind(R.id.reader) FrameLayout container;
@Inject PreferencesHelper prefs;
@ -59,12 +59,15 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
if (prefs.useFullscreenSet())
enableFullScreen();
viewer = getViewer();
enableHardwareAcceleration();
viewer = getViewer();
}
public void onPageListReady(List<Page> pages) {
if (viewer != null)
viewer.destroySubscriptions();
viewer = getViewer();
viewer.onPageListReady(pages);
viewer.updatePageNumber();
}
@ -81,11 +84,6 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
public void setSelectedPage(int pageIndex) {
viewer.setSelectedPage(pageIndex);
}

View File

@ -9,17 +9,18 @@ import javax.inject.Inject;
import de.greenrobot.event.EventBus;
import eu.kanade.mangafeed.data.database.DatabaseHelper;
import eu.kanade.mangafeed.data.download.DownloadManager;
import eu.kanade.mangafeed.data.preference.PreferencesHelper;
import eu.kanade.mangafeed.data.database.models.Chapter;
import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.data.download.DownloadManager;
import eu.kanade.mangafeed.data.preference.PreferencesHelper;
import eu.kanade.mangafeed.data.source.base.Source;
import eu.kanade.mangafeed.data.source.model.Page;
import eu.kanade.mangafeed.event.SourceMangaChapterEvent;
import eu.kanade.mangafeed.data.source.base.Source;
import eu.kanade.mangafeed.ui.base.presenter.BasePresenter;
import eu.kanade.mangafeed.util.EventBusHook;
import icepick.State;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import timber.log.Timber;
@ -33,10 +34,15 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
private Source source;
private Manga manga;
private Chapter chapter;
private Chapter nextChapter;
private Chapter previousChapter;
private List<Page> pageList;
private boolean isDownloaded;
@State int currentPage;
private Subscription nextChapterSubscription;
private Subscription previousChapterSubscription;
private static final int GET_PAGE_LIST = 1;
private static final int GET_PAGE_IMAGES = 2;
@ -47,7 +53,8 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
restartableLatestCache(GET_PAGE_LIST,
() -> getPageListObservable()
.doOnNext(pages -> pageList = pages)
.doOnCompleted( () -> start(GET_PAGE_IMAGES) ),
.doOnCompleted(this::getAdjacentChapters)
.doOnCompleted(() -> start(GET_PAGE_IMAGES)),
(view, pages) -> {
view.onPageListReady(pages);
if (currentPage != 0)
@ -76,24 +83,37 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
@Override
protected void onDestroy() {
if (!isDownloaded)
source.savePageList(chapter.url, pageList);
saveChapterProgress();
onChapterChange();
super.onDestroy();
}
@EventBusHook
public void onEventMainThread(SourceMangaChapterEvent event) {
EventBus.getDefault().removeStickyEvent(event);
source = event.getSource();
manga = event.getManga();
chapter = event.getChapter();
isDownloaded = chapter.downloaded == Chapter.DOWNLOADED;
loadChapter(event.getChapter());
}
private void loadChapter(Chapter chapter) {
this.chapter = chapter;
isDownloaded = isChapterDownloaded(chapter);
if (chapter.last_page_read != 0 && !chapter.read)
currentPage = chapter.last_page_read;
else
currentPage = 0;
// Reset next and previous chapter. They have to be fetched again
nextChapter = null;
previousChapter = null;
start(GET_PAGE_LIST);
}
EventBus.getDefault().removeStickyEvent(SourceMangaChapterEvent.class);
private void onChapterChange() {
if (!isDownloaded)
source.savePageList(chapter.url, pageList);
saveChapterProgress();
}
private Observable<List<Page>> getPageListObservable() {
@ -117,15 +137,17 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
File chapterDir = downloadManager.getAbsoluteChapterDirectory(source, manga, chapter);
pages = Observable.from(pageList)
.flatMap(page -> downloadManager.getDownloadedImage(page, source, chapterDir))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
.flatMap(page -> downloadManager.getDownloadedImage(page, source, chapterDir));
}
return pages
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
public void retryPage(Page page) {
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
@ -137,4 +159,43 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
}
db.insertChapter(chapter).executeAsBlocking();
}
private void getAdjacentChapters() {
if (nextChapterSubscription != null)
remove(nextChapterSubscription);
add(nextChapterSubscription = db.getNextChapter(chapter).createObservable()
.flatMap(Observable::from)
.subscribeOn(Schedulers.io())
.subscribe(result -> nextChapter = result));
if (previousChapterSubscription != null)
remove(previousChapterSubscription);
add(previousChapterSubscription = db.getPreviousChapter(chapter).createObservable()
.flatMap(Observable::from)
.subscribeOn(Schedulers.io())
.subscribe(result -> previousChapter = result));
}
public boolean isChapterDownloaded(Chapter chapter) {
File dir = downloadManager.getAbsoluteChapterDirectory(source, manga, chapter);
List<Page> pageList = downloadManager.getSavedPageList(source, manga, chapter);
return pageList != null && pageList.size() + 1 == dir.listFiles().length;
}
public void loadNextChapter() {
if (nextChapter != null) {
onChapterChange();
loadChapter(nextChapter);
}
}
public void loadPreviousChapter() {
if (previousChapter != null) {
onChapterChange();
loadChapter(previousChapter);
}
}
}

View File

@ -33,6 +33,20 @@ public abstract class BaseReader {
return getCurrentPageIndex(currentPosition);
}
public void retryPage(Page page) {
activity.getPresenter().retryPage(page);
}
public void requestNextChapter() {
activity.getPresenter().setCurrentPage(getCurrentPosition());
activity.getPresenter().loadNextChapter();
}
public void requestPreviousChapter() {
activity.getPresenter().setCurrentPage(getCurrentPosition());
activity.getPresenter().loadPreviousChapter();
}
public void destroySubscriptions() {}
public abstract int getTotalPages();

View File

@ -12,12 +12,12 @@ public class LeftToRightReader extends HorizontalReader {
@Override
public void onFirstPageOut() {
// TODO
requestPreviousChapter();
}
@Override
public void onLastPageOut() {
// TODO
requestNextChapter();
}
}

View File

@ -30,12 +30,12 @@ public class RightToLeftReader extends HorizontalReader {
@Override
public void onFirstPageOut() {
// TODO
requestNextChapter();
}
@Override
public void onLastPageOut() {
// TODO
requestPreviousChapter();
}
}

View File

@ -4,7 +4,7 @@
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/viewer"
android:id="@+id/reader"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>