Improve info fragment. Other minor changes and fixes.
This commit is contained in:
parent
c52c567eae
commit
eb10d77374
8 changed files with 328 additions and 274 deletions
|
@ -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) {
|
||||
|
|
|
@ -39,10 +39,10 @@ public class CatalogueFragment extends BaseRxFragment<CataloguePresenter> {
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -105,6 +105,9 @@ public class DownloadPresenter extends BasePresenter<DownloadFragment> {
|
|||
}
|
||||
|
||||
private void observePagesStatus(Download download, DownloadFragment view) {
|
||||
// Initial update of the downloaded pages
|
||||
view.updateDownloadedPages(download);
|
||||
|
||||
PublishSubject<Integer> pageStatusSubject = PublishSubject.create();
|
||||
for (Page page : download.pages) {
|
||||
if (page.getStatus() != Page.READY)
|
||||
|
|
|
@ -17,7 +17,6 @@ public class MangaPresenter extends BasePresenter<MangaActivity> {
|
|||
@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<MangaActivity> {
|
|||
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<MangaActivity> {
|
|||
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) {
|
||||
|
|
|
@ -56,53 +56,39 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
|
|||
|
||||
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;
|
||||
|
||||
if (!isStarted(DB_CHAPTERS)) {
|
||||
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) {
|
||||
|
@ -112,6 +98,7 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
|
|||
})
|
||||
.subscribe(chaptersSubject::onNext));
|
||||
}
|
||||
}
|
||||
|
||||
public void fetchChaptersFromSource() {
|
||||
hasRequested = true;
|
||||
|
|
|
@ -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<MangaInfoPresenter> {
|
||||
|
||||
@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<MangaInfoPresenter> {
|
|||
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();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<MangaInfoFragment> {
|
||||
|
||||
|
@ -24,8 +26,11 @@ public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
|
|||
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<MangaInfoFragment> {
|
|||
|
||||
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<MangaInfoFragment> {
|
|||
}
|
||||
}
|
||||
|
||||
public void initFavoriteText() {
|
||||
if (getView() != null)
|
||||
getView().setFavoriteText(manga.favorite);
|
||||
public void fetchMangaFromSource() {
|
||||
if (!isFetching) {
|
||||
isFetching = true;
|
||||
start(FETCH_MANGA_INFO);
|
||||
}
|
||||
}
|
||||
|
||||
private Observable<Manga> 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() {
|
||||
|
|
|
@ -3,10 +3,28 @@
|
|||
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">
|
||||
|
||||
|
||||
<!-- It seems I have to wrap everything in SwipeRefreshLayout because it always take the entire height
|
||||
and the description can't be seen.
|
||||
Maybe with Relative layout it's better. We shouldn't put this layout inside the description layout
|
||||
because the description should be scrollable and gestures could conflict with this layout.
|
||||
Leaving it like this for now.
|
||||
-->
|
||||
<android.support.v4.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipe_refresh"
|
||||
android:layout_width="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -205,4 +223,8 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
||||
|
||||
</LinearLayout>
|
Reference in a new issue