diff --git a/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java b/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java index 0ead41ff9f..e5a729ab87 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java @@ -395,7 +395,7 @@ public class DownloadManager { for (Download download : queue.get()) { if (download.getStatus() != Download.DOWNLOADED) { - download.setStatus(Download.QUEUE); + if (download.getStatus() != Download.QUEUE) download.setStatus(Download.QUEUE); if (!hasPendingDownloads) hasPendingDownloads = true; downloadsQueueSubject.onNext(download); } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersFragment.java index 8f44b938d9..a0cddef161 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersFragment.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersFragment.java @@ -18,6 +18,8 @@ import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.ImageView; +import com.afollestad.materialdialogs.MaterialDialog; + import java.util.List; import butterknife.Bind; @@ -35,6 +37,8 @@ import eu.kanade.mangafeed.util.ToastUtil; import nucleus.factory.RequiresPresenter; import rx.Observable; import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; @RequiresPresenter(ChaptersPresenter.class) public class ChaptersFragment extends BaseRxFragment implements @@ -192,10 +196,10 @@ public class ChaptersFragment extends BaseRxFragment implemen holder.onProgressChange(getContext(), download.downloadedImages, download.pages.size()); } - public void onChapterStatusChange(Download download) { - ChaptersHolder holder = getHolder(download.chapter); + public void onChapterStatusChange(Chapter chapter) { + ChaptersHolder holder = getHolder(chapter); if (holder != null) - holder.onStatusChange(download.getStatus()); + holder.onStatusChange(chapter.status); } @Nullable @@ -240,8 +244,13 @@ public class ChaptersFragment extends BaseRxFragment implemen } private Observable getSelectedChapters() { - return Observable.from(adapter.getSelectedItems()) - .map(adapter::getItem); + // Create a blocking copy of the selected chapters. + // When the action mode is closed the list is cleared. If we use background + // threads with this observable, some emissions could be lost. + List chapters = Observable.from(adapter.getSelectedItems()) + .map(adapter::getItem).toList().toBlocking().single(); + + return Observable.from(chapters); } public void closeActionMode() { @@ -268,13 +277,45 @@ public class ChaptersFragment extends BaseRxFragment implemen protected boolean onDownload(Observable chapters) { DownloadService.start(getActivity()); - getPresenter().downloadChapters(chapters); + + Observable observable = chapters + .doOnNext(chapter -> { + // Force update of the UI. We already receive updates when it's added to the queue, + // but sometimes it does nothing. + // TODO remove this when status updates works properly + chapter.status = Download.QUEUE; + onChapterStatusChange(chapter); + }); + + getPresenter().downloadChapters(observable); closeActionMode(); return true; } protected boolean onDelete(Observable chapters) { - getPresenter().deleteChapters(chapters); + int size = adapter.getSelectedItemCount(); + + MaterialDialog dialog = new MaterialDialog.Builder(getActivity()) + .title(R.string.deleting) + .progress(false, size, true) + .cancelable(false) + .show(); + + Observable observable = chapters + .concatMap(chapter -> { + getPresenter().deleteChapter(chapter); + return Observable.just(chapter); + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(chapter -> { + dialog.incrementProgress(1); + chapter.status = Download.NOT_DOWNLOADED; + onChapterStatusChange(chapter); + }) + .finallyDo(dialog::dismiss); + + getPresenter().deleteChapters(observable); closeActionMode(); return true; } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java b/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java index 5193b7d68b..2ae9c540fa 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java @@ -65,7 +65,7 @@ public class ChaptersPresenter extends BasePresenter { restartableLatestCache(CHAPTER_STATUS_CHANGES, this::getChapterStatusObs, - (view, download) -> view.onChapterStatusChange(download), + (view, download) -> view.onChapterStatusChange(download.chapter), (view, error) -> Timber.e(error.getCause(), error.getMessage())); registerForStickyEvents(); @@ -210,10 +210,7 @@ public class ChaptersPresenter extends BasePresenter { public void deleteChapters(Observable selectedChapters) { add(selectedChapters .subscribe(chapter -> { - // Somehow I can't delete files on Schedulers.io() - downloadManager.deleteChapter(source, manga, chapter); downloadManager.getQueue().remove(chapter); - chapter.status = Download.NOT_DOWNLOADED; }, error -> { Timber.e(error.getMessage()); }, () -> { @@ -222,6 +219,10 @@ public class ChaptersPresenter extends BasePresenter { })); } + public void deleteChapter(Chapter chapter) { + downloadManager.deleteChapter(source, manga, chapter); + } + public void revertSortOrder() { //TODO manga.chapter_order sortOrderAToZ = !sortOrderAToZ; diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsCacheFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsCacheFragment.java index 87fc5a53bd..81a04fe86a 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsCacheFragment.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsCacheFragment.java @@ -60,7 +60,7 @@ public class SettingsCacheFragment extends SettingsNestedFragment implements Pre File[] files = cacheManager.getCacheDir().listFiles(); MaterialDialog dialog = new MaterialDialog.Builder(getActivity()) - .title(R.string.deleting_files) + .title(R.string.deleting) .progress(false, files.length, true) .cancelable(false) .dismissListener(d -> { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 07b570189e..576024c764 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -30,7 +30,7 @@ Cancel - Deleting files… + Deleting… Loading…