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:
parent
ae5ad2a9a6
commit
72e7b649a2
@ -258,12 +258,6 @@ repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
experimental {
|
||||
coroutines 'enable'
|
||||
}
|
||||
}
|
||||
|
||||
androidExtensions {
|
||||
experimental = true
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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.
|
||||
*/
|
||||
|
@ -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>) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 ->
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user