浏览代码

Can now download from recent tab. #118

NoodleMage 9 年之前
父节点
当前提交
dec9442a65

+ 31 - 0
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<RecentChaptersPresenter> implements FlexibleViewHolder.OnListItemClickListener {
@@ -72,4 +78,29 @@ public class RecentChaptersFragment extends BaseRxFragment<RecentChaptersPresent
         Intent intent = ReaderActivity.newIntent(getActivity());
         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;
+    }
+
 }

+ 151 - 0
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<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();
+    }
+
+
 }

+ 93 - 2
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<RecentChaptersFragment> {
 
     @Inject DatabaseHelper db;
+    @Inject DownloadManager downloadManager;
     @Inject SourceManager sourceManager;
 
+    private List<MangaChapter> 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<RecentChaptersFragmen
 
         restartableLatestCache(GET_RECENT_CHAPTERS,
                 this::getRecentChaptersObservable,
-                RecentChaptersFragment::onNextMangaChapters);
+                (recentChaptersFragment, chapters) -> {
+                    recentChaptersFragment.onNextMangaChapters(chapters);
+                    updateMangaInformation(convertToMangaChaptersList(chapters));
+                });
+
+        startableLatestCache(CHAPTER_STATUS_CHANGES,
+                this::getChapterStatusObs,
+                RecentChaptersFragment::onChapterStatusChange,
+                (view, error) -> Timber.e(error.getCause(), error.getMessage()));
 
-        if (savedState == null)
+        if (savedState == null) {
             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() {
         Calendar cal = Calendar.getInstance();
         cal.setTime(new Date());
@@ -66,6 +133,22 @@ public class RecentChaptersPresenter extends BasePresenter<RecentChaptersFragmen
                 .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) {
         Calendar cal = Calendar.getInstance();
         cal.setTime(new Date(date));
@@ -80,4 +163,12 @@ public class RecentChaptersPresenter extends BasePresenter<RecentChaptersFragmen
         Source source = sourceManager.get(item.manga.source);
         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));
+                }));
+    }
 }