arkon 4 лет назад
Родитель
Сommit
9f7fda0bc5

+ 0 - 79
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt

@@ -1,7 +1,5 @@
 package eu.kanade.tachiyomi.ui.library
 
-import android.app.Activity
-import android.content.Intent
 import android.content.res.Configuration
 import android.os.Bundle
 import android.view.LayoutInflater
@@ -37,7 +35,6 @@ import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
 import eu.kanade.tachiyomi.ui.main.MainActivity
 import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
 import eu.kanade.tachiyomi.ui.manga.MangaController
-import eu.kanade.tachiyomi.util.hasCustomCover
 import eu.kanade.tachiyomi.util.system.getResourceColor
 import eu.kanade.tachiyomi.util.system.toast
 import eu.kanade.tachiyomi.util.view.gone
@@ -52,7 +49,6 @@ import reactivecircus.flowbinding.android.view.clicks
 import reactivecircus.flowbinding.appcompat.queryTextChanges
 import reactivecircus.flowbinding.viewpager.pageSelections
 import rx.Subscription
-import timber.log.Timber
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 
@@ -64,7 +60,6 @@ class LibraryController(
     RootController,
     TabbedController,
     ActionMode.Callback,
-    ChangeMangaCoverDialog.Listener,
     ChangeMangaCategoriesDialog.Listener,
     DeleteLibraryMangasDialog.Listener {
 
@@ -88,8 +83,6 @@ class LibraryController(
      */
     val selectedMangas = mutableSetOf<Manga>()
 
-    private var selectedCoverManga: Manga? = null
-
     /**
      * Relay to notify the UI of selection updates.
      */
@@ -468,7 +461,6 @@ class LibraryController(
         } else {
             mode.title = count.toString()
 
-            binding.actionToolbar.findItem(R.id.action_edit_cover)?.isVisible = count == 1
             binding.actionToolbar.findItem(R.id.action_download_unread)?.isVisible = selectedMangas.any { it.source != LocalSource.ID }
         }
         return false
@@ -480,7 +472,6 @@ class LibraryController(
 
     private fun onActionItemClicked(item: MenuItem): Boolean {
         when (item.itemId) {
-            R.id.action_edit_cover -> handleChangeCover()
             R.id.action_move_to_category -> showChangeMangaCategoriesDialog()
             R.id.action_download_unread -> downloadUnreadChapters()
             R.id.action_delete -> showDeleteMangaDialog()
@@ -540,23 +531,6 @@ class LibraryController(
         }
     }
 
-    private fun handleChangeCover() {
-        val manga = selectedMangas.firstOrNull() ?: return
-
-        if (manga.hasCustomCover(coverCache)) {
-            showEditCoverDialog(manga)
-        } else {
-            openMangaCoverPicker(manga)
-        }
-    }
-
-    /**
-     * Edit custom cover for selected manga.
-     */
-    private fun showEditCoverDialog(manga: Manga) {
-        ChangeMangaCoverDialog(this, manga).showDialog(router)
-    }
-
     /**
      * Move the selected manga to a list of categories.
      */
@@ -586,31 +560,6 @@ class LibraryController(
         DeleteLibraryMangasDialog(this, selectedMangas.toList()).showDialog(router)
     }
 
-    override fun openMangaCoverPicker(manga: Manga) {
-        selectedCoverManga = manga
-
-        if (manga.favorite) {
-            val intent = Intent(Intent.ACTION_GET_CONTENT)
-            intent.type = "image/*"
-            startActivityForResult(
-                Intent.createChooser(
-                    intent,
-                    resources?.getString(R.string.file_select_cover)
-                ),
-                REQUEST_IMAGE_OPEN
-            )
-        } else {
-            activity?.toast(R.string.notification_first_add_to_library)
-        }
-
-        destroyActionModeIfNeeded()
-    }
-
-    override fun deleteMangaCover(manga: Manga) {
-        presenter.deleteCustomCover(manga)
-        destroyActionModeIfNeeded()
-    }
-
     override fun updateCategoriesForMangas(mangas: List<Manga>, categories: List<Category>) {
         presenter.moveMangasToCategories(categories, mangas)
         destroyActionModeIfNeeded()
@@ -632,32 +581,4 @@ class LibraryController(
             selectInverseRelay.call(it)
         }
     }
-
-    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
-        if (requestCode == REQUEST_IMAGE_OPEN) {
-            val dataUri = data?.data
-            if (dataUri == null || resultCode != Activity.RESULT_OK) return
-            val activity = activity ?: return
-            val manga = selectedCoverManga ?: return
-
-            selectedCoverManga = null
-            presenter.editCover(manga, activity, dataUri)
-        }
-    }
-
-    fun onSetCoverSuccess() {
-        activity?.toast(R.string.cover_updated)
-    }
-
-    fun onSetCoverError(error: Throwable) {
-        activity?.toast(R.string.notification_cover_update_failed)
-        Timber.e(error)
-    }
-
-    private companion object {
-        /**
-         * Key to change the cover of a manga in [onActivityResult].
-         */
-        const val REQUEST_IMAGE_OPEN = 101
-    }
 }

+ 0 - 46
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt

@@ -1,7 +1,5 @@
 package eu.kanade.tachiyomi.ui.library
 
-import android.content.Context
-import android.net.Uri
 import android.os.Bundle
 import com.jakewharton.rxrelay.BehaviorRelay
 import eu.kanade.tachiyomi.data.cache.CoverCache
@@ -11,7 +9,6 @@ import eu.kanade.tachiyomi.data.database.models.Manga
 import eu.kanade.tachiyomi.data.database.models.MangaCategory
 import eu.kanade.tachiyomi.data.download.DownloadManager
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
-import eu.kanade.tachiyomi.source.LocalSource
 import eu.kanade.tachiyomi.source.SourceManager
 import eu.kanade.tachiyomi.source.model.SManga
 import eu.kanade.tachiyomi.source.online.HttpSource
@@ -21,7 +18,6 @@ import eu.kanade.tachiyomi.util.lang.combineLatest
 import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
 import eu.kanade.tachiyomi.util.lang.launchIO
 import eu.kanade.tachiyomi.util.removeCovers
-import eu.kanade.tachiyomi.util.updateCoverLastModified
 import java.util.Collections
 import java.util.Comparator
 import rx.Observable
@@ -374,46 +370,4 @@ class LibraryPresenter(
 
         db.setMangaCategories(mc, mangas)
     }
-
-    /**
-     * Update cover with local file.
-     *
-     * @param manga the manga edited.
-     * @param context Context.
-     * @param data uri of the cover resource.
-     */
-    fun editCover(manga: Manga, context: Context, data: Uri) {
-        Observable
-            .fromCallable {
-                context.contentResolver.openInputStream(data)?.use {
-                    if (manga.isLocal()) {
-                        LocalSource.updateCover(context, manga, it)
-                        manga.updateCoverLastModified(db)
-                    } else if (manga.favorite) {
-                        coverCache.setCustomCoverToCache(manga, it)
-                        manga.updateCoverLastModified(db)
-                    }
-                }
-            }
-            .subscribeOn(Schedulers.io())
-            .observeOn(AndroidSchedulers.mainThread())
-            .subscribeFirst(
-                { view, _ -> view.onSetCoverSuccess() },
-                { view, e -> view.onSetCoverError(e) }
-            )
-    }
-
-    fun deleteCustomCover(manga: Manga) {
-        Observable
-            .fromCallable {
-                coverCache.deleteCustomCover(manga)
-                manga.updateCoverLastModified(db)
-            }
-            .subscribeOn(Schedulers.io())
-            .observeOn(AndroidSchedulers.mainThread())
-            .subscribeFirst(
-                { view, _ -> view.onSetCoverSuccess() },
-                { view, e -> view.onSetCoverError(e) }
-            )
-    }
 }

+ 75 - 7
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt

@@ -26,6 +26,7 @@ import com.google.android.material.snackbar.Snackbar
 import eu.davidea.flexibleadapter.FlexibleAdapter
 import eu.davidea.flexibleadapter.SelectableAdapter
 import eu.kanade.tachiyomi.R
+import eu.kanade.tachiyomi.data.cache.CoverCache
 import eu.kanade.tachiyomi.data.database.DatabaseHelper
 import eu.kanade.tachiyomi.data.database.models.Category
 import eu.kanade.tachiyomi.data.database.models.Chapter
@@ -44,6 +45,7 @@ import eu.kanade.tachiyomi.ui.browse.migration.search.SearchController
 import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
 import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
 import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
+import eu.kanade.tachiyomi.ui.library.ChangeMangaCoverDialog
 import eu.kanade.tachiyomi.ui.library.LibraryController
 import eu.kanade.tachiyomi.ui.main.MainActivity
 import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
@@ -59,6 +61,7 @@ import eu.kanade.tachiyomi.ui.reader.ReaderActivity
 import eu.kanade.tachiyomi.ui.recent.history.HistoryController
 import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
 import eu.kanade.tachiyomi.ui.webview.WebViewActivity
+import eu.kanade.tachiyomi.util.hasCustomCover
 import eu.kanade.tachiyomi.util.system.getResourceColor
 import eu.kanade.tachiyomi.util.system.toast
 import eu.kanade.tachiyomi.util.view.getCoordinates
@@ -81,6 +84,7 @@ class MangaController :
     ActionMode.Callback,
     FlexibleAdapter.OnItemClickListener,
     FlexibleAdapter.OnItemLongClickListener,
+    ChangeMangaCoverDialog.Listener,
     ChangeMangaCategoriesDialog.Listener,
     DownloadCustomChaptersDialog.Listener,
     DeleteChaptersDialog.Listener {
@@ -113,6 +117,7 @@ class MangaController :
     private val fromSource = args.getBoolean(FROM_SOURCE_EXTRA, false)
 
     private val preferences: PreferencesHelper by injectLazy()
+    private val coverCache: CoverCache by injectLazy()
 
     private var mangaInfoAdapter: MangaInfoHeaderAdapter? = null
     private var chaptersHeaderAdapter: MangaChaptersHeaderAdapter? = null
@@ -310,7 +315,8 @@ class MangaController :
         // Hide download options for local manga
         menu.findItem(R.id.download_group).isVisible = !isLocalSource
 
-        // Hide migrate option for non-library manga
+        // Hide edit cover and migrate options for non-library manga
+        menu.findItem(R.id.action_edit_cover).isVisible = presenter.manga.favorite
         menu.findItem(R.id.action_migrate).isVisible = presenter.manga.favorite
     }
 
@@ -371,6 +377,7 @@ class MangaController :
                 activity?.invalidateOptionsMenu()
             }
 
+            R.id.action_edit_cover -> handleChangeCover()
             R.id.action_migrate -> migrateManga()
         }
         return super.onOptionsItemSelected(item)
@@ -582,22 +589,78 @@ class MangaController :
         }
     }
 
-    // Manga info - end
+    private fun handleChangeCover() {
+        val manga = manga ?: return
+        if (manga.hasCustomCover(coverCache)) {
+            showEditCoverDialog(manga)
+        } else {
+            openMangaCoverPicker(manga)
+        }
+    }
 
-    // Chapters list - start
+    /**
+     * Edit custom cover for selected manga.
+     */
+    private fun showEditCoverDialog(manga: Manga) {
+        ChangeMangaCoverDialog(this, manga).showDialog(router)
+    }
+
+    override fun openMangaCoverPicker(manga: Manga) {
+        if (manga.favorite) {
+            val intent = Intent(Intent.ACTION_GET_CONTENT)
+            intent.type = "image/*"
+            startActivityForResult(
+                Intent.createChooser(
+                    intent,
+                    resources?.getString(R.string.file_select_cover)
+                ),
+                REQUEST_IMAGE_OPEN
+            )
+        } else {
+            activity?.toast(R.string.notification_first_add_to_library)
+        }
+
+        destroyActionModeIfNeeded()
+    }
+
+    override fun deleteMangaCover(manga: Manga) {
+        presenter.deleteCustomCover(manga)
+        mangaInfoAdapter?.notifyDataSetChanged()
+        destroyActionModeIfNeeded()
+    }
+
+    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+        if (requestCode == REQUEST_IMAGE_OPEN) {
+            val dataUri = data?.data
+            if (dataUri == null || resultCode != Activity.RESULT_OK) return
+            val activity = activity ?: return
+            presenter.editCover(manga!!, activity, dataUri)
+        }
+    }
+
+    fun onSetCoverSuccess() {
+        mangaInfoAdapter?.notifyDataSetChanged()
+        activity?.toast(R.string.cover_updated)
+    }
+
+    fun onSetCoverError(error: Throwable) {
+        activity?.toast(R.string.notification_cover_update_failed)
+        Timber.e(error)
+    }
 
     /**
      * Initiates source migration for the specific manga.
      */
     private fun migrateManga() {
-        val controller =
-            SearchController(
-                presenter.manga
-            )
+        val controller = SearchController(presenter.manga)
         controller.targetController = this
         router.pushController(controller.withFadeTransaction())
     }
 
+    // Manga info - end
+
+    // Chapters list - start
+
     fun onNextChapters(chapters: List<ChapterItem>) {
         // If the list is empty and it hasn't requested previously, fetch chapters from source
         // We use presenter chapters instead because they are always unfiltered
@@ -943,5 +1006,10 @@ class MangaController :
     companion object {
         const val FROM_SOURCE_EXTRA = "from_source"
         const val MANGA_EXTRA = "manga"
+
+        /**
+         * Key to change the cover of a manga in [onActivityResult].
+         */
+        const val REQUEST_IMAGE_OPEN = 101
     }
 }

+ 46 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt

@@ -1,5 +1,7 @@
 package eu.kanade.tachiyomi.ui.manga
 
+import android.content.Context
+import android.net.Uri
 import android.os.Bundle
 import com.jakewharton.rxrelay.PublishRelay
 import eu.kanade.tachiyomi.data.cache.CoverCache
@@ -11,6 +13,7 @@ import eu.kanade.tachiyomi.data.database.models.MangaCategory
 import eu.kanade.tachiyomi.data.download.DownloadManager
 import eu.kanade.tachiyomi.data.download.model.Download
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
+import eu.kanade.tachiyomi.source.LocalSource
 import eu.kanade.tachiyomi.source.Source
 import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
 import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
@@ -21,6 +24,7 @@ import eu.kanade.tachiyomi.util.lang.launchIO
 import eu.kanade.tachiyomi.util.prepUpdateCover
 import eu.kanade.tachiyomi.util.removeCovers
 import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
+import eu.kanade.tachiyomi.util.updateCoverLastModified
 import java.util.Date
 import rx.Observable
 import rx.Subscription
@@ -217,6 +221,48 @@ class MangaPresenter(
         moveMangaToCategories(manga, listOfNotNull(category))
     }
 
+    /**
+     * Update cover with local file.
+     *
+     * @param manga the manga edited.
+     * @param context Context.
+     * @param data uri of the cover resource.
+     */
+    fun editCover(manga: Manga, context: Context, data: Uri) {
+        Observable
+            .fromCallable {
+                context.contentResolver.openInputStream(data)?.use {
+                    if (manga.isLocal()) {
+                        LocalSource.updateCover(context, manga, it)
+                        manga.updateCoverLastModified(db)
+                    } else if (manga.favorite) {
+                        coverCache.setCustomCoverToCache(manga, it)
+                        manga.updateCoverLastModified(db)
+                    }
+                }
+            }
+            .subscribeOn(Schedulers.io())
+            .observeOn(AndroidSchedulers.mainThread())
+            .subscribeFirst(
+                { view, _ -> view.onSetCoverSuccess() },
+                { view, e -> view.onSetCoverError(e) }
+            )
+    }
+
+    fun deleteCustomCover(manga: Manga) {
+        Observable
+            .fromCallable {
+                coverCache.deleteCustomCover(manga)
+                manga.updateCoverLastModified(db)
+            }
+            .subscribeOn(Schedulers.io())
+            .observeOn(AndroidSchedulers.mainThread())
+            .subscribeFirst(
+                { view, _ -> view.onSetCoverSuccess() },
+                { view, e -> view.onSetCoverError(e) }
+            )
+    }
+
     // Manga info - end
 
     // Chapters list - start

+ 6 - 3
app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt

@@ -12,6 +12,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.Manga
 import eu.kanade.tachiyomi.data.glide.GlideApp
+import eu.kanade.tachiyomi.data.glide.MangaThumbnail
 import eu.kanade.tachiyomi.data.glide.toMangaThumbnail
 import eu.kanade.tachiyomi.data.track.TrackManager
 import eu.kanade.tachiyomi.databinding.MangaInfoHeaderBinding
@@ -49,6 +50,7 @@ class MangaInfoHeaderAdapter(
     private lateinit var binding: MangaInfoHeaderBinding
 
     private var initialLoad: Boolean = true
+    private var currentMangaThumbnail: MangaThumbnail? = null
 
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HeaderViewHolder {
         binding = MangaInfoHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false)
@@ -237,9 +239,10 @@ class MangaInfoHeaderAdapter(
             // Set the favorite drawable to the correct one.
             setFavoriteButtonState(manga.favorite)
 
-            // Set cover if it wasn't already.
-            if (binding.mangaCover.drawable == null) {
-                val mangaThumbnail = manga.toMangaThumbnail()
+            // Set cover if changed.
+            val mangaThumbnail = manga.toMangaThumbnail()
+            if (mangaThumbnail != currentMangaThumbnail) {
+                currentMangaThumbnail = mangaThumbnail
                 listOf(binding.mangaCover, binding.backdrop)
                     .forEach {
                         GlideApp.with(view.context)

+ 5 - 0
app/src/main/res/menu/chapters.xml

@@ -97,6 +97,11 @@
         </menu>
     </item>
 
+    <item
+        android:id="@+id/action_edit_cover"
+        android:title="@string/action_edit_cover"
+        app:showAsAction="never" />
+
     <item
         android:id="@+id/action_migrate"
         android:title="@string/action_migrate"

+ 0 - 7
app/src/main/res/menu/library_selection.xml

@@ -2,13 +2,6 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
-    <item
-        android:id="@+id/action_edit_cover"
-        android:icon="@drawable/ic_edit_24dp"
-        android:title="@string/action_edit_cover"
-        app:iconTint="?attr/colorOnPrimary"
-        app:showAsAction="always" />
-
     <item
         android:id="@+id/action_move_to_category"
         android:icon="@drawable/ic_label_24dp"