Ask for chapter deletion when removing from library
This commit is contained in:
parent
b66f06d9dc
commit
f7c791d153
6 changed files with 85 additions and 18 deletions
|
@ -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<LibraryPresenter>(), 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()
|
||||
|
|
|
@ -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<LibraryFragment>() {
|
|||
|
||||
/**
|
||||
* 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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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<MangaInfoPresenter>() {
|
|||
|
||||
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<MangaInfoPresenter>() {
|
|||
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<MangaInfoPresenter>() {
|
|||
* 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<MangaInfoPresenter>() {
|
|||
* 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)
|
||||
|
|
|
@ -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<MangaInfoFragment>() {
|
|||
*/
|
||||
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<MangaInfoFragment>() {
|
|||
// 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<MangaInfoFragment>() {
|
|||
|
||||
/**
|
||||
* 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<MangaInfoFragment>() {
|
|||
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()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -218,6 +218,7 @@
|
|||
<string name="library_search_hint">Title or author…</string>
|
||||
<string name="updating_category">Updating category</string>
|
||||
<string name="confirm_delete_manga">Are you sure you want to remove selected manga?</string>
|
||||
<string name="also_delete_chapters">Also delete downloaded chapters</string>
|
||||
|
||||
<!-- Catalogue fragment -->
|
||||
<string name="source_requires_login">This source requires you to log in</string>
|
||||
|
@ -251,6 +252,7 @@
|
|||
<string name="shortcut_title">Shortcut title</string>
|
||||
<string name="icon_shape">Icon shape</string>
|
||||
<string name="icon_creation_fail">Failed to create shortcut!</string>
|
||||
<string name="delete_downloads_for_manga">Delete downloaded chapters?</string>
|
||||
|
||||
<!-- Manga chapters fragment -->
|
||||
<string name="manga_chapters_tab">Chapters</string>
|
||||
|
|
Reference in a new issue