From dec9442a65ae74da7f1f022127a0164deeb79497 Mon Sep 17 00:00:00 2001 From: NoodleMage Date: Thu, 18 Feb 2016 15:58:04 +0100 Subject: [PATCH] Can now download from recent tab. #118 --- .../ui/recent/RecentChaptersFragment.java | 31 ++++ .../ui/recent/RecentChaptersHolder.java | 151 ++++++++++++++++++ .../ui/recent/RecentChaptersPresenter.java | 95 ++++++++++- 3 files changed, 275 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersFragment.java index ff332773b..e78c34ccd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersFragment.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersFragment.java @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.recent; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -14,12 +15,17 @@ import java.util.List; import butterknife.Bind; import butterknife.ButterKnife; import eu.kanade.tachiyomi.R; +import eu.kanade.tachiyomi.data.database.models.Chapter; +import eu.kanade.tachiyomi.data.database.models.Manga; import eu.kanade.tachiyomi.data.database.models.MangaChapter; +import eu.kanade.tachiyomi.data.download.DownloadService; +import eu.kanade.tachiyomi.data.download.model.Download; import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder; import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment; import eu.kanade.tachiyomi.ui.decoration.DividerItemDecoration; import eu.kanade.tachiyomi.ui.reader.ReaderActivity; import nucleus.factory.RequiresPresenter; +import rx.Observable; @RequiresPresenter(RecentChaptersPresenter.class) public class RecentChaptersFragment extends BaseRxFragment implements FlexibleViewHolder.OnListItemClickListener { @@ -72,4 +78,29 @@ public class RecentChaptersFragment extends BaseRxFragment chapters, Manga manga) { + // Start the download service. + DownloadService.start(getActivity()); + + // Refresh data on download competition. + Observable observable = chapters + .doOnCompleted(adapter::notifyDataSetChanged); + + // Download chapter. + getPresenter().downloadChapter(observable, manga); + return true; + } + } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersHolder.java b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersHolder.java index 93927e9fc..8d3607e39 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersHolder.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersHolder.java @@ -1,32 +1,98 @@ package eu.kanade.tachiyomi.ui.recent; +import android.content.Context; import android.support.v4.content.ContextCompat; +import android.view.Menu; import android.view.View; +import android.widget.PopupMenu; +import android.widget.RelativeLayout; import android.widget.TextView; import butterknife.Bind; import butterknife.ButterKnife; import eu.kanade.tachiyomi.R; +import eu.kanade.tachiyomi.data.database.models.Chapter; import eu.kanade.tachiyomi.data.database.models.MangaChapter; +import eu.kanade.tachiyomi.data.download.model.Download; import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder; +import eu.kanade.tachiyomi.util.ToastUtil; +import rx.Observable; public class RecentChaptersHolder extends FlexibleViewHolder { + /** + * Adapter for recent chapters + */ + private final RecentChaptersAdapter adapter; + + /** + * Interface to global information about an application environment. + */ + private Context context; + + /** + * TextView containing chapter title + */ @Bind(R.id.chapter_title) TextView chapterTitle; + + /** + * TextView containing manga name + */ @Bind(R.id.manga_title) TextView mangaTitle; + /** + * TextView containing download status + */ + @Bind(R.id.download_text) TextView downloadText; + + /** + * RelativeLayout containing popup menu with download options + */ + @Bind(R.id.chapter_menu) RelativeLayout chapterMenu; + + /** + * TextView containing read progress + */ +// @Bind(R.id.chapter_pages) TextView pages; + + /** + * Color of read chapter + */ private final int readColor; + + /** + * Color of unread chapter + */ private final int unreadColor; + /** + * Object containing chapter information + */ + private MangaChapter mangaChapter; + + /** + * Constructor of RecentChaptersHolder + * + * @param view + * @param adapter + * @param onListItemClickListener + */ public RecentChaptersHolder(View view, RecentChaptersAdapter adapter, OnListItemClickListener onListItemClickListener) { super(view, adapter, onListItemClickListener); + this.adapter = adapter; + context = view.getContext(); ButterKnife.bind(this, view); + // Set colors. readColor = ContextCompat.getColor(view.getContext(), R.color.hint_text); unreadColor = ContextCompat.getColor(view.getContext(), R.color.primary_text); + + //Set OnClickListener for download menu + chapterMenu.setOnClickListener(v -> v.post(() -> showPopupMenu(v))); } public void onSetValues(MangaChapter item) { + this.mangaChapter = item; chapterTitle.setText(item.chapter.name); mangaTitle.setText(item.manga.title); @@ -36,7 +102,92 @@ public class RecentChaptersHolder extends FlexibleViewHolder { } else { chapterTitle.setTextColor(unreadColor); mangaTitle.setTextColor(unreadColor); + +// if (item.chapter.last_page_read > 0) { +// pages.setText(context.getString(R.string.chapter_progress, item.chapter.last_page_read + 1)); +// } else { +// pages.setText(""); +// } + } + + onStatusChange(item.chapter.status); + } + + public void onStatusChange(int status) { + switch (status) { + case Download.QUEUE: + downloadText.setText(R.string.chapter_queued); + break; + case Download.DOWNLOADING: + downloadText.setText(R.string.chapter_downloading); + break; + case Download.DOWNLOADED: + downloadText.setText(R.string.chapter_downloaded); + break; + case Download.ERROR: + downloadText.setText(R.string.chapter_error); + break; + default: + downloadText.setText(""); + break; } } + public void onProgressChange(Context context, int downloaded, int total) { + downloadText.setText(context.getString( + R.string.chapter_downloading_progress, downloaded, total)); + } + + private void showPopupMenu(View view) { + // Create a PopupMenu, giving it the clicked view for an anchor + PopupMenu popup = new PopupMenu(adapter.getFragment().getActivity(), view); + + // Inflate our menu resource into the PopupMenu's Menu + popup.getMenuInflater().inflate(R.menu.chapter_recent, popup.getMenu()); + + // Hide download and show delete if the chapter is downloaded and + if (mangaChapter.chapter.isDownloaded()) { + Menu menu = popup.getMenu(); + menu.findItem(R.id.action_download).setVisible(false); + menu.findItem(R.id.action_delete).setVisible(true); + } + + // Hide mark as unread when the chapter is unread + if (!mangaChapter.chapter.read /*&& mangaChapter.chapter.last_page_read == 0*/) { + popup.getMenu().findItem(R.id.action_mark_as_unread).setVisible(false); + } + + // Hide mark as read when the chapter is read + if (mangaChapter.chapter.read) { + popup.getMenu().findItem(R.id.action_mark_as_read).setVisible(false); + } + + // Set a listener so we are notified if a menu item is clicked + popup.setOnMenuItemClickListener(menuItem -> { + Observable chapterObservable = Observable.just(mangaChapter.chapter); + + switch (menuItem.getItemId()) { + case R.id.action_download: + return adapter.getFragment().onDownload(chapterObservable, mangaChapter.manga); + case R.id.action_delete: + ToastUtil.showShort(context, "Delete does not work, yet...."); + return true; +// return adapter.getFragment().onDelete(chapterObservable); + case R.id.action_mark_as_read: + ToastUtil.showShort(context, "Mark as read does not work, yet...."); + return true; +// return adapter.getFragment().onMarkAsRead(chapterObservable); + case R.id.action_mark_as_unread: + ToastUtil.showShort(context, "Mark as unread does not work, yet...."); + return true; +// return adapter.getFragment().onMarkAsUnread(chapterObservable); + } + return false; + }); + + // Finally show the PopupMenu + popup.show(); + } + + } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersPresenter.java index f991ee93b..a849c9d1d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersPresenter.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersPresenter.java @@ -15,20 +15,30 @@ import java.util.TreeMap; import javax.inject.Inject; import eu.kanade.tachiyomi.data.database.DatabaseHelper; +import eu.kanade.tachiyomi.data.database.models.Chapter; +import eu.kanade.tachiyomi.data.database.models.Manga; import eu.kanade.tachiyomi.data.database.models.MangaChapter; +import eu.kanade.tachiyomi.data.download.DownloadManager; +import eu.kanade.tachiyomi.data.download.model.Download; import eu.kanade.tachiyomi.data.source.SourceManager; import eu.kanade.tachiyomi.data.source.base.Source; +import eu.kanade.tachiyomi.event.DownloadChaptersEvent; import eu.kanade.tachiyomi.event.ReaderEvent; import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; +import timber.log.Timber; public class RecentChaptersPresenter extends BasePresenter { @Inject DatabaseHelper db; + @Inject DownloadManager downloadManager; @Inject SourceManager sourceManager; + private List mangaChapters; + private static final int GET_RECENT_CHAPTERS = 1; + private static final int CHAPTER_STATUS_CHANGES = 2; @Override protected void onCreate(Bundle savedState) { @@ -36,12 +46,69 @@ public class RecentChaptersPresenter extends BasePresenter { + recentChaptersFragment.onNextMangaChapters(chapters); + updateMangaInformation(convertToMangaChaptersList(chapters)); + }); - if (savedState == null) + startableLatestCache(CHAPTER_STATUS_CHANGES, + this::getChapterStatusObs, + RecentChaptersFragment::onChapterStatusChange, + (view, error) -> Timber.e(error.getCause(), error.getMessage())); + + if (savedState == null) { start(GET_RECENT_CHAPTERS); + } } + + private void updateMangaInformation(List mangaChapters) { + this.mangaChapters = mangaChapters; + + for (MangaChapter mangaChapter : mangaChapters) + setChapterStatus(mangaChapter); + + start(CHAPTER_STATUS_CHANGES); + } + + private List convertToMangaChaptersList(List chapters) { + List tempMangaChapterList = new ArrayList<>(); + for (Object object : chapters) { + if (object instanceof MangaChapter) { + tempMangaChapterList.add((MangaChapter) object); + } + } + return tempMangaChapterList; + } + + private Observable getChapterStatusObs() { + return downloadManager.getQueue().getStatusObservable() + .observeOn(AndroidSchedulers.mainThread()) + .filter(download -> chapterIdEquals(download.chapter.id)) + .doOnNext(this::updateChapterStatus); + } + + private boolean chapterIdEquals(Long chaptersId) { + for (MangaChapter mangaChapter : mangaChapters) { + if (chaptersId.equals(mangaChapter.chapter.id)) { + return true; + } + } + return false; + } + + public void updateChapterStatus(Download download) { + for (Object item : mangaChapters) { + if (item instanceof MangaChapter) { + if (download.chapter.id.equals(((MangaChapter) item).chapter.id)) { + ((MangaChapter) item).chapter.status = download.getStatus(); + break; + } + } + } + } + + private Observable> getRecentChaptersObservable() { Calendar cal = Calendar.getInstance(); cal.setTime(new Date()); @@ -66,6 +133,22 @@ public class RecentChaptersPresenter extends BasePresenter selectedChapter, Manga manga) { + add(selectedChapter + .toList() + .subscribe(chapters -> { + EventBus.getDefault().postSticky(new DownloadChaptersEvent(manga, chapters)); + })); + } }