Ask for chapter deletion when removing from library

This commit is contained in:
len 2017-02-03 20:14:33 +01:00
parent b66f06d9dc
commit f7c791d153
6 changed files with 85 additions and 18 deletions

View file

@ -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()

View file

@ -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()
}

View file

@ -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)

View file

@ -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()
}
}

View file

@ -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){

View file

@ -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>