Updates To Snackbar logic

Removed experimnetal coroutines
Snackbar for removing mangas now remove downloads when they disappear.
Undo Snackbars now disappear when touching somewhere thats not them
Opening Tachiyomi from a url (ie mangadex) now automatically goes to the manga page once the search finishes
Fixed self made typo in "Update Library"
Removed Delete Mangas dialog as it is unused
This commit is contained in:
Jay 2019-11-10 17:16:39 -08:00
parent ae5ad2a9a6
commit 72e7b649a2
17 changed files with 188 additions and 165 deletions

View File

@ -258,12 +258,6 @@ repositories {
mavenCentral()
}
kotlin {
experimental {
coroutines 'enable'
}
}
androidExtensions {
experimental = true
}

View File

@ -67,25 +67,4 @@ class CoverCache(private val context: Context) {
val file = getCoverFile(thumbnailUrl)
return file.exists() && file.delete()
}
/**
* Delete the cover file from the cache.
*
* @param thumbnailUrl the thumbnail url.
* @return status of deletion.
*/
fun deleteFromCache(manga: Manga, delayBy:Long) {
val thumbnailUrl = manga.thumbnail_url
// Check if url is empty.
if (thumbnailUrl.isNullOrEmpty()) return
launchUI {
delay(delayBy)
if (!manga.favorite) {
// Remove file.
val file = getCoverFile(thumbnailUrl)
if (file.exists()) file.delete()
}
}
}
}

View File

@ -190,22 +190,6 @@ class DownloadManager(context: Context) {
cache.removeManga(manga)
}
/**
* Deletes the directory of a downloaded manga.
*
* @param manga the manga to delete.
* @param source the source of the manga.
*/
fun deleteManga(manga: Manga, source: Source, delayBy: Long) {
launchUI {
delay(delayBy)
if (!manga.favorite) {
deleteManga(manga, source)
}
}
}
/**
* Adds a list of chapters to be deleted later.
*

View File

@ -64,7 +64,7 @@ class NotificationReceiver : BroadcastReceiver() {
ACTION_DELETE_IMAGE -> deleteImage(context, intent.getStringExtra(EXTRA_FILE_LOCATION),
intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1))
// Cancel library update and dismiss notification
ACTION_CANCEL_LIBRARY_UPDATE -> cancelLibraryUpdate(context, Notifications.ID_LIBRARY_PROGRESS)
ACTION_CANCEL_LIBRARY_UPDATE -> cancelLibraryUpdate(context)
// Open reader activity
ACTION_OPEN_CHAPTER -> {
openChapter(context, intent.getLongExtra(EXTRA_MANGA_ID, -1),
@ -76,7 +76,8 @@ class NotificationReceiver : BroadcastReceiver() {
context, notificationId, intent.getStringExtra(EXTRA_GROUP_ID)
)
val url = intent.getStringExtra(EXTRA_CHAPTER_URL) ?: return
markAsRead(url)
val mangaId = intent.getLongExtra(EXTRA_MANGA_ID, -1)
markAsRead(url, mangaId)
}
}
}
@ -157,9 +158,9 @@ class NotificationReceiver : BroadcastReceiver() {
* @param context context of application
* @param notificationId id of notification
*/
private fun cancelLibraryUpdate(context: Context, notificationId: Int) {
private fun cancelLibraryUpdate(context: Context) {
LibraryUpdateService.stop(context)
Handler().post { dismissNotification(context, notificationId) }
Handler().post { dismissNotification(context, Notifications.ID_LIBRARY_PROGRESS) }
}
/**
@ -168,9 +169,9 @@ class NotificationReceiver : BroadcastReceiver() {
* @param context context of application
* @param notificationId id of notification
*/
private fun markAsRead(chapterUrl: String) {
private fun markAsRead(chapterUrl: String, mangaaId: Long) {
val db: DatabaseHelper = Injekt.get()
val chapter = db.getChapter(chapterUrl).executeAsBlocking() ?: return
val chapter = db.getChapter(chapterUrl, mangaaId).executeAsBlocking() ?: return
chapter.read = true
db.updateChapterProgress(chapter).executeAsBlocking()
val preferences: PreferencesHelper = Injekt.get()
@ -398,6 +399,7 @@ class NotificationReceiver : BroadcastReceiver() {
val newIntent = Intent(context, NotificationReceiver::class.java).apply {
action = ACTION_MARK_AS_READ
putExtra(EXTRA_CHAPTER_URL, chapter.url)
putExtra(EXTRA_MANGA_ID, manga.id)
putExtra(EXTRA_NOTIFICATION_ID, manga.id.hashCode())
putExtra(EXTRA_GROUP_ID, groupId)
}

View File

@ -9,6 +9,7 @@ import android.view.*
import androidx.core.view.GravityCompat
import com.afollestad.materialdialogs.MaterialDialog
import com.f2prateek.rx.preferences.Preference
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.jakewharton.rxbinding.support.v7.widget.queryTextChangeEvents
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible
@ -24,6 +25,7 @@ import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
import eu.kanade.tachiyomi.ui.library.HeightTopWindowInsetsListener
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.manga.info.MangaWebViewController
import eu.kanade.tachiyomi.util.*
@ -501,18 +503,23 @@ open class BrowseCatalogueController(bundle: Bundle) :
* @param position the position of the element clicked.
*/
override fun onItemLongClick(position: Int) {
val activity = activity ?: return
val manga = (adapter?.getItem(position) as? CatalogueItem?)?.manga ?: return
snack?.dismiss()
if (manga.favorite) {
presenter.changeMangaFavorite(manga)
adapter?.notifyItemChanged(position)
snack =
catalouge_layout?.snack(R.string.manga_removed_library, 5000) {
snack = catalouge_layout?.snack(R.string.manga_removed_library, Snackbar.LENGTH_INDEFINITE) {
setAction(R.string.action_undo) {
if (!manga.favorite) addManga(manga, position)
}
addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
super.onDismissed(transientBottomBar, event)
if (!manga.favorite) presenter.confirmDeletion(manga)
}
})
}
(activity as? MainActivity)?.setUndoSnackBar(snack)
} else {
addManga(manga, position)
snack = catalouge_layout?.snack(R.string.manga_added_library)

View File

@ -254,14 +254,15 @@ open class BrowseCataloguePresenter(
*/
fun changeMangaFavorite(manga: Manga) {
manga.favorite = !manga.favorite
if (!manga.favorite) {
coverCache.deleteFromCache(manga, 5000)
val downloadManager: DownloadManager = Injekt.get()
downloadManager.deleteManga(manga,source,5000)
}
db.insertManga(manga).executeAsBlocking()
}
fun confirmDeletion(manga: Manga) {
coverCache.deleteFromCache(manga.thumbnail_url)
val downloadManager: DownloadManager = Injekt.get()
downloadManager.deleteManga(manga,source)
}
/**
* Changes the active display mode.
*/

View File

@ -171,12 +171,29 @@ open class CatalogueSearchController(
return null
}
override fun handleBack(): Boolean {
return if (extensionFilter != null) {
activity?.finishAffinity()
true
} else super.handleBack()
}
/**
* Add search result to adapter.
*
* @param searchResult result of search.
*/
fun setItems(searchResult: List<CatalogueSearchItem>) {
if (extensionFilter != null) {
val results = searchResult.first().results
if (results != null && results.size == 1) {
val manga = results.first().manga
router.pushController(MangaController(manga,true,fromExtension = true)
.withFadeTransaction()
)
return
}
}
adapter?.updateDataSet(searchResult)
}

View File

@ -1,43 +0,0 @@
package eu.kanade.tachiyomi.ui.library
import android.app.Dialog
import android.os.Bundle
import com.afollestad.materialdialogs.MaterialDialog
import com.bluelinelabs.conductor.Controller
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.widget.DialogCheckboxView
class DeleteLibraryMangasDialog<T>(bundle: Bundle? = null) :
DialogController(bundle) where T : Controller, T: DeleteLibraryMangasDialog.Listener {
private var mangas = emptyList<Manga>()
constructor(target: T, mangas: List<Manga>) : this() {
this.mangas = mangas
targetController = target
}
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val view = DialogCheckboxView(activity!!).apply {
setDescription(R.string.confirm_delete_manga)
setOptionDescription(R.string.also_delete_chapters)
}
return MaterialDialog.Builder(activity!!)
.title(R.string.action_remove)
.customView(view, true)
.positiveText(android.R.string.yes)
.negativeText(android.R.string.no)
.onPositive { _, _ ->
val deleteChapters = view.isChecked()
(targetController as? Listener)?.deleteMangasFromLibrary(mangas, deleteChapters)
}
.build()
}
interface Listener {
fun deleteMangasFromLibrary(mangas: List<Manga>, deleteChapters: Boolean)
}
}

View File

@ -21,6 +21,7 @@ import androidx.core.view.GravityCompat
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType
import com.f2prateek.rx.preferences.Preference
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout
import com.jakewharton.rxbinding.support.v4.view.pageSelections
@ -66,7 +67,6 @@ class LibraryController(
SecondaryDrawerController,
ActionMode.Callback,
ChangeMangaCategoriesDialog.Listener,
DeleteLibraryMangasDialog.Listener,
MigrationInterface {
/**
@ -530,14 +530,24 @@ class LibraryController(
private fun deleteMangasFromLibrary() {
val mangas = selectedMangas.toList()
presenter.removeMangaFromLibrary(mangas, true)
presenter.removeMangaFromLibrary(mangas)
destroyActionModeIfNeeded()
snack?.dismiss()
snack = view?.snack(activity?.getString(R.string.manga_removed_library) ?: "", 5000) {
snack = view?.snack(activity?.getString(R.string.manga_removed_library) ?: "", Snackbar.LENGTH_INDEFINITE) {
var undoing = false
setAction(R.string.action_undo) {
presenter.addMangas(mangas)
undoing = true
}
addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
super.onDismissed(transientBottomBar, event)
if (!undoing)
presenter.confirmDeletion(mangas)
}
})
}
(activity as? MainActivity)?.setUndoSnackBar(snack)
}
override fun updateCategoriesForMangas(mangas: List<Manga>, categories: List<Category>) {
@ -545,11 +555,6 @@ class LibraryController(
destroyActionModeIfNeeded()
}
override fun deleteMangasFromLibrary(mangas: List<Manga>, deleteChapters: Boolean) {
presenter.removeMangaFromLibrary(mangas, deleteChapters)
destroyActionModeIfNeeded()
}
/**
* Changes the cover for the selected manga.
*/

View File

@ -305,7 +305,7 @@ class LibraryPresenter(
* @param mangas the list of manga to delete.
* @param deleteChapters whether to also delete downloaded chapters.
*/
fun removeMangaFromLibrary(mangas: List<Manga>, deleteChapters: Boolean) {
fun removeMangaFromLibrary(mangas: List<Manga>) {
// Create a set of the list
val mangaToDelete = mangas.distinctBy { it.id }
mangaToDelete.forEach { it.favorite = false }
@ -314,20 +314,18 @@ class LibraryPresenter(
.onErrorResumeNext { Observable.empty() }
.subscribeOn(Schedulers.io())
.subscribe()
}
fun confirmDeletion(mangas: List<Manga>) {
Observable.fromCallable {
val mangaToDelete = mangas.distinctBy { it.id }
mangaToDelete.forEach { manga ->
coverCache.deleteFromCache(manga, 5000)
if (deleteChapters) {
coverCache.deleteFromCache(manga.thumbnail_url)
val source = sourceManager.get(manga.source) as? HttpSource
if (source != null) {
downloadManager.deleteManga(manga, source, 5000)
if (source != null)
downloadManager.deleteManga(manga, source)
}
}
}
}
.subscribeOn(Schedulers.io())
.subscribe()
}.subscribeOn(Schedulers.io()).subscribe()
}
fun addMangas(mangas: List<Manga>) {

View File

@ -5,25 +5,19 @@ import android.app.SearchManager
import android.content.Intent
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.Rect
import android.os.Build
import android.os.Bundle
import androidx.annotation.NonNull
import androidx.annotation.Px
import androidx.annotation.RequiresApi
import android.view.MotionEvent
import androidx.core.view.GravityCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.*
import androidx.appcompat.graphics.drawable.DrawerArrowDrawable
import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
import android.view.WindowManager
import android.widget.FrameLayout
import android.widget.LinearLayout
import com.bluelinelabs.conductor.*
import com.google.android.material.snackbar.Snackbar
import eu.kanade.tachiyomi.Migrations
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
@ -34,7 +28,6 @@ import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
import eu.kanade.tachiyomi.ui.download.DownloadController
import eu.kanade.tachiyomi.ui.extension.ExtensionController
import eu.kanade.tachiyomi.ui.library.HeightTopWindowInsetsListener
import eu.kanade.tachiyomi.ui.library.LibraryController
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController
@ -42,17 +35,17 @@ import eu.kanade.tachiyomi.ui.recently_read.RecentlyReadController
import eu.kanade.tachiyomi.ui.setting.SettingsMainController
import eu.kanade.tachiyomi.util.NoopWindowInsetsListener
import eu.kanade.tachiyomi.util.doOnApplyWindowInsets
import eu.kanade.tachiyomi.util.launchUI
import eu.kanade.tachiyomi.util.marginBottom
import eu.kanade.tachiyomi.util.marginTop
import eu.kanade.tachiyomi.util.openInBrowser
import eu.kanade.tachiyomi.util.updateLayoutParams
import eu.kanade.tachiyomi.util.updatePadding
import eu.kanade.tachiyomi.util.updatePaddingRelative
import kotlinx.android.synthetic.main.chapters_controller.view.*
import kotlinx.android.synthetic.main.main_activity.*
import kotlinx.coroutines.delay
import uy.kohesive.injekt.injectLazy
class MainActivity : BaseActivity() {
private lateinit var router: Router
@ -63,6 +56,25 @@ class MainActivity : BaseActivity() {
private var secondaryDrawer: ViewGroup? = null
private var snackBar:Snackbar? = null
var extraRectForUndo:Rect? = null
private var canDismissSnackBar = false
fun setUndoSnackBar(snackBar: Snackbar?, extraViewToCheck: View? = null) {
this.snackBar = snackBar
canDismissSnackBar = false
launchUI {
delay(1000)
canDismissSnackBar = true
}
if (extraViewToCheck != null) {
extraRectForUndo = Rect()
extraViewToCheck.getGlobalVisibleRect(extraRectForUndo)
}
else
extraRectForUndo = null
}
private val startScreenId by lazy {
when (preferences.startScreen()) {
2 -> R.id.nav_drawer_recently_read
@ -296,6 +308,28 @@ class MainActivity : BaseActivity() {
router.setRoot(controller.withFadeTransaction().tag(id.toString()))
}
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
if (ev?.action == MotionEvent.ACTION_DOWN) {
if (snackBar != null && snackBar!!.isShown) {
val sRect = Rect()
snackBar!!.view.getGlobalVisibleRect(sRect)
//This way the snackbar will only be dismissed if
//the user clicks outside it.
if (canDismissSnackBar && !sRect.contains(ev.x.toInt(), ev.y.toInt())
&& (extraRectForUndo == null ||
!extraRectForUndo!!.contains(ev.x.toInt(), ev.y.toInt()))) {
snackBar?.dismiss()
snackBar = null
extraRectForUndo = null
}
}
else if (snackBar != null)
snackBar = null
}
return super.dispatchTouchEvent(ev)
}
private fun syncActivityViewWithController(to: Controller?, from: Controller? = null) {
if (from is DialogController || to is DialogController) {
return

View File

@ -1,22 +1,20 @@
package eu.kanade.tachiyomi.ui.manga
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.app.Activity
import android.os.Bundle
import com.google.android.material.tabs.TabLayout
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType
import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.support.RouterPagerAdapter
import com.google.android.material.tabs.TabLayout
import com.jakewharton.rxrelay.BehaviorRelay
import com.jakewharton.rxrelay.PublishRelay
import eu.kanade.tachiyomi.R
@ -42,7 +40,10 @@ import java.util.Date
class MangaController : RxController, TabbedController {
constructor(manga: Manga?, fromCatalogue: Boolean = false) : super(Bundle().apply {
constructor(manga: Manga?, fromCatalogue: Boolean = false, fromExtension: Boolean = false) :
super
(Bundle()
.apply {
putLong(MANGA_EXTRA, manga?.id ?: 0)
putBoolean(FROM_CATALOGUE_EXTRA, fromCatalogue)
}) {
@ -50,6 +51,7 @@ class MangaController : RxController, TabbedController {
if (manga != null) {
source = Injekt.get<SourceManager>().getOrStub(manga.source)
}
backClosesApp = fromExtension
}
constructor(manga: Manga?, startY:Float?) : super(Bundle().apply {
@ -74,12 +76,32 @@ class MangaController : RxController, TabbedController {
)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
backClosesApp = false
super.onRestoreInstanceState(savedInstanceState)
}
override fun onActivityResumed(activity: Activity) {
backClosesApp = false
super.onActivityResumed(activity)
}
override fun handleBack(): Boolean {
return if (backClosesApp) {
activity?.finishAffinity()
true
} else super.handleBack()
}
var manga: Manga? = null
private set
var source: Source? = null
private set
var backClosesApp = false
private set
var startingChapterYPos:Float? = null
private var adapter: MangaDetailAdapter? = null

View File

@ -34,6 +34,7 @@ import android.content.Context
import android.util.AttributeSet
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.ui.main.MainActivity
import kotlin.math.*
class ChaptersController() : NucleusController<ChaptersPresenter>(),
@ -411,9 +412,9 @@ class ChaptersController() : NucleusController<ChaptersPresenter>(),
val view = view
destroyActionModeIfNeeded()
presenter.downloadChapters(chapters)
if (view != null && !presenter.manga.favorite && (snack == null || snack?.getText() != view.context.getString(R.string.snack_add_to_library))) {
snack =
view.snack(view.context.getString(R.string.snack_add_to_library), Snackbar.LENGTH_INDEFINITE) {
if (view != null && !presenter.manga.favorite && (snack == null ||
snack?.getText() != view.context.getString(R.string.snack_add_to_library))) {
snack = view.snack(view.context.getString(R.string.snack_add_to_library), Snackbar.LENGTH_INDEFINITE) {
setAction(R.string.action_add) {
presenter.addToLibrary()
}
@ -424,6 +425,7 @@ class ChaptersController() : NucleusController<ChaptersPresenter>(),
}
})
}
(activity as? MainActivity)?.setUndoSnackBar(snack)
}
}

View File

@ -11,18 +11,22 @@ import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import com.google.android.material.snackbar.Snackbar
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
import android.view.*
import android.widget.Toast
import com.afollestad.materialdialogs.MaterialDialog
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import com.jakewharton.rxbinding.support.v4.widget.refreshes
import com.jakewharton.rxbinding.view.clicks
import com.jakewharton.rxbinding.view.longClicks
@ -42,7 +46,14 @@ import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.util.*
import eu.kanade.tachiyomi.util.doOnApplyWindowInsets
import eu.kanade.tachiyomi.util.getUriCompat
import eu.kanade.tachiyomi.util.marginBottom
import eu.kanade.tachiyomi.util.openInBrowser
import eu.kanade.tachiyomi.util.snack
import eu.kanade.tachiyomi.util.toast
import eu.kanade.tachiyomi.util.updateLayoutParams
import eu.kanade.tachiyomi.util.updatePaddingRelative
import jp.wasabeef.glide.transformations.CropSquareTransformation
import jp.wasabeef.glide.transformations.MaskTransformation
import kotlinx.android.synthetic.main.manga_info_controller.*
@ -460,11 +471,19 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
val view = container
snack?.dismiss()
if (view != null) {
snack = view.snack(view.context.getString(R.string.manga_removed_library), 5000) {
snack = view.snack(view.context.getString(R.string.manga_removed_library), Snackbar.LENGTH_INDEFINITE) {
setAction(R.string.action_undo) {
presenter.setFavorite(true)
}
addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
super.onDismissed(transientBottomBar, event)
if (!presenter.manga.favorite)
presenter.confirmDeletion()
}
})
}
(activity as? MainActivity)?.setUndoSnackBar(snack, fab_favorite)
}
}
@ -480,7 +499,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
val categories = presenter.getCategories()
if (categories.isEmpty()) {
// no categories exist, display a message about adding categories
activity?.toast(activity?.getString(R.string.action_add_category))
snack = container?.snack(R.string.action_add_category)
} else {
val ids = presenter.getMangaCategoryIds(manga)
val preselected = ids.mapNotNull { id ->

View File

@ -109,15 +109,16 @@ class MangaInfoPresenter(
*/
fun toggleFavorite(): Boolean {
manga.favorite = !manga.favorite
if (!manga.favorite) {
coverCache.deleteFromCache(manga, 5000)
downloadManager.deleteManga(manga, source, 5000)
}
db.insertManga(manga).executeAsBlocking()
sendMangaToView()
return manga.favorite
}
fun confirmDeletion() {
coverCache.deleteFromCache(manga.thumbnail_url)
downloadManager.deleteManga(manga, source)
}
fun setFavorite(favorite: Boolean) {
if (manga.favorite == favorite) {
return

View File

@ -89,7 +89,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
swipe_refresh.refreshes().subscribeUntilDestroy {
if (!LibraryUpdateService.isRunning(view.context)) {
LibraryUpdateService.start(view.context)
view.snack(R.string.action_update_library)
view.snack(R.string.updating_library)
}
// It can be a very long operation, so we disable swipe refresh and show a snackbar.
swipe_refresh.isRefreshing = false

View File

@ -50,7 +50,7 @@
<string name="action_remove_bookmark">Remove bookmark</string>
<string name="action_delete">Delete</string>
<string name="action_update">Update</string>
<string name="action_update_library">Updating library</string>
<string name="action_update_library">Update library</string>
<string name="action_edit">Edit</string>
<string name="action_add">Add</string>
<string name="action_add_category">Add category</string>
@ -317,6 +317,7 @@
<!-- Library fragment -->
<string name="library_search_hint">Title or author…</string>
<string name="updating_library">Updating library</string>
<string name="updating_category">Updating category</string>
<string name="local_source_badge">Local</string>
<string name="confirm_delete_manga">Are you sure you want to remove selected manga?</string>