mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-19 22:39:18 +01:00
Move edit cover to manga info
This commit is contained in:
parent
1f67695713
commit
9f7fda0bc5
@ -1,7 +1,5 @@
|
|||||||
package eu.kanade.tachiyomi.ui.library
|
package eu.kanade.tachiyomi.ui.library
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
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.MainActivity
|
||||||
import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
|
import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
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.getResourceColor
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.gone
|
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.appcompat.queryTextChanges
|
||||||
import reactivecircus.flowbinding.viewpager.pageSelections
|
import reactivecircus.flowbinding.viewpager.pageSelections
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import timber.log.Timber
|
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -64,7 +60,6 @@ class LibraryController(
|
|||||||
RootController,
|
RootController,
|
||||||
TabbedController,
|
TabbedController,
|
||||||
ActionMode.Callback,
|
ActionMode.Callback,
|
||||||
ChangeMangaCoverDialog.Listener,
|
|
||||||
ChangeMangaCategoriesDialog.Listener,
|
ChangeMangaCategoriesDialog.Listener,
|
||||||
DeleteLibraryMangasDialog.Listener {
|
DeleteLibraryMangasDialog.Listener {
|
||||||
|
|
||||||
@ -88,8 +83,6 @@ class LibraryController(
|
|||||||
*/
|
*/
|
||||||
val selectedMangas = mutableSetOf<Manga>()
|
val selectedMangas = mutableSetOf<Manga>()
|
||||||
|
|
||||||
private var selectedCoverManga: Manga? = null
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Relay to notify the UI of selection updates.
|
* Relay to notify the UI of selection updates.
|
||||||
*/
|
*/
|
||||||
@ -468,7 +461,6 @@ class LibraryController(
|
|||||||
} else {
|
} else {
|
||||||
mode.title = count.toString()
|
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 }
|
binding.actionToolbar.findItem(R.id.action_download_unread)?.isVisible = selectedMangas.any { it.source != LocalSource.ID }
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -480,7 +472,6 @@ class LibraryController(
|
|||||||
|
|
||||||
private fun onActionItemClicked(item: MenuItem): Boolean {
|
private fun onActionItemClicked(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_edit_cover -> handleChangeCover()
|
|
||||||
R.id.action_move_to_category -> showChangeMangaCategoriesDialog()
|
R.id.action_move_to_category -> showChangeMangaCategoriesDialog()
|
||||||
R.id.action_download_unread -> downloadUnreadChapters()
|
R.id.action_download_unread -> downloadUnreadChapters()
|
||||||
R.id.action_delete -> showDeleteMangaDialog()
|
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.
|
* Move the selected manga to a list of categories.
|
||||||
*/
|
*/
|
||||||
@ -586,31 +560,6 @@ class LibraryController(
|
|||||||
DeleteLibraryMangasDialog(this, selectedMangas.toList()).showDialog(router)
|
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>) {
|
override fun updateCategoriesForMangas(mangas: List<Manga>, categories: List<Category>) {
|
||||||
presenter.moveMangasToCategories(categories, mangas)
|
presenter.moveMangasToCategories(categories, mangas)
|
||||||
destroyActionModeIfNeeded()
|
destroyActionModeIfNeeded()
|
||||||
@ -632,32 +581,4 @@ class LibraryController(
|
|||||||
selectInverseRelay.call(it)
|
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package eu.kanade.tachiyomi.ui.library
|
package eu.kanade.tachiyomi.ui.library
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.jakewharton.rxrelay.BehaviorRelay
|
import com.jakewharton.rxrelay.BehaviorRelay
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
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.database.models.MangaCategory
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
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.isNullOrUnsubscribed
|
||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.removeCovers
|
import eu.kanade.tachiyomi.util.removeCovers
|
||||||
import eu.kanade.tachiyomi.util.updateCoverLastModified
|
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import java.util.Comparator
|
import java.util.Comparator
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
@ -374,46 +370,4 @@ class LibraryPresenter(
|
|||||||
|
|
||||||
db.setMangaCategories(mc, mangas)
|
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) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import com.google.android.material.snackbar.Snackbar
|
|||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||||
import eu.kanade.tachiyomi.R
|
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.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
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.browse.BrowseSourceController
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
||||||
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
|
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.library.LibraryController
|
||||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||||
import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
|
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.history.HistoryController
|
||||||
import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
|
import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
|
||||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
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.getResourceColor
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.getCoordinates
|
import eu.kanade.tachiyomi.util.view.getCoordinates
|
||||||
@ -81,6 +84,7 @@ class MangaController :
|
|||||||
ActionMode.Callback,
|
ActionMode.Callback,
|
||||||
FlexibleAdapter.OnItemClickListener,
|
FlexibleAdapter.OnItemClickListener,
|
||||||
FlexibleAdapter.OnItemLongClickListener,
|
FlexibleAdapter.OnItemLongClickListener,
|
||||||
|
ChangeMangaCoverDialog.Listener,
|
||||||
ChangeMangaCategoriesDialog.Listener,
|
ChangeMangaCategoriesDialog.Listener,
|
||||||
DownloadCustomChaptersDialog.Listener,
|
DownloadCustomChaptersDialog.Listener,
|
||||||
DeleteChaptersDialog.Listener {
|
DeleteChaptersDialog.Listener {
|
||||||
@ -113,6 +117,7 @@ class MangaController :
|
|||||||
private val fromSource = args.getBoolean(FROM_SOURCE_EXTRA, false)
|
private val fromSource = args.getBoolean(FROM_SOURCE_EXTRA, false)
|
||||||
|
|
||||||
private val preferences: PreferencesHelper by injectLazy()
|
private val preferences: PreferencesHelper by injectLazy()
|
||||||
|
private val coverCache: CoverCache by injectLazy()
|
||||||
|
|
||||||
private var mangaInfoAdapter: MangaInfoHeaderAdapter? = null
|
private var mangaInfoAdapter: MangaInfoHeaderAdapter? = null
|
||||||
private var chaptersHeaderAdapter: MangaChaptersHeaderAdapter? = null
|
private var chaptersHeaderAdapter: MangaChaptersHeaderAdapter? = null
|
||||||
@ -310,7 +315,8 @@ class MangaController :
|
|||||||
// Hide download options for local manga
|
// Hide download options for local manga
|
||||||
menu.findItem(R.id.download_group).isVisible = !isLocalSource
|
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
|
menu.findItem(R.id.action_migrate).isVisible = presenter.manga.favorite
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,6 +377,7 @@ class MangaController :
|
|||||||
activity?.invalidateOptionsMenu()
|
activity?.invalidateOptionsMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.action_edit_cover -> handleChangeCover()
|
||||||
R.id.action_migrate -> migrateManga()
|
R.id.action_migrate -> migrateManga()
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item)
|
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.
|
* Initiates source migration for the specific manga.
|
||||||
*/
|
*/
|
||||||
private fun migrateManga() {
|
private fun migrateManga() {
|
||||||
val controller =
|
val controller = SearchController(presenter.manga)
|
||||||
SearchController(
|
|
||||||
presenter.manga
|
|
||||||
)
|
|
||||||
controller.targetController = this
|
controller.targetController = this
|
||||||
router.pushController(controller.withFadeTransaction())
|
router.pushController(controller.withFadeTransaction())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Manga info - end
|
||||||
|
|
||||||
|
// Chapters list - start
|
||||||
|
|
||||||
fun onNextChapters(chapters: List<ChapterItem>) {
|
fun onNextChapters(chapters: List<ChapterItem>) {
|
||||||
// If the list is empty and it hasn't requested previously, fetch chapters from source
|
// 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
|
// We use presenter chapters instead because they are always unfiltered
|
||||||
@ -943,5 +1006,10 @@ class MangaController :
|
|||||||
companion object {
|
companion object {
|
||||||
const val FROM_SOURCE_EXTRA = "from_source"
|
const val FROM_SOURCE_EXTRA = "from_source"
|
||||||
const val MANGA_EXTRA = "manga"
|
const val MANGA_EXTRA = "manga"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key to change the cover of a manga in [onActivityResult].
|
||||||
|
*/
|
||||||
|
const val REQUEST_IMAGE_OPEN = 101
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.ui.manga
|
package eu.kanade.tachiyomi.ui.manga
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.jakewharton.rxrelay.PublishRelay
|
import com.jakewharton.rxrelay.PublishRelay
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
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.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
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.prepUpdateCover
|
||||||
import eu.kanade.tachiyomi.util.removeCovers
|
import eu.kanade.tachiyomi.util.removeCovers
|
||||||
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
|
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
|
||||||
|
import eu.kanade.tachiyomi.util.updateCoverLastModified
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
@ -217,6 +221,48 @@ class MangaPresenter(
|
|||||||
moveMangaToCategories(manga, listOfNotNull(category))
|
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
|
// Manga info - end
|
||||||
|
|
||||||
// Chapters list - start
|
// Chapters list - start
|
||||||
|
@ -12,6 +12,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
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.glide.toMangaThumbnail
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.databinding.MangaInfoHeaderBinding
|
import eu.kanade.tachiyomi.databinding.MangaInfoHeaderBinding
|
||||||
@ -49,6 +50,7 @@ class MangaInfoHeaderAdapter(
|
|||||||
private lateinit var binding: MangaInfoHeaderBinding
|
private lateinit var binding: MangaInfoHeaderBinding
|
||||||
|
|
||||||
private var initialLoad: Boolean = true
|
private var initialLoad: Boolean = true
|
||||||
|
private var currentMangaThumbnail: MangaThumbnail? = null
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HeaderViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HeaderViewHolder {
|
||||||
binding = MangaInfoHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
binding = MangaInfoHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
@ -237,9 +239,10 @@ class MangaInfoHeaderAdapter(
|
|||||||
// Set the favorite drawable to the correct one.
|
// Set the favorite drawable to the correct one.
|
||||||
setFavoriteButtonState(manga.favorite)
|
setFavoriteButtonState(manga.favorite)
|
||||||
|
|
||||||
// Set cover if it wasn't already.
|
// Set cover if changed.
|
||||||
if (binding.mangaCover.drawable == null) {
|
val mangaThumbnail = manga.toMangaThumbnail()
|
||||||
val mangaThumbnail = manga.toMangaThumbnail()
|
if (mangaThumbnail != currentMangaThumbnail) {
|
||||||
|
currentMangaThumbnail = mangaThumbnail
|
||||||
listOf(binding.mangaCover, binding.backdrop)
|
listOf(binding.mangaCover, binding.backdrop)
|
||||||
.forEach {
|
.forEach {
|
||||||
GlideApp.with(view.context)
|
GlideApp.with(view.context)
|
||||||
|
@ -97,6 +97,11 @@
|
|||||||
</menu>
|
</menu>
|
||||||
</item>
|
</item>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_edit_cover"
|
||||||
|
android:title="@string/action_edit_cover"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_migrate"
|
android:id="@+id/action_migrate"
|
||||||
android:title="@string/action_migrate"
|
android:title="@string/action_migrate"
|
||||||
|
@ -2,13 +2,6 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
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
|
<item
|
||||||
android:id="@+id/action_move_to_category"
|
android:id="@+id/action_move_to_category"
|
||||||
android:icon="@drawable/ic_label_24dp"
|
android:icon="@drawable/ic_label_24dp"
|
||||||
|
Loading…
Reference in New Issue
Block a user