Browse Source

Allow to load next and previous chapter for horizontal readers

inorichi 9 years ago
parent
commit
e6c230cbe3

+ 28 - 0
app/src/main/java/eu/kanade/mangafeed/data/database/DatabaseHelper.java

@@ -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)

+ 7 - 6
app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java

@@ -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;

+ 6 - 8
app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderActivity.java

@@ -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);
     }

+ 74 - 13
app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java

@@ -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);
+        }
+    }
 }

+ 14 - 0
app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/base/BaseReader.java

@@ -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();

+ 2 - 2
app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/LeftToRightReader.java

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

+ 2 - 2
app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/RightToLeftReader.java

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

+ 1 - 1
app/src/main/res/layout/activity_reader.xml

@@ -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>