mirror of
https://github.com/mihonapp/mihon.git
synced 2025-06-27 11:37:51 +02:00
Add advanced option to always update manga title from source (#1182)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
This commit is contained in:
@ -20,6 +20,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
|
|||||||
- Use Github markdown flavour for Github releases & fix bullet list alignment ([@Secozzi](https://github.com/Secozzi)) ([#2024](https://github.com/mihonapp/mihon/pull/2024))
|
- Use Github markdown flavour for Github releases & fix bullet list alignment ([@Secozzi](https://github.com/Secozzi)) ([#2024](https://github.com/mihonapp/mihon/pull/2024))
|
||||||
- Add Nord Theme ([@Riztard](https://github.com/Riztard)) ([#1951](https://github.com/mihonapp/mihon/pull/1951))
|
- Add Nord Theme ([@Riztard](https://github.com/Riztard)) ([#1951](https://github.com/mihonapp/mihon/pull/1951))
|
||||||
- Option to keep read manga when clearing database ([@AwkwardPeak7](https://github.com/AwkwardPeak7)) ([#1979](https://github.com/mihonapp/mihon/pull/1979))
|
- Option to keep read manga when clearing database ([@AwkwardPeak7](https://github.com/AwkwardPeak7)) ([#1979](https://github.com/mihonapp/mihon/pull/1979))
|
||||||
|
- Add advanced option to always update manga title from source ([@FlaminSarge](https://github.com/FlaminSarge)) ([#1182](https://github.com/mihonapp/mihon/pull/1182))
|
||||||
|
|
||||||
### Improved
|
### Improved
|
||||||
- Significantly improve browsing speed (near instantaneous) ([@AntsyLich](https://github.com/AntsyLich)) ([#1946](https://github.com/mihonapp/mihon/pull/1946))
|
- Significantly improve browsing speed (near instantaneous) ([@AntsyLich](https://github.com/AntsyLich)) ([#1946](https://github.com/mihonapp/mihon/pull/1946))
|
||||||
|
@ -2,7 +2,9 @@ package eu.kanade.domain.manga.interactor
|
|||||||
|
|
||||||
import eu.kanade.domain.manga.model.hasCustomCover
|
import eu.kanade.domain.manga.model.hasCustomCover
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.domain.manga.interactor.FetchInterval
|
import tachiyomi.domain.manga.interactor.FetchInterval
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.manga.model.MangaUpdate
|
import tachiyomi.domain.manga.model.MangaUpdate
|
||||||
@ -31,6 +33,8 @@ class UpdateManga(
|
|||||||
remoteManga: SManga,
|
remoteManga: SManga,
|
||||||
manualFetch: Boolean,
|
manualFetch: Boolean,
|
||||||
coverCache: CoverCache = Injekt.get(),
|
coverCache: CoverCache = Injekt.get(),
|
||||||
|
libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||||
|
downloadManager: DownloadManager = Injekt.get(),
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val remoteTitle = try {
|
val remoteTitle = try {
|
||||||
remoteManga.title
|
remoteManga.title
|
||||||
@ -38,8 +42,13 @@ class UpdateManga(
|
|||||||
""
|
""
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the manga isn't a favorite, set its title from source and update in db
|
// if the manga isn't a favorite (or 'update titles' preference is enabled), set its title from source and update in db
|
||||||
val title = if (remoteTitle.isEmpty() || localManga.favorite) null else remoteTitle
|
val title =
|
||||||
|
if (remoteTitle.isNotEmpty() && (!localManga.favorite || libraryPreferences.updateMangaTitles().get())) {
|
||||||
|
remoteTitle
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
val coverLastModified =
|
val coverLastModified =
|
||||||
when {
|
when {
|
||||||
@ -59,7 +68,7 @@ class UpdateManga(
|
|||||||
|
|
||||||
val thumbnailUrl = remoteManga.thumbnail_url?.takeIf { it.isNotEmpty() }
|
val thumbnailUrl = remoteManga.thumbnail_url?.takeIf { it.isNotEmpty() }
|
||||||
|
|
||||||
return mangaRepository.update(
|
val success = mangaRepository.update(
|
||||||
MangaUpdate(
|
MangaUpdate(
|
||||||
id = localManga.id,
|
id = localManga.id,
|
||||||
title = title,
|
title = title,
|
||||||
@ -74,6 +83,10 @@ class UpdateManga(
|
|||||||
initialized = true,
|
initialized = true,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
if (success && title != null) {
|
||||||
|
downloadManager.renameManga(localManga, title)
|
||||||
|
}
|
||||||
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun awaitUpdateFetchInterval(
|
suspend fun awaitUpdateFetchInterval(
|
||||||
|
@ -63,6 +63,7 @@ import tachiyomi.core.common.util.lang.launchNonCancellable
|
|||||||
import tachiyomi.core.common.util.lang.withUIContext
|
import tachiyomi.core.common.util.lang.withUIContext
|
||||||
import tachiyomi.core.common.util.system.ImageUtil
|
import tachiyomi.core.common.util.system.ImageUtil
|
||||||
import tachiyomi.core.common.util.system.logcat
|
import tachiyomi.core.common.util.system.logcat
|
||||||
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.domain.manga.interactor.ResetViewerFlags
|
import tachiyomi.domain.manga.interactor.ResetViewerFlags
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
@ -85,6 +86,7 @@ object SettingsAdvancedScreen : SearchableSettings {
|
|||||||
|
|
||||||
val basePreferences = remember { Injekt.get<BasePreferences>() }
|
val basePreferences = remember { Injekt.get<BasePreferences>() }
|
||||||
val networkPreferences = remember { Injekt.get<NetworkPreferences>() }
|
val networkPreferences = remember { Injekt.get<NetworkPreferences>() }
|
||||||
|
val libraryPreferences = remember { Injekt.get<LibraryPreferences>() }
|
||||||
|
|
||||||
return listOf(
|
return listOf(
|
||||||
Preference.PreferenceItem.TextPreference(
|
Preference.PreferenceItem.TextPreference(
|
||||||
@ -125,7 +127,7 @@ object SettingsAdvancedScreen : SearchableSettings {
|
|||||||
getBackgroundActivityGroup(),
|
getBackgroundActivityGroup(),
|
||||||
getDataGroup(),
|
getDataGroup(),
|
||||||
getNetworkGroup(networkPreferences = networkPreferences),
|
getNetworkGroup(networkPreferences = networkPreferences),
|
||||||
getLibraryGroup(),
|
getLibraryGroup(libraryPreferences = libraryPreferences),
|
||||||
getReaderGroup(basePreferences = basePreferences),
|
getReaderGroup(basePreferences = basePreferences),
|
||||||
getExtensionsGroup(basePreferences = basePreferences),
|
getExtensionsGroup(basePreferences = basePreferences),
|
||||||
)
|
)
|
||||||
@ -286,7 +288,9 @@ object SettingsAdvancedScreen : SearchableSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun getLibraryGroup(): Preference.PreferenceGroup {
|
private fun getLibraryGroup(
|
||||||
|
libraryPreferences: LibraryPreferences,
|
||||||
|
): Preference.PreferenceGroup {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
@ -314,6 +318,11 @@ object SettingsAdvancedScreen : SearchableSettings {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
Preference.PreferenceItem.SwitchPreference(
|
||||||
|
preference = libraryPreferences.updateMangaTitles(),
|
||||||
|
title = stringResource(MR.strings.pref_update_library_manga_titles),
|
||||||
|
subtitle = stringResource(MR.strings.pref_update_library_manga_titles_summary),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -282,6 +282,41 @@ class DownloadCache(
|
|||||||
notifyChanges()
|
notifyChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renames a manga in this cache.
|
||||||
|
*
|
||||||
|
* @param manga the manga being renamed.
|
||||||
|
* @param mangaUniFile the manga's new directory.
|
||||||
|
* @param newTitle the manga's new title.
|
||||||
|
*/
|
||||||
|
suspend fun renameManga(manga: Manga, mangaUniFile: UniFile, newTitle: String) {
|
||||||
|
rootDownloadsDirMutex.withLock {
|
||||||
|
val sourceDir = rootDownloadsDir.sourceDirs[manga.source] ?: return
|
||||||
|
val oldMangaDirName = provider.getMangaDirName(manga.title)
|
||||||
|
var oldChapterDirs: MutableSet<String>? = null
|
||||||
|
// Save the old name's cached chapter dirs
|
||||||
|
if (sourceDir.mangaDirs.containsKey(oldMangaDirName)) {
|
||||||
|
oldChapterDirs = sourceDir.mangaDirs[oldMangaDirName]?.chapterDirs
|
||||||
|
sourceDir.mangaDirs -= oldMangaDirName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve/create the cached manga directory for new name
|
||||||
|
val newMangaDirName = provider.getMangaDirName(newTitle)
|
||||||
|
var mangaDir = sourceDir.mangaDirs[newMangaDirName]
|
||||||
|
if (mangaDir == null) {
|
||||||
|
mangaDir = MangaDirectory(mangaUniFile)
|
||||||
|
sourceDir.mangaDirs += newMangaDirName to mangaDir
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the old chapters to new name's cache
|
||||||
|
if (!oldChapterDirs.isNullOrEmpty()) {
|
||||||
|
mangaDir.chapterDirs += oldChapterDirs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyChanges()
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun removeSource(source: Source) {
|
suspend fun removeSource(source: Source) {
|
||||||
rootDownloadsDirMutex.withLock {
|
rootDownloadsDirMutex.withLock {
|
||||||
rootDownloadsDir.sourceDirs -= source.id
|
rootDownloadsDir.sourceDirs -= source.id
|
||||||
|
@ -327,6 +327,38 @@ class DownloadManager(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renames manga download folder
|
||||||
|
*
|
||||||
|
* @param manga the manga
|
||||||
|
* @param newTitle the new manga title.
|
||||||
|
*/
|
||||||
|
suspend fun renameManga(manga: Manga, newTitle: String) {
|
||||||
|
val source = sourceManager.getOrStub(manga.source)
|
||||||
|
val oldFolder = provider.findMangaDir(manga.title, source) ?: return
|
||||||
|
val newName = provider.getMangaDirName(newTitle)
|
||||||
|
|
||||||
|
if (oldFolder.name == newName) return
|
||||||
|
|
||||||
|
// just to be safe, don't allow downloads for this manga while renaming it
|
||||||
|
downloader.removeFromQueue(manga)
|
||||||
|
|
||||||
|
val capitalizationChanged = oldFolder.name.equals(newName, ignoreCase = true)
|
||||||
|
if (capitalizationChanged) {
|
||||||
|
val tempName = newName + Downloader.TMP_DIR_SUFFIX
|
||||||
|
if (!oldFolder.renameTo(tempName)) {
|
||||||
|
logcat(LogPriority.ERROR) { "Failed to rename manga download folder: ${oldFolder.name}" }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldFolder.renameTo(newName)) {
|
||||||
|
cache.renameManga(manga, oldFolder, newTitle)
|
||||||
|
} else {
|
||||||
|
logcat(LogPriority.ERROR) { "Failed to rename manga download folder: ${oldFolder.name}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renames an already downloaded chapter
|
* Renames an already downloaded chapter
|
||||||
*
|
*
|
||||||
|
@ -189,6 +189,8 @@ class LibraryPreferences(
|
|||||||
ChapterSwipeAction.ToggleRead,
|
ChapterSwipeAction.ToggleRead,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun updateMangaTitles() = preferenceStore.getBoolean("pref_update_library_manga_titles", false)
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
enum class ChapterSwipeAction {
|
enum class ChapterSwipeAction {
|
||||||
|
@ -626,6 +626,8 @@
|
|||||||
<string name="pref_verbose_logging">Verbose logging</string>
|
<string name="pref_verbose_logging">Verbose logging</string>
|
||||||
<string name="pref_verbose_logging_summary">Print verbose logs to system log (reduces app performance)</string>
|
<string name="pref_verbose_logging_summary">Print verbose logs to system log (reduces app performance)</string>
|
||||||
<string name="pref_debug_info">Debug info</string>
|
<string name="pref_debug_info">Debug info</string>
|
||||||
|
<string name="pref_update_library_manga_titles">Update library manga titles to match source</string>
|
||||||
|
<string name="pref_update_library_manga_titles_summary">Warning: if a manga is renamed, it will be removed from the download queue (if present).</string>
|
||||||
|
|
||||||
<!-- About section -->
|
<!-- About section -->
|
||||||
<string name="website">Website</string>
|
<string name="website">Website</string>
|
||||||
|
Reference in New Issue
Block a user