diff --git a/app/src/main/java/eu/kanade/mangafeed/data/helpers/DownloadManager.java b/app/src/main/java/eu/kanade/mangafeed/data/helpers/DownloadManager.java index f7a38b786d..3aa2ee4f58 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/helpers/DownloadManager.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/helpers/DownloadManager.java @@ -48,10 +48,9 @@ public class DownloadManager { .subscribe(); } - private Observable downloadChapter(Manga manga, Chapter chapter) { + public Observable downloadChapter(Manga manga, Chapter chapter) { final Source source = sourceManager.get(manga.source); - final File chapterDirectory = new File( - preferences.getDownloadsDirectory(), getChapterDirectory(source, manga, chapter)); + final File chapterDirectory = getAbsoluteChapterDirectory(source, manga, chapter); return source .pullPageListFromNetwork(chapter.url) @@ -64,8 +63,13 @@ public class DownloadManager { // Start downloading images .flatMap(page -> getDownloadedImage(page, source, chapterDirectory)); } + + public File getAbsoluteChapterDirectory(Source source, Manga manga, Chapter chapter) { + return new File(preferences.getDownloadsDirectory(), + getChapterDirectory(source, manga, chapter)); + } - private String getChapterDirectory(Source source, Manga manga, Chapter chapter) { + public String getChapterDirectory(Source source, Manga manga, Chapter chapter) { return source.getName() + File.separator + manga.title.replaceAll("[^a-zA-Z0-9.-]", "_") + diff --git a/app/src/main/java/eu/kanade/mangafeed/data/models/Chapter.java b/app/src/main/java/eu/kanade/mangafeed/data/models/Chapter.java index 86dd0d101c..034990c3ad 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/models/Chapter.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/models/Chapter.java @@ -32,6 +32,12 @@ public class Chapter { @StorIOSQLiteColumn(name = ChaptersTable.COLUMN_DATE_UPLOAD) public long date_upload; + public int downloaded; + + public static final int UNKNOWN = 0; + public static final int NOT_DOWNLOADED = 1; + public static final int DOWNLOADED = 2; + public Chapter() {} diff --git a/app/src/main/java/eu/kanade/mangafeed/events/SourceChapterEvent.java b/app/src/main/java/eu/kanade/mangafeed/events/SourceMangaChapterEvent.java similarity index 58% rename from app/src/main/java/eu/kanade/mangafeed/events/SourceChapterEvent.java rename to app/src/main/java/eu/kanade/mangafeed/events/SourceMangaChapterEvent.java index c9fcf1c6f5..c26b8e920a 100644 --- a/app/src/main/java/eu/kanade/mangafeed/events/SourceChapterEvent.java +++ b/app/src/main/java/eu/kanade/mangafeed/events/SourceMangaChapterEvent.java @@ -1,15 +1,18 @@ package eu.kanade.mangafeed.events; import eu.kanade.mangafeed.data.models.Chapter; +import eu.kanade.mangafeed.data.models.Manga; import eu.kanade.mangafeed.sources.base.Source; -public class SourceChapterEvent { +public class SourceMangaChapterEvent { private Source source; + private Manga manga; private Chapter chapter; - public SourceChapterEvent(Source source, Chapter chapter) { + public SourceMangaChapterEvent(Source source, Manga manga, Chapter chapter) { this.source = source; + this.manga = manga; this.chapter = chapter; } @@ -17,6 +20,10 @@ public class SourceChapterEvent { return source; } + public Manga getManga() { + return manga; + } + public Chapter getChapter() { return chapter; } diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java index 6b85278553..fa41f545fe 100644 --- a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java @@ -2,17 +2,20 @@ package eu.kanade.mangafeed.presenter; import android.os.Bundle; +import java.io.File; import java.util.List; import javax.inject.Inject; import de.greenrobot.event.EventBus; import eu.kanade.mangafeed.data.helpers.DatabaseHelper; +import eu.kanade.mangafeed.data.helpers.DownloadManager; +import eu.kanade.mangafeed.data.helpers.PreferencesHelper; import eu.kanade.mangafeed.data.helpers.SourceManager; import eu.kanade.mangafeed.data.models.Chapter; import eu.kanade.mangafeed.data.models.Manga; import eu.kanade.mangafeed.events.ChapterCountEvent; -import eu.kanade.mangafeed.events.SourceChapterEvent; +import eu.kanade.mangafeed.events.SourceMangaChapterEvent; import eu.kanade.mangafeed.sources.base.Source; import eu.kanade.mangafeed.ui.fragment.MangaChaptersFragment; import eu.kanade.mangafeed.util.EventBusHook; @@ -26,6 +29,8 @@ public class MangaChaptersPresenter extends BasePresenter @Inject DatabaseHelper db; @Inject SourceManager sourceManager; + @Inject PreferencesHelper preferences; + @Inject DownloadManager downloadManager; private Manga manga; private Source source; @@ -111,7 +116,7 @@ public class MangaChaptersPresenter extends BasePresenter } public void onChapterClicked(Chapter chapter) { - EventBus.getDefault().postSticky(new SourceChapterEvent(source, chapter)); + EventBus.getDefault().postSticky(new SourceMangaChapterEvent(source, manga, chapter)); } public void markChaptersRead(Observable selectedChapters, boolean read) { @@ -131,4 +136,14 @@ public class MangaChaptersPresenter extends BasePresenter })); } + + public void checkIsChapterDownloaded(Chapter chapter) { + File dir = downloadManager.getAbsoluteChapterDirectory(source, manga, chapter); + + if (dir.exists() && dir.listFiles().length > 0) { + chapter.downloaded = Chapter.DOWNLOADED; + } else { + chapter.downloaded = Chapter.NOT_DOWNLOADED; + } + } } diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/ReaderPresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/ReaderPresenter.java index e711f377ab..53921a45a7 100644 --- a/app/src/main/java/eu/kanade/mangafeed/presenter/ReaderPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/presenter/ReaderPresenter.java @@ -2,16 +2,19 @@ package eu.kanade.mangafeed.presenter; import android.os.Bundle; +import java.io.File; import java.util.List; import javax.inject.Inject; import de.greenrobot.event.EventBus; import eu.kanade.mangafeed.data.helpers.DatabaseHelper; +import eu.kanade.mangafeed.data.helpers.DownloadManager; import eu.kanade.mangafeed.data.helpers.PreferencesHelper; import eu.kanade.mangafeed.data.models.Chapter; +import eu.kanade.mangafeed.data.models.Manga; import eu.kanade.mangafeed.data.models.Page; -import eu.kanade.mangafeed.events.SourceChapterEvent; +import eu.kanade.mangafeed.events.SourceMangaChapterEvent; import eu.kanade.mangafeed.sources.base.Source; import eu.kanade.mangafeed.ui.activity.ReaderActivity; import eu.kanade.mangafeed.util.EventBusHook; @@ -25,14 +28,17 @@ public class ReaderPresenter extends BasePresenter { @Inject PreferencesHelper prefs; @Inject DatabaseHelper db; + @Inject DownloadManager downloadManager; private Source source; + private Manga manga; private Chapter chapter; private List pageList; @State int currentPage; private static final int GET_PAGE_LIST = 1; private static final int GET_PAGE_IMAGES = 2; + private static final int GET_LOCAL_IMAGES = 3; @Override protected void onCreate(Bundle savedState) { @@ -41,7 +47,7 @@ public class ReaderPresenter extends BasePresenter { restartableLatestCache(GET_PAGE_LIST, () -> getPageListObservable() .doOnNext(pages -> pageList = pages) - .doOnCompleted(() -> start(GET_PAGE_IMAGES)), + .doOnCompleted(this::prepareChapter), (view, pages) -> { view.onPageListReady(pages); if (currentPage != 0) @@ -55,6 +61,10 @@ public class ReaderPresenter extends BasePresenter { (view, page) -> { }, (view, error) -> Timber.e("An error occurred while downloading an image")); + + restartableReplay(GET_LOCAL_IMAGES, + this::getLocalImagesObservable, + (view, page) -> {}); } @Override @@ -77,14 +87,16 @@ public class ReaderPresenter extends BasePresenter { } @EventBusHook - public void onEventMainThread(SourceChapterEvent event) { + public void onEventMainThread(SourceMangaChapterEvent event) { source = event.getSource(); + manga = event.getManga(); chapter = event.getChapter(); if (chapter.last_page_read != 0 && !chapter.read) currentPage = chapter.last_page_read; - start(1); - EventBus.getDefault().removeStickyEvent(SourceChapterEvent.class); + start(GET_PAGE_LIST); + + EventBus.getDefault().removeStickyEvent(SourceMangaChapterEvent.class); } private Observable> getPageListObservable() { @@ -103,10 +115,26 @@ public class ReaderPresenter extends BasePresenter { .observeOn(AndroidSchedulers.mainThread()); } + private Observable getLocalImagesObservable() { + File chapterDir = downloadManager.getAbsoluteChapterDirectory(source, manga, chapter); + + return Observable.from(pageList) + .flatMap(page -> downloadManager.getDownloadedImage(page, source, chapterDir)) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } + private void prepareChapter() { + if (chapter.downloaded != Chapter.DOWNLOADED) + start(GET_PAGE_IMAGES); + else + start(GET_LOCAL_IMAGES); + } + private void saveChapter() { chapter.last_page_read = currentPage; if (currentPage == pageList.size() - 1) { diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/adapter/ChaptersAdapter.java b/app/src/main/java/eu/kanade/mangafeed/ui/adapter/ChaptersAdapter.java index d98e1b86a2..4cb0383cd1 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/adapter/ChaptersAdapter.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/adapter/ChaptersAdapter.java @@ -1,6 +1,5 @@ package eu.kanade.mangafeed.ui.adapter; -import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -11,16 +10,17 @@ import java.util.List; import eu.davidea.flexibleadapter.FlexibleAdapter; import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.data.models.Chapter; +import eu.kanade.mangafeed.ui.fragment.MangaChaptersFragment; import eu.kanade.mangafeed.ui.fragment.base.BaseFragment; import eu.kanade.mangafeed.ui.holder.ChaptersHolder; public class ChaptersAdapter extends FlexibleAdapter { - private Context context; + private BaseFragment fragment; public OnItemClickListener clickListener; public ChaptersAdapter(BaseFragment fragment) { - this.context = fragment.getActivity(); + this.fragment = fragment; mItems = new ArrayList<>(); clickListener = (OnItemClickListener) fragment; } @@ -30,14 +30,14 @@ public class ChaptersAdapter extends FlexibleAdapter { @Override public ChaptersHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View v = LayoutInflater.from(context).inflate(R.layout.item_chapter, parent, false); + View v = LayoutInflater.from(fragment.getActivity()).inflate(R.layout.item_chapter, parent, false); return new ChaptersHolder(v, this); } @Override public void onBindViewHolder(ChaptersHolder holder, int position) { final Chapter chapter = getItem(position); - holder.onSetValues(context, chapter); + holder.onSetValues(fragment.getActivity(), chapter); } public void setItems(List chapters) { @@ -49,4 +49,8 @@ public class ChaptersAdapter extends FlexibleAdapter { boolean onListItemClick(int position); void onListItemLongClick(int position); } + + public MangaChaptersFragment getMangaChaptersFragment() { + return (MangaChaptersFragment) fragment; + } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/holder/CatalogueHolder.java b/app/src/main/java/eu/kanade/mangafeed/ui/holder/CatalogueHolder.java index c1850a4912..2e316420d7 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/holder/CatalogueHolder.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/holder/CatalogueHolder.java @@ -37,6 +37,8 @@ public class CatalogueHolder extends ItemViewHolder { .diskCacheStrategy(DiskCacheStrategy.RESULT) .centerCrop() .into(image); + } else { + image.setImageResource(android.R.color.transparent); } } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/holder/ChaptersHolder.java b/app/src/main/java/eu/kanade/mangafeed/ui/holder/ChaptersHolder.java index a904e74e78..7e3c214fcc 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/holder/ChaptersHolder.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/holder/ChaptersHolder.java @@ -38,7 +38,7 @@ public class ChaptersHolder extends RecyclerView.ViewHolder implements public void onSetValues(Context context, Chapter chapter) { title.setText(chapter.name); - download_icon.setImageResource(R.drawable.ic_file_download_black_48dp); + if (chapter.read) { title.setTextColor(ContextCompat.getColor(context, R.color.chapter_read_text)); @@ -52,6 +52,14 @@ public class ChaptersHolder extends RecyclerView.ViewHolder implements pages.setText(""); } + if (chapter.downloaded == Chapter.UNKNOWN) { + adapter.getMangaChaptersFragment().getPresenter().checkIsChapterDownloaded(chapter); + } + if (chapter.downloaded == Chapter.DOWNLOADED) + download_icon.setImageResource(R.drawable.ic_action_delete_36dp); + else if (chapter.downloaded == Chapter.NOT_DOWNLOADED) + download_icon.setImageResource(R.drawable.ic_file_download_black_36dp); + toggleActivation(); } diff --git a/app/src/main/res/drawable-hdpi/ic_action_delete_36dp.png b/app/src/main/res/drawable-hdpi/ic_action_delete_36dp.png new file mode 100644 index 0000000000..8377c1da7f Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_delete_36dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_file_download_black_36dp.png b/app/src/main/res/drawable-hdpi/ic_file_download_black_36dp.png new file mode 100644 index 0000000000..e8d3ec4872 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_file_download_black_36dp.png differ diff --git a/app/src/main/res/drawable-ldpi/ic_action_delete_36dp.png b/app/src/main/res/drawable-ldpi/ic_action_delete_36dp.png new file mode 100644 index 0000000000..5bbc471807 Binary files /dev/null and b/app/src/main/res/drawable-ldpi/ic_action_delete_36dp.png differ diff --git a/app/src/main/res/drawable-ldpi/ic_file_download_black_36dp.png b/app/src/main/res/drawable-ldpi/ic_file_download_black_36dp.png new file mode 100644 index 0000000000..9ab2d63a6d Binary files /dev/null and b/app/src/main/res/drawable-ldpi/ic_file_download_black_36dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_delete_36dp.png b/app/src/main/res/drawable-mdpi/ic_action_delete_36dp.png new file mode 100644 index 0000000000..eec14f009a Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_delete_36dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_file_download_black_36dp.png b/app/src/main/res/drawable-mdpi/ic_file_download_black_36dp.png new file mode 100644 index 0000000000..bdf4345353 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_file_download_black_36dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_delete_36dp.png b/app/src/main/res/drawable-xhdpi/ic_action_delete_36dp.png new file mode 100644 index 0000000000..3a25d9b622 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_delete_36dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_file_download_black_36dp.png b/app/src/main/res/drawable-xhdpi/ic_file_download_black_36dp.png new file mode 100644 index 0000000000..46a95731c1 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_file_download_black_36dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_delete_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_action_delete_36dp.png new file mode 100644 index 0000000000..51f5e8bcb7 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_delete_36dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_file_download_black_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_file_download_black_36dp.png new file mode 100644 index 0000000000..5a8afa4d6c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_file_download_black_36dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_action_delete_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_action_delete_36dp.png new file mode 100644 index 0000000000..484eed003d Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_action_delete_36dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_file_download_black_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_file_download_black_36dp.png new file mode 100644 index 0000000000..ef8abc1252 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_file_download_black_36dp.png differ