diff --git a/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java b/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java index 00829b43b5..47009bd0e3 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java @@ -25,7 +25,6 @@ import eu.kanade.mangafeed.data.source.model.Page; import eu.kanade.mangafeed.event.DownloadChaptersEvent; import eu.kanade.mangafeed.util.DiskUtils; import eu.kanade.mangafeed.util.DynamicConcurrentMergeOperator; -import eu.kanade.mangafeed.util.UrlUtil; import rx.Observable; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; @@ -182,8 +181,10 @@ public class DownloadManager { return pageListObservable .subscribeOn(Schedulers.io()) - .doOnNext(pages -> download.setStatus(Download.DOWNLOADING)) - .doOnNext(pages -> download.downloadedImages = 0) + .doOnNext(pages -> { + download.downloadedImages = 0; + download.setStatus(Download.DOWNLOADING); + }) // Get all the URLs to the source images, fetch pages if necessary .flatMap(download.source::getAllImageUrlsFromPageList) // Start downloading images, consider we can have downloaded images already @@ -263,10 +264,8 @@ public class DownloadManager { // Get the filename for an image given the page private String getImageFilename(Page page) { - String url = UrlUtil.getPath(page.getImageUrl()); - return url.substring( - url.lastIndexOf("/") + 1, - url.length()); + String url = page.getImageUrl(); + return url.substring(url.lastIndexOf("/") + 1, url.length()); } private boolean isImageDownloaded(File imagePath) { diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/catalogue/CatalogueFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/catalogue/CatalogueFragment.java index 2f623f8ae1..295bbc4cc7 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/catalogue/CatalogueFragment.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/catalogue/CatalogueFragment.java @@ -39,10 +39,10 @@ public class CatalogueFragment extends BaseRxFragment { public final static String SOURCE_ID = "source_id"; - public static CatalogueFragment newInstance(int source_id) { + public static CatalogueFragment newInstance(int sourceId) { CatalogueFragment fragment = new CatalogueFragment(); Bundle args = new Bundle(); - args.putInt(SOURCE_ID, source_id); + args.putInt(SOURCE_ID, sourceId); fragment.setArguments(args); return fragment; } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadPresenter.java b/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadPresenter.java index 28958c11f5..be6880a34b 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadPresenter.java @@ -105,6 +105,9 @@ public class DownloadPresenter extends BasePresenter { } private void observePagesStatus(Download download, DownloadFragment view) { + // Initial update of the downloaded pages + view.updateDownloadedPages(download); + PublishSubject pageStatusSubject = PublishSubject.create(); for (Page page : download.pages) { if (page.getStatus() != Page.READY) diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/manga/MangaPresenter.java b/app/src/main/java/eu/kanade/mangafeed/ui/manga/MangaPresenter.java index e1f8cbdcbe..d2addc4d91 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/manga/MangaPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/manga/MangaPresenter.java @@ -17,7 +17,6 @@ public class MangaPresenter extends BasePresenter { @Inject DatabaseHelper db; private long mangaId; - private Manga manga; private static final int DB_MANGA = 1; @@ -25,19 +24,13 @@ public class MangaPresenter extends BasePresenter { protected void onCreate(Bundle savedState) { super.onCreate(savedState); - restartableLatestCache(DB_MANGA, - () -> getDbMangaObservable() - .doOnNext(manga -> this.manga = manga), - (view, manga) -> { - view.setManga(manga); - EventBus.getDefault().postSticky(manga); - }); + restartableLatestCache(DB_MANGA, this::getDbMangaObservable, MangaActivity::setManga); } @Override protected void onDestroy() { super.onDestroy(); - // Avoid fragments receiving wrong manga + // Avoid new instances receiving wrong manga EventBus.getDefault().removeStickyEvent(Manga.class); } @@ -45,7 +38,8 @@ public class MangaPresenter extends BasePresenter { return db.getManga(mangaId).createObservable() .subscribeOn(Schedulers.io()) .flatMap(Observable::from) - .observeOn(AndroidSchedulers.mainThread()); + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(manga -> EventBus.getDefault().postSticky(manga)); } public void queryManga(long mangaId) { diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java b/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java index d09ce6aff2..60c1151cc2 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java @@ -56,61 +56,48 @@ public class ChaptersPresenter extends BasePresenter { restartableLatestCache(DB_CHAPTERS, this::getDbChaptersObs, - ChaptersFragment::onNextChapters - ); + ChaptersFragment::onNextChapters); - restartableLatestCache(FETCH_CHAPTERS, + restartableFirst(FETCH_CHAPTERS, this::getOnlineChaptersObs, (view, result) -> view.onFetchChaptersDone(), - (view, error) -> view.onFetchChaptersError() - ); + (view, error) -> view.onFetchChaptersError()); restartableLatestCache(CHAPTER_STATUS_CHANGES, this::getChapterStatusObs, (view, download) -> view.onChapterStatusChange(download), - (view, error) -> Timber.e(error.getCause(), error.getMessage()) - ); - } + (view, error) -> Timber.e(error.getCause(), error.getMessage())); - @Override - protected void onTakeView(ChaptersFragment view) { - super.onTakeView(view); registerForStickyEvents(); } - @Override - protected void onDropView() { - unregisterForEvents(); - super.onDropView(); - } - @Override protected void onDestroy() { + unregisterForEvents(); EventBus.getDefault().removeStickyEvent(ChapterCountEvent.class); super.onDestroy(); } @EventBusHook public void onEventMainThread(Manga manga) { - if (this.manga != null) - return; - this.manga = manga; - source = sourceManager.get(manga.source); - start(DB_CHAPTERS); - add(db.getChapters(manga).createObservable() - .subscribeOn(Schedulers.io()) - .doOnNext(chapters -> { - stop(CHAPTER_STATUS_CHANGES); - this.chapters = chapters; - EventBus.getDefault().postSticky(new ChapterCountEvent(chapters.size())); - for (Chapter chapter : chapters) { - setChapterStatus(chapter); - } - start(CHAPTER_STATUS_CHANGES); - }) - .subscribe(chaptersSubject::onNext)); + if (!isStarted(DB_CHAPTERS)) { + source = sourceManager.get(manga.source); + start(DB_CHAPTERS); + + add(db.getChapters(manga).createObservable() + .subscribeOn(Schedulers.io()) + .doOnNext(chapters -> { + this.chapters = chapters; + EventBus.getDefault().postSticky(new ChapterCountEvent(chapters.size())); + for (Chapter chapter : chapters) { + setChapterStatus(chapter); + } + start(CHAPTER_STATUS_CHANGES); + }) + .subscribe(chaptersSubject::onNext)); + } } public void fetchChaptersFromSource() { diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/manga/info/MangaInfoFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/manga/info/MangaInfoFragment.java index b6e4146195..3ed89af97d 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/manga/info/MangaInfoFragment.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/manga/info/MangaInfoFragment.java @@ -1,6 +1,7 @@ package eu.kanade.mangafeed.ui.manga.info; import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -21,13 +22,15 @@ import nucleus.factory.RequiresPresenter; @RequiresPresenter(MangaInfoPresenter.class) public class MangaInfoFragment extends BaseRxFragment { - @Bind(R.id.manga_artist) TextView mArtist; - @Bind(R.id.manga_author) TextView mAuthor; - @Bind(R.id.manga_chapters) TextView mChapters; - @Bind(R.id.manga_genres) TextView mGenres; - @Bind(R.id.manga_status) TextView mStatus; - @Bind(R.id.manga_summary) TextView mDescription; - @Bind(R.id.manga_cover) ImageView mCover; + @Bind(R.id.swipe_refresh) SwipeRefreshLayout swipeRefresh; + + @Bind(R.id.manga_artist) TextView artist; + @Bind(R.id.manga_author) TextView author; + @Bind(R.id.manga_chapters) TextView chapterCount; + @Bind(R.id.manga_genres) TextView genres; + @Bind(R.id.manga_status) TextView status; + @Bind(R.id.manga_summary) TextView description; + @Bind(R.id.manga_cover) ImageView cover; @Bind(R.id.action_favorite) Button favoriteBtn; @@ -52,37 +55,63 @@ public class MangaInfoFragment extends BaseRxFragment { favoriteBtn.setOnClickListener(v -> { getPresenter().toggleFavorite(); }); + swipeRefresh.setOnRefreshListener(this::fetchMangaFromSource); return view; } - public void setMangaInfo(Manga manga) { - mArtist.setText(manga.artist); - mAuthor.setText(manga.author); - mGenres.setText(manga.genre); - mStatus.setText("Ongoing"); //TODO - mDescription.setText(manga.description); + public void onNextManga(Manga manga) { + if (manga.initialized) { + setMangaInfo(manga); + } else { + // Initialize manga + fetchMangaFromSource(); + } + } + + private void setMangaInfo(Manga manga) { + artist.setText(manga.artist); + author.setText(manga.author); + genres.setText(manga.genre); + status.setText("Ongoing"); //TODO + description.setText(manga.description); setFavoriteText(manga.favorite); - if (mCover.getDrawable() == null) { - CoverCache coverCache = getPresenter().coverCache; - LazyHeaders headers = getPresenter().source.getGlideHeaders(); + CoverCache coverCache = getPresenter().coverCache; + LazyHeaders headers = getPresenter().source.getGlideHeaders(); + if (manga.thumbnail_url != null && cover.getDrawable() == null) { if (manga.favorite) { - coverCache.saveAndLoadFromCache(mCover, manga.thumbnail_url, headers); + coverCache.saveAndLoadFromCache(cover, manga.thumbnail_url, headers); } else { - coverCache.loadFromNetwork(mCover, manga.thumbnail_url, headers); + coverCache.loadFromNetwork(cover, manga.thumbnail_url, headers); } + cover.setTag(manga.thumbnail_url); } - } public void setChapterCount(int count) { - mChapters.setText(String.valueOf(count)); + chapterCount.setText(String.valueOf(count)); } public void setFavoriteText(boolean isFavorite) { favoriteBtn.setText(!isFavorite ? R.string.add_to_library : R.string.remove_from_library); } + private void fetchMangaFromSource() { + setRefreshing(true); + getPresenter().fetchMangaFromSource(); + } + + public void onFetchMangaDone() { + setRefreshing(false); + } + + public void onFetchMangaError() { + setRefreshing(false); + } + + private void setRefreshing(boolean value) { + swipeRefresh.setRefreshing(value); + } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/manga/info/MangaInfoPresenter.java b/app/src/main/java/eu/kanade/mangafeed/ui/manga/info/MangaInfoPresenter.java index d128e99c67..332a4bcc53 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/manga/info/MangaInfoPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/manga/info/MangaInfoPresenter.java @@ -13,6 +13,8 @@ import eu.kanade.mangafeed.event.ChapterCountEvent; import eu.kanade.mangafeed.ui.base.presenter.BasePresenter; import eu.kanade.mangafeed.util.EventBusHook; import rx.Observable; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; public class MangaInfoPresenter extends BasePresenter { @@ -24,8 +26,11 @@ public class MangaInfoPresenter extends BasePresenter { protected Source source; private int count = -1; + private boolean isFetching; + private static final int GET_MANGA = 1; private static final int GET_CHAPTER_COUNT = 2; + private static final int FETCH_MANGA_INFO = 3; @Override protected void onCreate(Bundle savedState) { @@ -33,23 +38,24 @@ public class MangaInfoPresenter extends BasePresenter { restartableLatestCache(GET_MANGA, () -> Observable.just(manga), - MangaInfoFragment::setMangaInfo); + MangaInfoFragment::onNextManga); restartableLatestCache(GET_CHAPTER_COUNT, () -> Observable.just(count), MangaInfoFragment::setChapterCount); - } - @Override - protected void onTakeView(MangaInfoFragment view) { - super.onTakeView(view); + restartableFirst(FETCH_MANGA_INFO, + this::fetchMangaObs, + (view, manga) -> view.onFetchMangaDone(), + (view, error) -> view.onFetchMangaError()); + registerForStickyEvents(); } @Override - protected void onDropView() { + protected void onDestroy() { unregisterForEvents(); - super.onDropView(); + super.onDestroy(); } @EventBusHook @@ -67,9 +73,23 @@ public class MangaInfoPresenter extends BasePresenter { } } - public void initFavoriteText() { - if (getView() != null) - getView().setFavoriteText(manga.favorite); + public void fetchMangaFromSource() { + if (!isFetching) { + isFetching = true; + start(FETCH_MANGA_INFO); + } + } + + private Observable fetchMangaObs() { + return source.pullMangaFromNetwork(manga.url) + .flatMap(networkManga -> { + Manga.copyFromNetwork(manga, networkManga); + db.insertManga(manga).executeAsBlocking(); + return Observable.just(manga); + }) + .finallyDo(() -> isFetching = false) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); } public void toggleFavorite() { diff --git a/app/src/main/res/layout/fragment_manga_info.xml b/app/src/main/res/layout/fragment_manga_info.xml index d8c3500c91..93e77c1309 100644 --- a/app/src/main/res/layout/fragment_manga_info.xml +++ b/app/src/main/res/layout/fragment_manga_info.xml @@ -3,206 +3,228 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:fitsSystemWindows="true" android:orientation="vertical" tools:context="eu.kanade.mangafeed.ui.catalogue.CatalogueFragment"> - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -