diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c6e93a502..9dfb27f33 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,6 +12,7 @@ android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" + android:hardwareAccelerated="true" android:theme="@style/AppTheme" > @@ -27,8 +28,7 @@ + android:parentActivityName=".ui.manga.MangaActivity"> diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderActivity.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderActivity.java index 7101716f5..0f512b39f 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderActivity.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderActivity.java @@ -9,6 +9,8 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; import android.view.Surface; import android.view.View; import android.view.WindowManager; @@ -111,6 +113,16 @@ public class ReaderActivity extends BaseRxActivity { super.onDestroy(); } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + return readerMenu.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + return readerMenu.onOptionsItemSelected(item) || super.onOptionsItemSelected(item); + } + @Override protected void onSaveInstanceState(@NonNull Bundle outState) { Icepick.saveInstanceState(readerMenu, outState); @@ -131,6 +143,10 @@ public class ReaderActivity extends BaseRxActivity { readerMenu.onChapterReady(pages.size(), manga, chapter, currentPage); } + public void onAdjacentChapters(Chapter previous, Chapter next) { + readerMenu.onAdjacentChapters(previous, next); + } + private BaseReader createViewer(Manga manga) { int mangaViewer = manga.viewer == 0 ? preferences.getDefaultViewer() : manga.viewer; @@ -160,6 +176,21 @@ public class ReaderActivity extends BaseRxActivity { readerMenu.toggle(); } + public void requestNextChapter() { + getPresenter().setCurrentPage(viewer != null ? viewer.getCurrentPage() : 0); + if (!getPresenter().loadNextChapter()) { + ToastUtil.showShort(this, R.string.no_next_chapter); + } + + } + + public void requestPreviousChapter() { + getPresenter().setCurrentPage(viewer != null ? viewer.getCurrentPage() : 0); + if (!getPresenter().loadPreviousChapter()) { + ToastUtil.showShort(this, R.string.no_previous_chapter); + } + } + private void initializeSettings() { subscriptions.add(preferences.showPageNumber() .asObservable() diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderMenu.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderMenu.java index 48a5b87aa..25db12bf4 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderMenu.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderMenu.java @@ -5,6 +5,8 @@ import android.content.Context; import android.support.v7.app.AlertDialog; import android.support.v7.widget.Toolbar; import android.view.Gravity; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; @@ -42,6 +44,11 @@ public class ReaderMenu { @Bind(R.id.reader_extra_settings) ImageButton extraSettings; @Bind(R.id.reader_brightness) ImageButton brightnessSettings; + private MenuItem nextChapterBtn; + private MenuItem prevChapterBtn; + private Chapter prevChapter; + private Chapter nextChapter; + private ReaderActivity activity; private PreferencesHelper preferences; @@ -106,6 +113,25 @@ public class ReaderMenu { showing = false; } + public boolean onCreateOptionsMenu(Menu menu) { + activity.getMenuInflater().inflate(R.menu.reader, menu); + nextChapterBtn = menu.findItem(R.id.action_next_chapter); + prevChapterBtn = menu.findItem(R.id.action_previous_chapter); + setAdjacentChaptersVisibility(); + return true; + } + + public boolean onOptionsItemSelected(MenuItem item) { + if (item == prevChapterBtn) { + activity.requestPreviousChapter(); + } else if (item == nextChapterBtn) { + activity.requestNextChapter(); + } else { + return false; + } + return true; + } + public void onChapterReady(int numPages, Manga manga, Chapter chapter, int currentPageIndex) { if (manga.viewer == ReaderActivity.RIGHT_TO_LEFT && !inverted) { // Invert the seekbar and textview fields for the right to left reader @@ -136,6 +162,17 @@ public class ReaderMenu { seekBar.setProgress(pageIndex); } + public void onAdjacentChapters(Chapter previous, Chapter next) { + prevChapter = previous; + nextChapter = next; + setAdjacentChaptersVisibility(); + } + + private void setAdjacentChaptersVisibility() { + if (prevChapterBtn != null) prevChapterBtn.setVisible(prevChapter != null); + if (nextChapterBtn != null) nextChapterBtn.setVisible(nextChapter != null); + } + private void initializeOptions() { // Orientation changes add(preferences.lockOrientation().asObservable() diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java index d92d7361d..0ac9ebc6c 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java @@ -2,6 +2,7 @@ package eu.kanade.mangafeed.ui.reader; import android.os.Bundle; import android.support.annotation.NonNull; +import android.util.Pair; import java.io.File; import java.util.List; @@ -53,8 +54,9 @@ public class ReaderPresenter extends BasePresenter { private static final int GET_PAGE_LIST = 1; private static final int GET_PAGE_IMAGES = 2; - private static final int RETRY_IMAGES = 3; - private static final int PRELOAD_NEXT_CHAPTER = 4; + private static final int GET_ADJACENT_CHAPTERS = 3; + private static final int RETRY_IMAGES = 4; + private static final int PRELOAD_NEXT_CHAPTER = 5; @Override protected void onCreate(Bundle savedState) { @@ -71,12 +73,16 @@ public class ReaderPresenter extends BasePresenter { (view, pages) -> {}, (view, error) -> Timber.e("An error occurred while preloading a chapter")); - restartableReplay(GET_PAGE_IMAGES, - () -> getPageImagesObservable() - .doOnCompleted(this::preloadNextChapter), + restartableLatestCache(GET_PAGE_IMAGES, + this::getPageImagesObservable, (view, page) -> {}, (view, error) -> Timber.e("An error occurred while downloading an image")); + restartableLatestCache(GET_ADJACENT_CHAPTERS, + this::getAdjacentChaptersObservable, + (view, pair) -> view.onAdjacentChapters(pair.first, pair.second), + (view, error) -> Timber.e("An error occurred while getting adjacent chapters")); + restartableLatestCache(RETRY_IMAGES, this::getRetryPageObservable, (view, page) -> {}, @@ -86,7 +92,7 @@ public class ReaderPresenter extends BasePresenter { () -> getPageListObservable() .doOnNext(pages -> pageList = pages) .doOnCompleted(() -> { - getAdjacentChapters(); + start(GET_ADJACENT_CHAPTERS); start(GET_PAGE_IMAGES); start(RETRY_IMAGES); }), @@ -117,6 +123,7 @@ public class ReaderPresenter extends BasePresenter { // These are started by GET_PAGE_LIST, so we don't let them restart itselves stop(GET_PAGE_IMAGES); + stop(GET_ADJACENT_CHAPTERS); stop(RETRY_IMAGES); stop(PRELOAD_NEXT_CHAPTER); } @@ -153,9 +160,19 @@ public class ReaderPresenter extends BasePresenter { pageObservable = Observable.from(pageList) .flatMap(page -> downloadManager.getDownloadedImage(page, chapterDir)); } - return Observable.defer(() -> pageObservable) - .subscribeOn(Schedulers.io()) - .onBackpressureBuffer() + return pageObservable.subscribeOn(Schedulers.io()) + .doOnCompleted(this::preloadNextChapter); + } + + private Observable> getAdjacentChaptersObservable() { + return Observable.zip( + db.getPreviousChapter(chapter).createObservable().take(1), + db.getNextChapter(chapter).createObservable().take(1), + Pair::create) + .doOnNext(pair -> { + previousChapter = pair.first; + nextChapter = pair.second; + }) .observeOn(AndroidSchedulers.mainThread()); } @@ -275,28 +292,22 @@ public class ReaderPresenter extends BasePresenter { this.currentPage = currentPage; } - private void getAdjacentChapters() { - add(db.getNextChapter(chapter).createObservable() - .take(1) - .subscribe(result -> nextChapter = result)); - - add(db.getPreviousChapter(chapter).createObservable() - .take(1) - .subscribe(result -> previousChapter = result)); - } - - public void loadNextChapter() { + public boolean loadNextChapter() { if (hasNextChapter()) { onChapterLeft(); loadChapter(nextChapter); + return true; } + return false; } - public void loadPreviousChapter() { + public boolean loadPreviousChapter() { if (hasPreviousChapter()) { onChapterLeft(); loadChapter(previousChapter); + return true; } + return false; } public boolean hasNextChapter() { diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/base/BaseReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/base/BaseReader.java index 1bf05fd39..149abaec4 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/base/BaseReader.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/base/BaseReader.java @@ -4,12 +4,9 @@ import android.view.MotionEvent; import java.util.List; -import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.data.source.model.Page; import eu.kanade.mangafeed.ui.base.fragment.BaseFragment; import eu.kanade.mangafeed.ui.reader.ReaderActivity; -import eu.kanade.mangafeed.ui.reader.ReaderPresenter; -import eu.kanade.mangafeed.util.ToastUtil; public abstract class BaseReader extends BaseFragment { @@ -32,27 +29,6 @@ public abstract class BaseReader extends BaseFragment { return page; } - public void requestNextChapter() { - ReaderPresenter presenter = getReaderActivity().getPresenter(); - if (presenter.hasNextChapter()) { - presenter.setCurrentPage(getCurrentPage()); - presenter.loadNextChapter(); - } else { - ToastUtil.showShort(getActivity(), R.string.no_next_chapter); - } - - } - - public void requestPreviousChapter() { - ReaderPresenter presenter = getReaderActivity().getPresenter(); - if (presenter.hasPreviousChapter()) { - presenter.setCurrentPage(getCurrentPage()); - presenter.loadPreviousChapter(); - } else { - ToastUtil.showShort(getActivity(), R.string.no_previous_chapter); - } - } - public void onPageChanged(int position) { currentPage = getPageForPosition(position); updatePageNumber(); diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/PagerReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/PagerReader.java index 178fd4af3..a10985781 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/PagerReader.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/common/PagerReader.java @@ -70,10 +70,12 @@ public abstract class PagerReader extends BaseReader { @Override public void onPageListReady(List pages, int currentPage) { - this.pages = pages; - this.currentPage = currentPage; - if (isResumed()) { - setPages(); + if (this.pages != pages) { + this.pages = pages; + this.currentPage = currentPage; + if (isResumed()) { + setPages(); + } } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/LeftToRightReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/LeftToRightReader.java index fe5bfb1af..9256f8d97 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/LeftToRightReader.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/LeftToRightReader.java @@ -4,12 +4,12 @@ public class LeftToRightReader extends HorizontalReader { @Override public void onFirstPageOut() { - requestPreviousChapter(); + getReaderActivity().requestPreviousChapter(); } @Override public void onLastPageOut() { - requestNextChapter(); + getReaderActivity().requestNextChapter(); } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/RightToLeftReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/RightToLeftReader.java index 3f476a48e..043a90ddf 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/RightToLeftReader.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/horizontal/RightToLeftReader.java @@ -27,12 +27,12 @@ public class RightToLeftReader extends HorizontalReader { @Override public void onFirstPageOut() { - requestNextChapter(); + getReaderActivity().requestNextChapter(); } @Override public void onLastPageOut() { - requestPreviousChapter(); + getReaderActivity().requestPreviousChapter(); } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalReader.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalReader.java index 1711d813b..ca1fa944e 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalReader.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/vertical/VerticalReader.java @@ -18,12 +18,12 @@ public class VerticalReader extends PagerReader { @Override public void onFirstPageOut() { - requestPreviousChapter(); + getReaderActivity().requestPreviousChapter(); } @Override public void onLastPageOut() { - requestNextChapter(); + getReaderActivity().requestNextChapter(); } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonAdapter.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonAdapter.java index ccb877781..baf9f60fb 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonAdapter.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/viewer/webtoon/WebtoonAdapter.java @@ -58,6 +58,13 @@ public class WebtoonAdapter extends RecyclerView.Adapter pages, int currentPage) { - this.pages = pages; - if (isResumed()) { - setPages(); + if (this.pages != pages) { + this.pages = pages; + if (isResumed()) { + setPages(); + } } } private void setPages() { if (pages != null) { + unsubscribeStatus(); + adapter.clear(); observeStatus(0); } } @@ -112,8 +120,8 @@ public class WebtoonReader extends BaseReader { PublishSubject statusSubject = PublishSubject.create(); page.setStatusSubject(statusSubject); - if (subscription != null && !subscription.isUnsubscribed()) - subscription.unsubscribe(); + // Unsubscribe from the previous page + unsubscribeStatus(); subscription = statusSubject .startWith(page.getStatus()) diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml index 1b253231b..94282b214 100644 --- a/app/src/main/res/anim/fade_in.xml +++ b/app/src/main/res/anim/fade_in.xml @@ -4,5 +4,6 @@ android:fromAlpha="0.0" android:toAlpha="1.0" android:interpolator="@android:anim/accelerate_interpolator" - android:duration="300" /> + android:duration="300" + android:fillAfter="true"/> \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_skip_next_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_skip_next_white_24dp.png new file mode 100644 index 000000000..48dbcb9b6 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_skip_next_white_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_skip_previous_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_skip_previous_white_24dp.png new file mode 100644 index 000000000..b50e444f9 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_skip_previous_white_24dp.png differ diff --git a/app/src/main/res/drawable-ldpi/ic_skip_next_white_24dp.png b/app/src/main/res/drawable-ldpi/ic_skip_next_white_24dp.png new file mode 100644 index 000000000..be6e4e44a Binary files /dev/null and b/app/src/main/res/drawable-ldpi/ic_skip_next_white_24dp.png differ diff --git a/app/src/main/res/drawable-ldpi/ic_skip_previous_white_24dp.png b/app/src/main/res/drawable-ldpi/ic_skip_previous_white_24dp.png new file mode 100644 index 000000000..6f71c7998 Binary files /dev/null and b/app/src/main/res/drawable-ldpi/ic_skip_previous_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_skip_next_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_skip_next_white_24dp.png new file mode 100644 index 000000000..0f3f6f3e0 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_skip_next_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_skip_previous_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_skip_previous_white_24dp.png new file mode 100644 index 000000000..3cea26d18 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_skip_previous_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_skip_next_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_skip_next_white_24dp.png new file mode 100644 index 000000000..9cbbdc89f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_skip_next_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_skip_previous_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_skip_previous_white_24dp.png new file mode 100644 index 000000000..95344a056 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_skip_previous_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_skip_next_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_skip_next_white_24dp.png new file mode 100644 index 000000000..1da08ccc7 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_skip_next_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_skip_previous_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_skip_previous_white_24dp.png new file mode 100644 index 000000000..c0fff0760 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_skip_previous_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_skip_next_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_skip_next_white_24dp.png new file mode 100644 index 000000000..268f3d494 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_skip_next_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_skip_previous_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_skip_previous_white_24dp.png new file mode 100644 index 000000000..516846cce Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_skip_previous_white_24dp.png differ diff --git a/app/src/main/res/menu/reader.xml b/app/src/main/res/menu/reader.xml new file mode 100644 index 000000000..4dbb59813 --- /dev/null +++ b/app/src/main/res/menu/reader.xml @@ -0,0 +1,19 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9e33d981b..35bcbc5d3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -34,6 +34,9 @@ Next unread Start Stop + Previous chapter + Next chapter + OK