Can now download from recent tab. #118

This commit is contained in:
NoodleMage 2016-02-18 15:58:04 +01:00
parent dcfda61aba
commit dec9442a65
3 changed files with 275 additions and 2 deletions

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.recent;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
@ -14,12 +15,17 @@ import java.util.List;
import butterknife.Bind; import butterknife.Bind;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import eu.kanade.tachiyomi.R; 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.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.adapter.FlexibleViewHolder;
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment; import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment;
import eu.kanade.tachiyomi.ui.decoration.DividerItemDecoration; import eu.kanade.tachiyomi.ui.decoration.DividerItemDecoration;
import eu.kanade.tachiyomi.ui.reader.ReaderActivity; import eu.kanade.tachiyomi.ui.reader.ReaderActivity;
import nucleus.factory.RequiresPresenter; import nucleus.factory.RequiresPresenter;
import rx.Observable;
@RequiresPresenter(RecentChaptersPresenter.class) @RequiresPresenter(RecentChaptersPresenter.class)
public class RecentChaptersFragment extends BaseRxFragment<RecentChaptersPresenter> implements FlexibleViewHolder.OnListItemClickListener { public class RecentChaptersFragment extends BaseRxFragment<RecentChaptersPresenter> implements FlexibleViewHolder.OnListItemClickListener {
@ -72,4 +78,29 @@ public class RecentChaptersFragment extends BaseRxFragment<RecentChaptersPresent
Intent intent = ReaderActivity.newIntent(getActivity()); Intent intent = ReaderActivity.newIntent(getActivity());
startActivity(intent); startActivity(intent);
} }
public void onChapterStatusChange(Download download) {
RecentChaptersHolder holder = getHolder(download.chapter);
if (holder != null)
holder.onStatusChange(download.getStatus());
}
@Nullable
private RecentChaptersHolder getHolder(Chapter chapter) {
return (RecentChaptersHolder) recyclerView.findViewHolderForItemId(chapter.id);
}
protected boolean onDownload(Observable<Chapter> chapters, Manga manga) {
// Start the download service.
DownloadService.start(getActivity());
// Refresh data on download competition.
Observable<Chapter> observable = chapters
.doOnCompleted(adapter::notifyDataSetChanged);
// Download chapter.
getPresenter().downloadChapter(observable, manga);
return true;
}
} }

View File

@ -1,32 +1,98 @@
package eu.kanade.tachiyomi.ui.recent; package eu.kanade.tachiyomi.ui.recent;
import android.content.Context;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.view.Menu;
import android.view.View; import android.view.View;
import android.widget.PopupMenu;
import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import butterknife.Bind; import butterknife.Bind;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import eu.kanade.tachiyomi.R; 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.database.models.MangaChapter;
import eu.kanade.tachiyomi.data.download.model.Download;
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder; import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder;
import eu.kanade.tachiyomi.util.ToastUtil;
import rx.Observable;
public class RecentChaptersHolder extends FlexibleViewHolder { 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; @Bind(R.id.chapter_title) TextView chapterTitle;
/**
* TextView containing manga name
*/
@Bind(R.id.manga_title) TextView mangaTitle; @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; private final int readColor;
/**
* Color of unread chapter
*/
private final int unreadColor; 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) { public RecentChaptersHolder(View view, RecentChaptersAdapter adapter, OnListItemClickListener onListItemClickListener) {
super(view, adapter, onListItemClickListener); super(view, adapter, onListItemClickListener);
this.adapter = adapter;
context = view.getContext();
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
// Set colors.
readColor = ContextCompat.getColor(view.getContext(), R.color.hint_text); readColor = ContextCompat.getColor(view.getContext(), R.color.hint_text);
unreadColor = ContextCompat.getColor(view.getContext(), R.color.primary_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) { public void onSetValues(MangaChapter item) {
this.mangaChapter = item;
chapterTitle.setText(item.chapter.name); chapterTitle.setText(item.chapter.name);
mangaTitle.setText(item.manga.title); mangaTitle.setText(item.manga.title);
@ -36,7 +102,92 @@ public class RecentChaptersHolder extends FlexibleViewHolder {
} else { } else {
chapterTitle.setTextColor(unreadColor); chapterTitle.setTextColor(unreadColor);
mangaTitle.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<Chapter> 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();
}
} }

View File

@ -15,20 +15,30 @@ import java.util.TreeMap;
import javax.inject.Inject; import javax.inject.Inject;
import eu.kanade.tachiyomi.data.database.DatabaseHelper; 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.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.SourceManager;
import eu.kanade.tachiyomi.data.source.base.Source; import eu.kanade.tachiyomi.data.source.base.Source;
import eu.kanade.tachiyomi.event.DownloadChaptersEvent;
import eu.kanade.tachiyomi.event.ReaderEvent; import eu.kanade.tachiyomi.event.ReaderEvent;
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter; import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter;
import rx.Observable; import rx.Observable;
import rx.android.schedulers.AndroidSchedulers; import rx.android.schedulers.AndroidSchedulers;
import timber.log.Timber;
public class RecentChaptersPresenter extends BasePresenter<RecentChaptersFragment> { public class RecentChaptersPresenter extends BasePresenter<RecentChaptersFragment> {
@Inject DatabaseHelper db; @Inject DatabaseHelper db;
@Inject DownloadManager downloadManager;
@Inject SourceManager sourceManager; @Inject SourceManager sourceManager;
private List<MangaChapter> mangaChapters;
private static final int GET_RECENT_CHAPTERS = 1; private static final int GET_RECENT_CHAPTERS = 1;
private static final int CHAPTER_STATUS_CHANGES = 2;
@Override @Override
protected void onCreate(Bundle savedState) { protected void onCreate(Bundle savedState) {
@ -36,11 +46,68 @@ public class RecentChaptersPresenter extends BasePresenter<RecentChaptersFragmen
restartableLatestCache(GET_RECENT_CHAPTERS, restartableLatestCache(GET_RECENT_CHAPTERS,
this::getRecentChaptersObservable, this::getRecentChaptersObservable,
RecentChaptersFragment::onNextMangaChapters); (recentChaptersFragment, chapters) -> {
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); start(GET_RECENT_CHAPTERS);
} }
}
private void updateMangaInformation(List<MangaChapter> mangaChapters) {
this.mangaChapters = mangaChapters;
for (MangaChapter mangaChapter : mangaChapters)
setChapterStatus(mangaChapter);
start(CHAPTER_STATUS_CHANGES);
}
private List<MangaChapter> convertToMangaChaptersList(List<Object> chapters) {
List<MangaChapter> tempMangaChapterList = new ArrayList<>();
for (Object object : chapters) {
if (object instanceof MangaChapter) {
tempMangaChapterList.add((MangaChapter) object);
}
}
return tempMangaChapterList;
}
private Observable<Download> 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<List<Object>> getRecentChaptersObservable() { private Observable<List<Object>> getRecentChaptersObservable() {
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
@ -66,6 +133,22 @@ public class RecentChaptersPresenter extends BasePresenter<RecentChaptersFragmen
.observeOn(AndroidSchedulers.mainThread()); .observeOn(AndroidSchedulers.mainThread());
} }
private void setChapterStatus(MangaChapter mangaChapter) {
for (Download download : downloadManager.getQueue()) {
if (mangaChapter.chapter.id.equals(download.chapter.id)) {
mangaChapter.chapter.status = download.getStatus();
return;
}
}
Source source = sourceManager.get(mangaChapter.manga.source);
if (downloadManager.isChapterDownloaded(source, mangaChapter.manga, mangaChapter.chapter)) {
mangaChapter.chapter.status = Download.DOWNLOADED;
} else {
mangaChapter.chapter.status = Download.NOT_DOWNLOADED;
}
}
private Date getMapKey(long date) { private Date getMapKey(long date) {
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
cal.setTime(new Date(date)); cal.setTime(new Date(date));
@ -80,4 +163,12 @@ public class RecentChaptersPresenter extends BasePresenter<RecentChaptersFragmen
Source source = sourceManager.get(item.manga.source); Source source = sourceManager.get(item.manga.source);
EventBus.getDefault().postSticky(new ReaderEvent(source, item.manga, item.chapter)); EventBus.getDefault().postSticky(new ReaderEvent(source, item.manga, item.chapter));
} }
public void downloadChapter(Observable<Chapter> selectedChapter, Manga manga) {
add(selectedChapter
.toList()
.subscribe(chapters -> {
EventBus.getDefault().postSticky(new DownloadChaptersEvent(manga, chapters));
}));
}
} }