From f7c791d153bb9f819e18151414c7cffc4ecacf3a Mon Sep 17 00:00:00 2001 From: len Date: Fri, 3 Feb 2017 20:14:33 +0100 Subject: [PATCH] Ask for chapter deletion when removing from library --- .../tachiyomi/ui/library/LibraryFragment.kt | 12 +++++-- .../tachiyomi/ui/library/LibraryPresenter.kt | 29 ++++++++++++----- .../ui/manga/info/MangaInfoFragment.kt | 31 ++++++++++++++++--- .../ui/manga/info/MangaInfoPresenter.kt | 24 ++++++++++++-- .../tachiyomi/widget/DialogCheckboxView.kt | 5 +-- app/src/main/res/values/strings.xml | 2 ++ 6 files changed, 85 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt index 9a0787cd02..c0663516be 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt @@ -25,6 +25,7 @@ import eu.kanade.tachiyomi.ui.category.CategoryActivity import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.util.inflate import eu.kanade.tachiyomi.util.toast +import eu.kanade.tachiyomi.widget.DialogCheckboxView import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.fragment_library.* import nucleus.factory.RequiresPresenter @@ -480,12 +481,19 @@ class LibraryFragment : BaseRxFragment(), ActionMode.Callback } private fun showDeleteMangaDialog() { + val view = DialogCheckboxView(context).apply { + setDescription(R.string.confirm_delete_manga) + setOptionDescription(R.string.also_delete_chapters) + } + MaterialDialog.Builder(activity) - .content(R.string.confirm_delete_manga) + .title(R.string.action_remove) + .customView(view, true) .positiveText(android.R.string.yes) .negativeText(android.R.string.no) .onPositive { dialog, action -> - presenter.removeMangaFromLibrary() + val deleteChapters = view.isChecked() + presenter.removeMangaFromLibrary(deleteChapters) destroyActionModeIfNeeded() } .show() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index 45e1d53813..176c1f6cd3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.source.LocalSource import eu.kanade.tachiyomi.source.SourceManager +import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.util.combineLatest import eu.kanade.tachiyomi.util.isNullOrUnsubscribed @@ -303,19 +304,31 @@ class LibraryPresenter : BasePresenter() { /** * Remove the selected manga from the library. + * + * @param deleteChapters whether to also delete downloaded chapters. */ - fun removeMangaFromLibrary() { + fun removeMangaFromLibrary(deleteChapters: Boolean) { // Create a set of the list - val mangaToDelete = selectedMangas.toSet() + val mangaToDelete = selectedMangas.distinctBy { it.id } + mangaToDelete.forEach { it.favorite = false } - Observable.from(mangaToDelete) + Observable.fromCallable { db.insertMangas(mangaToDelete).executeAsBlocking() } + .onErrorResumeNext { Observable.empty() } .subscribeOn(Schedulers.io()) - .doOnNext { - it.favorite = false - coverCache.deleteFromCache(it.thumbnail_url) + .subscribe() + + Observable.fromCallable { + mangaToDelete.forEach { manga -> + coverCache.deleteFromCache(manga.thumbnail_url) + if (deleteChapters) { + val source = sourceManager.get(manga.source) as? HttpSource + if (source != null) { + downloadManager.findMangaDir(source, manga)?.delete() + } } - .toList() - .flatMap { db.insertMangas(it).asRxObservable() } + } + } + .subscribeOn(Schedulers.io()) .subscribe() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.kt index 5b808ff73f..e874f034c4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.kt @@ -20,6 +20,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment import eu.kanade.tachiyomi.ui.manga.MangaActivity import eu.kanade.tachiyomi.util.getResourceColor +import eu.kanade.tachiyomi.util.snack import eu.kanade.tachiyomi.util.toast import jp.wasabeef.glide.transformations.CropCircleTransformation import jp.wasabeef.glide.transformations.CropSquareTransformation @@ -62,7 +63,7 @@ class MangaInfoFragment : BaseRxFragment() { override fun onViewCreated(view: View?, savedState: Bundle?) { // Set onclickListener to toggle favorite when FAB clicked. - fab_favorite.setOnClickListener { presenter.toggleFavorite() } + fab_favorite.setOnClickListener { toggleFavorite() } // Set SwipeRefresh to refresh manga data. swipe_refresh.setOnRefreshListener { fetchMangaFromSource() } @@ -160,13 +161,31 @@ class MangaInfoFragment : BaseRxFragment() { manga_chapters.text = count.toString() } + /** + * Toggles the favorite status and asks for confirmation to delete downloaded chapters. + */ + fun toggleFavorite() { + if (!isAdded) return + + val isNowFavorite = presenter.toggleFavorite() + if (!isNowFavorite && presenter.hasDownloads()) { + view!!.snack(getString(R.string.delete_downloads_for_manga)) { + setAction(R.string.action_delete) { + presenter.deleteDownloads() + } + } + } + } + /** * Open the manga in browser. */ fun openInBrowser() { + if (!isAdded) return + val source = presenter.source as? HttpSource ?: return try { - val url = Uri.parse(source.baseUrl + presenter.manga.url) + val url = Uri.parse(source.mangaDetailsRequest(presenter.manga).url().toString()) val intent = CustomTabsIntent.Builder() .setToolbarColor(context.getResourceColor(R.attr.colorPrimary)) .build() @@ -180,14 +199,16 @@ class MangaInfoFragment : BaseRxFragment() { * Called to run Intent with [Intent.ACTION_SEND], which show share dialog. */ private fun shareManga() { + if (!isAdded) return + val source = presenter.source as? HttpSource ?: return try { val url = source.mangaDetailsRequest(presenter.manga).url().toString() val sharingIntent = Intent(Intent.ACTION_SEND).apply { type = "text/plain" - putExtra(android.content.Intent.EXTRA_TEXT, resources.getString(R.string.share_text, presenter.manga.title, url)) + putExtra(Intent.EXTRA_TEXT, getString(R.string.share_text, presenter.manga.title, url)) } - startActivity(Intent.createChooser(sharingIntent, resources.getText(R.string.action_share))) + startActivity(Intent.createChooser(sharingIntent, getString(R.string.action_share))) } catch (e: Exception) { context.toast(e.message) } @@ -197,6 +218,8 @@ class MangaInfoFragment : BaseRxFragment() { * Add the manga to the home screen */ fun addToHomeScreen() { + if (!isAdded) return + val shortcutIntent = activity.intent shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) .putExtra(MangaActivity.FROM_LAUNCHER_EXTRA, true) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt index 048c54c73a..3db68e5fb4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt @@ -4,6 +4,7 @@ import android.os.Bundle import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Manga +import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter @@ -50,6 +51,8 @@ class MangaInfoPresenter : BasePresenter() { */ val coverCache: CoverCache by injectLazy() + private val downloadManager: DownloadManager by injectLazy() + /** * Subscription to send the manga to the view. */ @@ -75,7 +78,7 @@ class MangaInfoPresenter : BasePresenter() { // Update favorite status SharedData.get(MangaFavoriteEvent::class.java)?.observable ?.observeOn(AndroidSchedulers.mainThread()) - ?.subscribe{setFavorite(it)} + ?.subscribe { setFavorite(it) } } /** @@ -111,14 +114,17 @@ class MangaInfoPresenter : BasePresenter() { /** * Update favorite status of manga, (removes / adds) manga (to / from) library. + * + * @return the new status of the manga. */ - fun toggleFavorite() { + fun toggleFavorite(): Boolean { manga.favorite = !manga.favorite if (!manga.favorite) { coverCache.deleteFromCache(manga.thumbnail_url) } db.insertManga(manga).executeAsBlocking() sendMangaToView() + return manga.favorite } private fun setFavorite(favorite: Boolean) { @@ -128,4 +134,18 @@ class MangaInfoPresenter : BasePresenter() { toggleFavorite() } + /** + * Returns true if the manga has any downloads. + */ + fun hasDownloads(): Boolean { + return downloadManager.findMangaDir(source, manga) != null + } + + /** + * Deletes all the downloads for the manga. + */ + fun deleteDownloads() { + downloadManager.findMangaDir(source, manga)?.delete() + } + } diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCheckboxView.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCheckboxView.kt index 5a0d2a3295..e84826004a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCheckboxView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCheckboxView.kt @@ -4,14 +4,15 @@ import android.content.Context import android.support.annotation.StringRes import android.util.AttributeSet import android.widget.LinearLayout -import android.widget.RelativeLayout import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.util.inflate import kotlinx.android.synthetic.main.dialog_with_checkbox.view.* class DialogCheckboxView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : LinearLayout(context, attrs) { + init { - RelativeLayout.inflate(context, R.layout.dialog_with_checkbox, this) + addView(inflate(R.layout.dialog_with_checkbox)) } fun setDescription(@StringRes id: Int){ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b980a00158..d4e29f6fc8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -218,6 +218,7 @@ Title or author… Updating category Are you sure you want to remove selected manga? + Also delete downloaded chapters This source requires you to log in @@ -251,6 +252,7 @@ Shortcut title Icon shape Failed to create shortcut! + Delete downloaded chapters? Chapters