Compare commits

...

24 Commits

Author SHA1 Message Date
f3e1fb7664
update gitignore 2025-05-30 17:15:05 +01:00
Jobobby04
cc934607c8 SpotlessApply 2025-05-24 21:07:29 -04:00
Weblate (bot)
5074e68b9c
Translations update from Hosted Weblate (#1442)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/my/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/uk/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hant/
Translation: Mihon/TachiyomiSY
Translation: Mihon/TachiyomiSY Plurals

Co-authored-by: Alex Maryson Jr <akamar87@gmail.com>
Co-authored-by: B4LiN7 <87660017+B4LiN7@users.noreply.github.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: FateXBlood <fatexblood@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Hualiang <642615676@qq.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Kosťantin Horovij <lg096066587039@gmail.com>
Co-authored-by: Lapis (Bas77) <sebastianramli77@gmail.com>
Co-authored-by: LordTenebrous <danielmorenoperez836@gmail.com>
Co-authored-by: Mohamed kh <mohamedkhamekhami@gmail.com>
Co-authored-by: Sky children of the Light <tu25261@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: akir45 <akkn0708@gmail.com>
Co-authored-by: edgole <test.backache009@aleeas.com>
Co-authored-by: fl0k1 <michele.carnova@gmail.com>
Co-authored-by: naikhon <naikhon5@gmail.com>
Co-authored-by: qaugji <asteeky9@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: Георгій Обушенков <heorhii.obushenkov@gmail.com>
Co-authored-by: ابومسلم <linuxmint1978@gmail.com>
2025-05-24 20:47:35 -04:00
多能豆
ade41f113d
Fix E-Hentai Jump/Seek match for detailed date (#1450) 2025-05-24 20:44:55 -04:00
Jobobby04
95dc82594f More guards against edited data 2025-05-24 20:44:27 -04:00
NGB-Was-Taken
80e585fa91
Change log file extension to .txt (#1449) 2025-05-24 20:19:17 -04:00
Jobobby04
9f110f9db8 Bump version so migation actually runs 2025-05-24 20:18:14 -04:00
NGB-Was-Taken
71470b9e02
Remove the unused mark duplicate as read preference. (#1448)
* Remove the unused mark duplicate as read preference.

* Migrate the old preference to new preference
2025-05-24 20:16:44 -04:00
renovate[bot]
4fd24accac
Update dependency net.zetetic:sqlcipher-android to v4.9.0 (#1447)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-24 20:15:17 -04:00
NGB-Was-Taken
31312fecac
Fixes screen staying on in library tab. (#1451) 2025-05-24 20:13:43 -04:00
Mend Renovate
b80d057922 Update dependency androidx.compose:compose-bom to v2025.05.01 (#2133)
(cherry picked from commit 92b376d9af93da988b695c36c4775d5e6947c048)
2025-05-24 20:12:57 -04:00
Mend Renovate
f01d8bc835 Update dependency gradle to v8.14.1 (#2138)
(cherry picked from commit 1a2f09a622017dc5b201eadc6acc667487cf3d4d)
2025-05-24 20:12:48 -04:00
Jobobby04
ddffe71a22 SpotlessApply 2025-05-24 20:12:38 -04:00
AntsyLich
649a19ec57 Fix content cut off in home screen
Closes #2141

(cherry picked from commit 209e982fe4f1da5d1d49cfbfdd178625ee3c70f4)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/home/HomeScreen.kt
2025-05-24 20:10:18 -04:00
Mend Renovate
e82fd99a09 Update plugin org.gradle.toolchains.foojay-resolver-convention to v1 (#2130)
(cherry picked from commit 0109102901f942502807e2a7a9f1a58f951c763f)
2025-05-24 20:09:57 -04:00
Mend Renovate
67a9b8e2a0 Update dependency com.pinterest.ktlint:ktlint-cli to v1.6.0 (#2129)
(cherry picked from commit 4117a5167470ae36b4172721b4e4d40373f2a3c6)
2025-05-24 20:09:51 -04:00
Mend Renovate
2000f947c3 Update xml.serialization.version to v0.91.1 (#2112)
(cherry picked from commit 4090a61d08964a8e82f943ac4eb81a52c110005f)
2025-05-24 20:09:45 -04:00
Jobobby04
f992ada0a8 SpotlessApply 2025-05-16 21:16:09 -04:00
Jobobby04
f876cdb037 Use MediaServer in Json for NHentai
Co-authored-by: 4521 <18432684+az4521@users.noreply.github.com>
2025-05-16 20:34:03 -04:00
Jobobby04
f919d42370 Hello Discord 2025-05-16 12:02:37 -04:00
Mend Renovate
ab5ff00c39 Update kotlin monorepo to v2.1.21 (#2102)
(cherry picked from commit 625c85cbd68086d605553b2d5ab9cc9cc9460688)
2025-05-15 13:50:17 -04:00
Mend Renovate
422738af56 Update dependency org.jetbrains.kotlinx:kotlinx-collections-immutable to v0.4.0 (#2104)
(cherry picked from commit 737ceeea576074cffcd2e96933aceffdbcc0a03a)
2025-05-15 13:50:08 -04:00
Mend Renovate
81751fc9ce Update dependency io.coil-kt.coil3:coil-bom to v3.2.0 (#2101)
(cherry picked from commit 7933c9eeb7b28ecc2ae31fa337654a80f2371b85)
2025-05-15 13:49:58 -04:00
Jobobby04
9b6c5effc9 Minor refactors 2025-05-15 13:38:03 -04:00
82 changed files with 599 additions and 499 deletions

5
.gitignore vendored
View File

@ -18,4 +18,7 @@ local.properties
# SY ignores # SY ignores
google-services.json google-services.json
/app/src/main/assets/client_secrets.json /app/src/main/assets/client_secrets.json
*.apk *.apk
# Custom ignores
/keys

View File

@ -31,7 +31,7 @@ android {
defaultConfig { defaultConfig {
applicationId = "eu.kanade.tachiyomi.sy" applicationId = "eu.kanade.tachiyomi.sy"
versionCode = 74 versionCode = 75
versionName = "1.12.0" versionName = "1.12.0"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")

View File

@ -28,7 +28,6 @@ import tachiyomi.data.source.SavedSearchRepositoryImpl
import tachiyomi.domain.chapter.interactor.DeleteChapters import tachiyomi.domain.chapter.interactor.DeleteChapters
import tachiyomi.domain.chapter.interactor.GetChapterByUrl import tachiyomi.domain.chapter.interactor.GetChapterByUrl
import tachiyomi.domain.chapter.interactor.GetMergedChaptersByMangaId import tachiyomi.domain.chapter.interactor.GetMergedChaptersByMangaId
import tachiyomi.domain.history.interactor.GetHistoryByMangaId
import tachiyomi.domain.manga.interactor.DeleteByMergeId import tachiyomi.domain.manga.interactor.DeleteByMergeId
import tachiyomi.domain.manga.interactor.DeleteFavoriteEntries import tachiyomi.domain.manga.interactor.DeleteFavoriteEntries
import tachiyomi.domain.manga.interactor.DeleteMangaById import tachiyomi.domain.manga.interactor.DeleteMangaById
@ -88,7 +87,6 @@ class SYDomainModule : InjektModule {
addFactory { DeleteChapters(get()) } addFactory { DeleteChapters(get()) }
addFactory { DeleteMangaById(get()) } addFactory { DeleteMangaById(get()) }
addFactory { FilterSerializer() } addFactory { FilterSerializer() }
addFactory { GetHistoryByMangaId(get()) }
addFactory { GetChapterByUrl(get()) } addFactory { GetChapterByUrl(get()) }
addFactory { GetSourceCategories(get()) } addFactory { GetSourceCategories(get()) }
addFactory { CreateSourceCategory(get()) } addFactory { CreateSourceCategory(get()) }

View File

@ -23,7 +23,7 @@ class GetPagePreviews(
return try { return try {
val pagePreviews = try { val pagePreviews = try {
pagePreviewCache.getPageListFromCache(manga, chapterIds, page) pagePreviewCache.getPageListFromCache(manga, chapterIds, page)
} catch (e: Exception) { } catch (_: Exception) {
source.getPagePreviewList(manga.toSManga(), chapters.map { it.toSChapter() }, page).also { source.getPagePreviewList(manga.toSManga(), chapters.map { it.toSChapter() }, page).also {
pagePreviewCache.putPageListToCache(manga, chapterIds, it) pagePreviewCache.putPageListToCache(manga, chapterIds, it)
} }

View File

@ -38,12 +38,14 @@ fun Manga.chaptersFiltered(): Boolean {
fun Manga.toSManga(): SManga = SManga.create().also { fun Manga.toSManga(): SManga = SManga.create().also {
it.url = url it.url = url
it.title = title // SY -->
it.artist = artist it.title = ogTitle
it.author = author it.artist = ogArtist
it.description = description it.author = ogAuthor
it.genre = genre.orEmpty().joinToString() it.description = ogDescription
it.status = status.toInt() it.genre = ogGenre.orEmpty().joinToString()
it.status = ogStatus.toInt()
// SY <--
it.thumbnail_url = thumbnailUrl it.thumbnail_url = thumbnailUrl
it.initialized = initialized it.initialized = initialized
} }

View File

@ -88,5 +88,32 @@ class SourcePreferences(
BANDWIDTH_HERO, BANDWIDTH_HERO,
WSRV_NL, WSRV_NL,
} }
fun migrateFlags() = preferenceStore.getInt("migrate_flags", Int.MAX_VALUE)
fun defaultMangaOrder() = preferenceStore.getString("default_manga_order", "")
fun migrationSources() = preferenceStore.getString("migrate_sources", "")
fun smartMigration() = preferenceStore.getBoolean("smart_migrate", false)
fun useSourceWithMost() = preferenceStore.getBoolean("use_source_with_most", false)
fun skipPreMigration() = preferenceStore.getBoolean(Preference.appStateKey("skip_pre_migration"), false)
fun hideNotFoundMigration() = preferenceStore.getBoolean("hide_not_found_migration", false)
fun showOnlyUpdatesMigration() = preferenceStore.getBoolean("show_only_updates_migration", false)
fun allowLocalSourceHiddenFolders() = preferenceStore.getBoolean("allow_local_source_hidden_folders", false)
fun preferredMangaDexId() = preferenceStore.getString("preferred_mangaDex_id", "0")
fun mangadexSyncToLibraryIndexes() = preferenceStore.getStringSet(
"pref_mangadex_sync_to_library_indexes",
emptySet(),
)
fun recommendationSearchFlags() = preferenceStore.getInt("rec_search_flags", Int.MAX_VALUE)
// SY <-- // SY <--
} }

View File

@ -13,13 +13,13 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import exh.log.xLogE import exh.log.xLogE
import exh.source.ExhPreferences
import exh.uconfig.EHConfigurator import exh.uconfig.EHConfigurator
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import tachiyomi.core.common.util.lang.launchUI import tachiyomi.core.common.util.lang.launchUI
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
@ -29,8 +29,8 @@ import kotlin.time.Duration.Companion.seconds
@Composable @Composable
fun ConfigureExhDialog(run: Boolean, onRunning: () -> Unit) { fun ConfigureExhDialog(run: Boolean, onRunning: () -> Unit) {
val unsortedPreferences = remember { val exhPreferences = remember {
Injekt.get<UnsortedPreferences>() Injekt.get<ExhPreferences>()
} }
var warnDialogOpen by remember { mutableStateOf(false) } var warnDialogOpen by remember { mutableStateOf(false) }
var configureDialogOpen by remember { mutableStateOf(false) } var configureDialogOpen by remember { mutableStateOf(false) }
@ -38,7 +38,7 @@ fun ConfigureExhDialog(run: Boolean, onRunning: () -> Unit) {
LaunchedEffect(run) { LaunchedEffect(run) {
if (run) { if (run) {
if (unsortedPreferences.exhShowSettingsUploadWarning().get()) { if (exhPreferences.exhShowSettingsUploadWarning().get()) {
warnDialogOpen = true warnDialogOpen = true
} else { } else {
configureDialogOpen = true configureDialogOpen = true
@ -57,7 +57,7 @@ fun ConfigureExhDialog(run: Boolean, onRunning: () -> Unit) {
confirmButton = { confirmButton = {
TextButton( TextButton(
onClick = { onClick = {
unsortedPreferences.exhShowSettingsUploadWarning().set(false) exhPreferences.exhShowSettingsUploadWarning().set(false)
configureDialogOpen = true configureDialogOpen = true
warnDialogOpen = false warnDialogOpen = false
}, },

View File

@ -72,6 +72,7 @@ import exh.pref.DelegateSourcePreferences
import exh.source.BlacklistedSources import exh.source.BlacklistedSources
import exh.source.EH_SOURCE_ID import exh.source.EH_SOURCE_ID
import exh.source.EXH_SOURCE_ID import exh.source.EXH_SOURCE_ID
import exh.source.ExhPreferences
import exh.util.toAnnotatedString import exh.util.toAnnotatedString
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
@ -86,7 +87,6 @@ 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.UnsortedPreferences
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.manga.interactor.GetAllManga import tachiyomi.domain.manga.interactor.GetAllManga
@ -701,14 +701,14 @@ object SettingsAdvancedScreen : SearchableSettings {
val context = LocalContext.current val context = LocalContext.current
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
val sourcePreferences = remember { Injekt.get<SourcePreferences>() } val sourcePreferences = remember { Injekt.get<SourcePreferences>() }
val unsortedPreferences = remember { Injekt.get<UnsortedPreferences>() } val exhPreferences = remember { Injekt.get<ExhPreferences>() }
val delegateSourcePreferences = remember { Injekt.get<DelegateSourcePreferences>() } val delegateSourcePreferences = remember { Injekt.get<DelegateSourcePreferences>() }
val securityPreferences = remember { Injekt.get<SecurityPreferences>() } val securityPreferences = remember { Injekt.get<SecurityPreferences>() }
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(SYMR.strings.developer_tools), title = stringResource(SYMR.strings.developer_tools),
preferenceItems = persistentListOf( preferenceItems = persistentListOf(
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
preference = unsortedPreferences.isHentaiEnabled(), preference = exhPreferences.isHentaiEnabled(),
title = stringResource(SYMR.strings.toggle_hentai_features), title = stringResource(SYMR.strings.toggle_hentai_features),
subtitle = stringResource(SYMR.strings.toggle_hentai_features_summary), subtitle = stringResource(SYMR.strings.toggle_hentai_features_summary),
onValueChanged = { onValueChanged = {
@ -733,7 +733,7 @@ object SettingsAdvancedScreen : SearchableSettings {
), ),
), ),
Preference.PreferenceItem.ListPreference( Preference.PreferenceItem.ListPreference(
preference = unsortedPreferences.logLevel(), preference = exhPreferences.logLevel(),
title = stringResource(SYMR.strings.log_level), title = stringResource(SYMR.strings.log_level),
subtitle = stringResource(SYMR.strings.log_level_summary), subtitle = stringResource(SYMR.strings.log_level_summary),
entries = EHLogLevel.entries.mapIndexed { index, ehLogLevel -> entries = EHLogLevel.entries.mapIndexed { index, ehLogLevel ->

View File

@ -20,7 +20,6 @@ import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.authenticate
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import mihon.domain.extensionrepo.interactor.GetExtensionRepoCount import mihon.domain.extensionrepo.interactor.GetExtensionRepoCount
import tachiyomi.core.common.i18n.stringResource import tachiyomi.core.common.i18n.stringResource
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.i18n.pluralStringResource import tachiyomi.presentation.core.i18n.pluralStringResource
@ -49,7 +48,6 @@ object SettingsBrowseScreen : SearchableSettings {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val hideFeedTab by remember { Injekt.get<UiPreferences>().hideFeedTab().asState(scope) } val hideFeedTab by remember { Injekt.get<UiPreferences>().hideFeedTab().asState(scope) }
val uiPreferences = remember { Injekt.get<UiPreferences>() } val uiPreferences = remember { Injekt.get<UiPreferences>() }
val unsortedPreferences = remember { Injekt.get<UnsortedPreferences>() }
// SY <-- // SY <--
return listOf( return listOf(
// SY --> // SY -->
@ -77,7 +75,7 @@ object SettingsBrowseScreen : SearchableSettings {
subtitle = stringResource(SYMR.strings.pref_source_navigation_summery), subtitle = stringResource(SYMR.strings.pref_source_navigation_summery),
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
preference = unsortedPreferences.allowLocalSourceHiddenFolders(), preference = sourcePreferences.allowLocalSourceHiddenFolders(),
title = stringResource(SYMR.strings.pref_local_source_hidden_folders), title = stringResource(SYMR.strings.pref_local_source_hidden_folders),
subtitle = stringResource(SYMR.strings.pref_local_source_hidden_folders_summery), subtitle = stringResource(SYMR.strings.pref_local_source_hidden_folders_summery),
), ),
@ -131,6 +129,24 @@ object SettingsBrowseScreen : SearchableSettings {
Preference.PreferenceItem.InfoPreference(stringResource(MR.strings.parental_controls_info)), Preference.PreferenceItem.InfoPreference(stringResource(MR.strings.parental_controls_info)),
), ),
), ),
getMigrationCategory(sourcePreferences),
)
}
@Composable
fun getMigrationCategory(sourcePreferences: SourcePreferences): Preference.PreferenceGroup {
val skipPreMigration by sourcePreferences.skipPreMigration().collectAsState()
val migrationSources by sourcePreferences.migrationSources().collectAsState()
return Preference.PreferenceGroup(
stringResource(SYMR.strings.migration),
enabled = skipPreMigration || migrationSources.isNotEmpty(),
preferenceItems = persistentListOf(
Preference.PreferenceItem.SwitchPreference(
preference = sourcePreferences.skipPreMigration(),
title = stringResource(SYMR.strings.skip_pre_migration),
subtitle = stringResource(SYMR.strings.pref_skip_pre_migration_summary),
),
),
) )
} }
} }

View File

@ -51,6 +51,7 @@ import exh.eh.EHentaiUpdateWorker
import exh.eh.EHentaiUpdateWorkerConstants import exh.eh.EHentaiUpdateWorkerConstants
import exh.eh.EHentaiUpdaterStats import exh.eh.EHentaiUpdaterStats
import exh.metadata.metadata.EHentaiSearchMetadata import exh.metadata.metadata.EHentaiSearchMetadata
import exh.source.ExhPreferences
import exh.ui.login.EhLoginActivity import exh.ui.login.EhLoginActivity
import exh.util.nullIfBlank import exh.util.nullIfBlank
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@ -63,7 +64,6 @@ import tachiyomi.core.common.util.lang.launchNonCancellable
import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.core.common.util.lang.withUIContext import tachiyomi.core.common.util.lang.withUIContext
import tachiyomi.core.common.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.library.service.LibraryPreferences.Companion.DEVICE_CHARGING import tachiyomi.domain.library.service.LibraryPreferences.Companion.DEVICE_CHARGING
import tachiyomi.domain.library.service.LibraryPreferences.Companion.DEVICE_ONLY_ON_WIFI import tachiyomi.domain.library.service.LibraryPreferences.Companion.DEVICE_ONLY_ON_WIFI
import tachiyomi.domain.manga.interactor.DeleteFavoriteEntries import tachiyomi.domain.manga.interactor.DeleteFavoriteEntries
@ -88,22 +88,22 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
override fun getTitleRes() = SYMR.strings.pref_category_eh override fun getTitleRes() = SYMR.strings.pref_category_eh
override fun isEnabled(): Boolean = Injekt.get<UnsortedPreferences>().isHentaiEnabled().get() override fun isEnabled(): Boolean = Injekt.get<ExhPreferences>().isHentaiEnabled().get()
@Composable @Composable
fun Reconfigure( fun Reconfigure(
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
openWarnConfigureDialogController: () -> Unit, openWarnConfigureDialogController: () -> Unit,
) { ) {
var initialLoadGuard by remember { mutableStateOf(false) } var initialLoadGuard by remember { mutableStateOf(false) }
val useHentaiAtHome by unsortedPreferences.useHentaiAtHome().collectAsState() val useHentaiAtHome by exhPreferences.useHentaiAtHome().collectAsState()
val useJapaneseTitle by unsortedPreferences.useJapaneseTitle().collectAsState() val useJapaneseTitle by exhPreferences.useJapaneseTitle().collectAsState()
val useOriginalImages by unsortedPreferences.exhUseOriginalImages().collectAsState() val useOriginalImages by exhPreferences.exhUseOriginalImages().collectAsState()
val ehTagFilterValue by unsortedPreferences.ehTagFilterValue().collectAsState() val ehTagFilterValue by exhPreferences.ehTagFilterValue().collectAsState()
val ehTagWatchingValue by unsortedPreferences.ehTagWatchingValue().collectAsState() val ehTagWatchingValue by exhPreferences.ehTagWatchingValue().collectAsState()
val settingsLanguages by unsortedPreferences.exhSettingsLanguages().collectAsState() val settingsLanguages by exhPreferences.exhSettingsLanguages().collectAsState()
val enabledCategories by unsortedPreferences.exhEnabledCategories().collectAsState() val enabledCategories by exhPreferences.exhEnabledCategories().collectAsState()
val imageQuality by unsortedPreferences.imageQuality().collectAsState() val imageQuality by exhPreferences.imageQuality().collectAsState()
DisposableEffect( DisposableEffect(
useHentaiAtHome, useHentaiAtHome,
useJapaneseTitle, useJapaneseTitle,
@ -124,15 +124,15 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
val unsortedPreferences: UnsortedPreferences = remember { Injekt.get() } val exhPreferences: ExhPreferences = remember { Injekt.get() }
val getFlatMetadataById: GetFlatMetadataById = remember { Injekt.get() } val getFlatMetadataById: GetFlatMetadataById = remember { Injekt.get() }
val deleteFavoriteEntries: DeleteFavoriteEntries = remember { Injekt.get() } val deleteFavoriteEntries: DeleteFavoriteEntries = remember { Injekt.get() }
val getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata = remember { Injekt.get() } val getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata = remember { Injekt.get() }
val exhentaiEnabled by unsortedPreferences.enableExhentai().collectAsState() val exhentaiEnabled by exhPreferences.enableExhentai().collectAsState()
var runConfigureDialog by remember { mutableStateOf(false) } var runConfigureDialog by remember { mutableStateOf(false) }
val openWarnConfigureDialogController = { runConfigureDialog = true } val openWarnConfigureDialogController = { runConfigureDialog = true }
Reconfigure(unsortedPreferences, openWarnConfigureDialogController) Reconfigure(exhPreferences, openWarnConfigureDialogController)
ConfigureExhDialog(run = runConfigureDialog, onRunning = { runConfigureDialog = false }) ConfigureExhDialog(run = runConfigureDialog, onRunning = { runConfigureDialog = false })
@ -140,36 +140,36 @@ object SettingsEhScreen : SearchableSettings {
Preference.PreferenceGroup( Preference.PreferenceGroup(
stringResource(SYMR.strings.ehentai_prefs_account_settings), stringResource(SYMR.strings.ehentai_prefs_account_settings),
preferenceItems = persistentListOf( preferenceItems = persistentListOf(
getLoginPreference(unsortedPreferences, openWarnConfigureDialogController), getLoginPreference(exhPreferences, openWarnConfigureDialogController),
useHentaiAtHome(exhentaiEnabled, unsortedPreferences), useHentaiAtHome(exhentaiEnabled, exhPreferences),
useJapaneseTitle(exhentaiEnabled, unsortedPreferences), useJapaneseTitle(exhentaiEnabled, exhPreferences),
useOriginalImages(exhentaiEnabled, unsortedPreferences), useOriginalImages(exhentaiEnabled, exhPreferences),
watchedTags(exhentaiEnabled), watchedTags(exhentaiEnabled),
tagFilterThreshold(exhentaiEnabled, unsortedPreferences), tagFilterThreshold(exhentaiEnabled, exhPreferences),
tagWatchingThreshold(exhentaiEnabled, unsortedPreferences), tagWatchingThreshold(exhentaiEnabled, exhPreferences),
settingsLanguages(exhentaiEnabled, unsortedPreferences), settingsLanguages(exhentaiEnabled, exhPreferences),
enabledCategories(exhentaiEnabled, unsortedPreferences), enabledCategories(exhentaiEnabled, exhPreferences),
watchedListDefaultState(exhentaiEnabled, unsortedPreferences), watchedListDefaultState(exhentaiEnabled, exhPreferences),
imageQuality(exhentaiEnabled, unsortedPreferences), imageQuality(exhentaiEnabled, exhPreferences),
enhancedEhentaiView(unsortedPreferences), enhancedEhentaiView(exhPreferences),
), ),
), ),
Preference.PreferenceGroup( Preference.PreferenceGroup(
stringResource(SYMR.strings.favorites_sync), stringResource(SYMR.strings.favorites_sync),
preferenceItems = persistentListOf( preferenceItems = persistentListOf(
readOnlySync(unsortedPreferences), readOnlySync(exhPreferences),
syncFavoriteNotes(), syncFavoriteNotes(),
lenientSync(unsortedPreferences), lenientSync(exhPreferences),
forceSyncReset(deleteFavoriteEntries), forceSyncReset(deleteFavoriteEntries),
), ),
), ),
Preference.PreferenceGroup( Preference.PreferenceGroup(
stringResource(SYMR.strings.gallery_update_checker), stringResource(SYMR.strings.gallery_update_checker),
preferenceItems = persistentListOf( preferenceItems = persistentListOf(
updateCheckerFrequency(unsortedPreferences), updateCheckerFrequency(exhPreferences),
autoUpdateRequirements(unsortedPreferences), autoUpdateRequirements(exhPreferences),
updaterStatistics( updaterStatistics(
unsortedPreferences, exhPreferences,
getExhFavoriteMangaWithMetadata, getExhFavoriteMangaWithMetadata,
getFlatMetadataById, getFlatMetadataById,
), ),
@ -180,7 +180,7 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun getLoginPreference( fun getLoginPreference(
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
openWarnConfigureDialogController: () -> Unit, openWarnConfigureDialogController: () -> Unit,
): Preference.PreferenceItem.SwitchPreference { ): Preference.PreferenceItem.SwitchPreference {
val activityResultContract = val activityResultContract =
@ -191,9 +191,9 @@ object SettingsEhScreen : SearchableSettings {
} }
} }
val context = LocalContext.current val context = LocalContext.current
val value by unsortedPreferences.enableExhentai().collectAsState() val value by exhPreferences.enableExhentai().collectAsState()
return Preference.PreferenceItem.SwitchPreference( return Preference.PreferenceItem.SwitchPreference(
preference = unsortedPreferences.enableExhentai(), preference = exhPreferences.enableExhentai(),
title = stringResource(SYMR.strings.enable_exhentai), title = stringResource(SYMR.strings.enable_exhentai),
subtitle = if (!value) { subtitle = if (!value) {
stringResource(SYMR.strings.requires_login) stringResource(SYMR.strings.requires_login)
@ -202,7 +202,7 @@ object SettingsEhScreen : SearchableSettings {
}, },
onValueChanged = { newVal -> onValueChanged = { newVal ->
if (!newVal) { if (!newVal) {
unsortedPreferences.enableExhentai().set(false) exhPreferences.enableExhentai().set(false)
true true
} else { } else {
activityResultContract.launch(EhLoginActivity.newIntent(context)) activityResultContract.launch(EhLoginActivity.newIntent(context))
@ -215,10 +215,10 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun useHentaiAtHome( fun useHentaiAtHome(
exhentaiEnabled: Boolean, exhentaiEnabled: Boolean,
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
): Preference.PreferenceItem.ListPreference<Int> { ): Preference.PreferenceItem.ListPreference<Int> {
return Preference.PreferenceItem.ListPreference( return Preference.PreferenceItem.ListPreference(
preference = unsortedPreferences.useHentaiAtHome(), preference = exhPreferences.useHentaiAtHome(),
title = stringResource(SYMR.strings.use_hentai_at_home), title = stringResource(SYMR.strings.use_hentai_at_home),
subtitle = stringResource(SYMR.strings.use_hentai_at_home_summary), subtitle = stringResource(SYMR.strings.use_hentai_at_home_summary),
entries = persistentMapOf( entries = persistentMapOf(
@ -232,11 +232,11 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun useJapaneseTitle( fun useJapaneseTitle(
exhentaiEnabled: Boolean, exhentaiEnabled: Boolean,
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
): Preference.PreferenceItem.SwitchPreference { ): Preference.PreferenceItem.SwitchPreference {
val value by unsortedPreferences.useJapaneseTitle().collectAsState() val value by exhPreferences.useJapaneseTitle().collectAsState()
return Preference.PreferenceItem.SwitchPreference( return Preference.PreferenceItem.SwitchPreference(
preference = unsortedPreferences.useJapaneseTitle(), preference = exhPreferences.useJapaneseTitle(),
title = stringResource(SYMR.strings.show_japanese_titles), title = stringResource(SYMR.strings.show_japanese_titles),
subtitle = if (value) { subtitle = if (value) {
stringResource(SYMR.strings.show_japanese_titles_option_1) stringResource(SYMR.strings.show_japanese_titles_option_1)
@ -250,11 +250,11 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun useOriginalImages( fun useOriginalImages(
exhentaiEnabled: Boolean, exhentaiEnabled: Boolean,
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
): Preference.PreferenceItem.SwitchPreference { ): Preference.PreferenceItem.SwitchPreference {
val value by unsortedPreferences.exhUseOriginalImages().collectAsState() val value by exhPreferences.exhUseOriginalImages().collectAsState()
return Preference.PreferenceItem.SwitchPreference( return Preference.PreferenceItem.SwitchPreference(
preference = unsortedPreferences.exhUseOriginalImages(), preference = exhPreferences.exhUseOriginalImages(),
title = stringResource(SYMR.strings.use_original_images), title = stringResource(SYMR.strings.use_original_images),
subtitle = if (value) { subtitle = if (value) {
stringResource(SYMR.strings.use_original_images_on) stringResource(SYMR.strings.use_original_images_on)
@ -351,9 +351,9 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun tagFilterThreshold( fun tagFilterThreshold(
exhentaiEnabled: Boolean, exhentaiEnabled: Boolean,
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
): Preference.PreferenceItem.TextPreference { ): Preference.PreferenceItem.TextPreference {
val value by unsortedPreferences.ehTagFilterValue().collectAsState() val value by exhPreferences.ehTagFilterValue().collectAsState()
var dialogOpen by remember { mutableStateOf(false) } var dialogOpen by remember { mutableStateOf(false) }
if (dialogOpen) { if (dialogOpen) {
TagThresholdDialog( TagThresholdDialog(
@ -364,7 +364,7 @@ object SettingsEhScreen : SearchableSettings {
outsideRangeError = stringResource(SYMR.strings.tag_filtering_threshhold_error), outsideRangeError = stringResource(SYMR.strings.tag_filtering_threshhold_error),
onValueChange = { onValueChange = {
dialogOpen = false dialogOpen = false
unsortedPreferences.ehTagFilterValue().set(it) exhPreferences.ehTagFilterValue().set(it)
}, },
) )
} }
@ -381,9 +381,9 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun tagWatchingThreshold( fun tagWatchingThreshold(
exhentaiEnabled: Boolean, exhentaiEnabled: Boolean,
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
): Preference.PreferenceItem.TextPreference { ): Preference.PreferenceItem.TextPreference {
val value by unsortedPreferences.ehTagWatchingValue().collectAsState() val value by exhPreferences.ehTagWatchingValue().collectAsState()
var dialogOpen by remember { mutableStateOf(false) } var dialogOpen by remember { mutableStateOf(false) }
if (dialogOpen) { if (dialogOpen) {
TagThresholdDialog( TagThresholdDialog(
@ -394,7 +394,7 @@ object SettingsEhScreen : SearchableSettings {
outsideRangeError = stringResource(SYMR.strings.tag_watching_threshhold_error), outsideRangeError = stringResource(SYMR.strings.tag_watching_threshhold_error),
onValueChange = { onValueChange = {
dialogOpen = false dialogOpen = false
unsortedPreferences.ehTagWatchingValue().set(it) exhPreferences.ehTagWatchingValue().set(it)
}, },
) )
} }
@ -604,9 +604,9 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun settingsLanguages( fun settingsLanguages(
exhentaiEnabled: Boolean, exhentaiEnabled: Boolean,
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
): Preference.PreferenceItem.TextPreference { ): Preference.PreferenceItem.TextPreference {
val value by unsortedPreferences.exhSettingsLanguages().collectAsState() val value by exhPreferences.exhSettingsLanguages().collectAsState()
var dialogOpen by remember { mutableStateOf(false) } var dialogOpen by remember { mutableStateOf(false) }
if (dialogOpen) { if (dialogOpen) {
LanguagesDialog( LanguagesDialog(
@ -614,7 +614,7 @@ object SettingsEhScreen : SearchableSettings {
initialValue = value, initialValue = value,
onValueChange = { onValueChange = {
dialogOpen = false dialogOpen = false
unsortedPreferences.exhSettingsLanguages().set(it) exhPreferences.exhSettingsLanguages().set(it)
}, },
) )
} }
@ -770,9 +770,9 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun enabledCategories( fun enabledCategories(
exhentaiEnabled: Boolean, exhentaiEnabled: Boolean,
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
): Preference.PreferenceItem.TextPreference { ): Preference.PreferenceItem.TextPreference {
val value by unsortedPreferences.exhEnabledCategories().collectAsState() val value by exhPreferences.exhEnabledCategories().collectAsState()
var dialogOpen by remember { mutableStateOf(false) } var dialogOpen by remember { mutableStateOf(false) }
if (dialogOpen) { if (dialogOpen) {
FrontPageCategoriesDialog( FrontPageCategoriesDialog(
@ -780,7 +780,7 @@ object SettingsEhScreen : SearchableSettings {
initialValue = value, initialValue = value,
onValueChange = { onValueChange = {
dialogOpen = false dialogOpen = false
unsortedPreferences.exhEnabledCategories().set(it) exhPreferences.exhEnabledCategories().set(it)
}, },
) )
} }
@ -797,10 +797,10 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun watchedListDefaultState( fun watchedListDefaultState(
exhentaiEnabled: Boolean, exhentaiEnabled: Boolean,
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
): Preference.PreferenceItem.SwitchPreference { ): Preference.PreferenceItem.SwitchPreference {
return Preference.PreferenceItem.SwitchPreference( return Preference.PreferenceItem.SwitchPreference(
preference = unsortedPreferences.exhWatchedListDefaultState(), preference = exhPreferences.exhWatchedListDefaultState(),
title = stringResource(SYMR.strings.watched_list_default), title = stringResource(SYMR.strings.watched_list_default),
subtitle = stringResource(SYMR.strings.watched_list_state_summary), subtitle = stringResource(SYMR.strings.watched_list_state_summary),
enabled = exhentaiEnabled, enabled = exhentaiEnabled,
@ -810,10 +810,10 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun imageQuality( fun imageQuality(
exhentaiEnabled: Boolean, exhentaiEnabled: Boolean,
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
): Preference.PreferenceItem.ListPreference<String> { ): Preference.PreferenceItem.ListPreference<String> {
return Preference.PreferenceItem.ListPreference( return Preference.PreferenceItem.ListPreference(
preference = unsortedPreferences.imageQuality(), preference = exhPreferences.imageQuality(),
title = stringResource(SYMR.strings.eh_image_quality_summary), title = stringResource(SYMR.strings.eh_image_quality_summary),
subtitle = stringResource(SYMR.strings.eh_image_quality), subtitle = stringResource(SYMR.strings.eh_image_quality),
entries = persistentMapOf( entries = persistentMapOf(
@ -829,18 +829,18 @@ object SettingsEhScreen : SearchableSettings {
} }
@Composable @Composable
fun enhancedEhentaiView(unsortedPreferences: UnsortedPreferences): Preference.PreferenceItem.SwitchPreference { fun enhancedEhentaiView(exhPreferences: ExhPreferences): Preference.PreferenceItem.SwitchPreference {
return Preference.PreferenceItem.SwitchPreference( return Preference.PreferenceItem.SwitchPreference(
preference = unsortedPreferences.enhancedEHentaiView(), preference = exhPreferences.enhancedEHentaiView(),
title = stringResource(SYMR.strings.pref_enhanced_e_hentai_view), title = stringResource(SYMR.strings.pref_enhanced_e_hentai_view),
subtitle = stringResource(SYMR.strings.pref_enhanced_e_hentai_view_summary), subtitle = stringResource(SYMR.strings.pref_enhanced_e_hentai_view_summary),
) )
} }
@Composable @Composable
fun readOnlySync(unsortedPreferences: UnsortedPreferences): Preference.PreferenceItem.SwitchPreference { fun readOnlySync(exhPreferences: ExhPreferences): Preference.PreferenceItem.SwitchPreference {
return Preference.PreferenceItem.SwitchPreference( return Preference.PreferenceItem.SwitchPreference(
preference = unsortedPreferences.exhReadOnlySync(), preference = exhPreferences.exhReadOnlySync(),
title = stringResource(SYMR.strings.disable_favorites_uploading), title = stringResource(SYMR.strings.disable_favorites_uploading),
subtitle = stringResource(SYMR.strings.disable_favorites_uploading_summary), subtitle = stringResource(SYMR.strings.disable_favorites_uploading_summary),
) )
@ -863,9 +863,9 @@ object SettingsEhScreen : SearchableSettings {
} }
@Composable @Composable
fun lenientSync(unsortedPreferences: UnsortedPreferences): Preference.PreferenceItem.SwitchPreference { fun lenientSync(exhPreferences: ExhPreferences): Preference.PreferenceItem.SwitchPreference {
return Preference.PreferenceItem.SwitchPreference( return Preference.PreferenceItem.SwitchPreference(
preference = unsortedPreferences.exhLenientSync(), preference = exhPreferences.exhLenientSync(),
title = stringResource(SYMR.strings.ignore_sync_errors), title = stringResource(SYMR.strings.ignore_sync_errors),
subtitle = stringResource(SYMR.strings.ignore_sync_errors_summary), subtitle = stringResource(SYMR.strings.ignore_sync_errors_summary),
) )
@ -935,12 +935,12 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun updateCheckerFrequency( fun updateCheckerFrequency(
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
): Preference.PreferenceItem.ListPreference<Int> { ): Preference.PreferenceItem.ListPreference<Int> {
val value by unsortedPreferences.exhAutoUpdateFrequency().collectAsState() val value by exhPreferences.exhAutoUpdateFrequency().collectAsState()
val context = LocalContext.current val context = LocalContext.current
return Preference.PreferenceItem.ListPreference( return Preference.PreferenceItem.ListPreference(
preference = unsortedPreferences.exhAutoUpdateFrequency(), preference = exhPreferences.exhAutoUpdateFrequency(),
title = stringResource(SYMR.strings.time_between_batches), title = stringResource(SYMR.strings.time_between_batches),
subtitle = if (value == 0) { subtitle = if (value == 0) {
stringResource(SYMR.strings.time_between_batches_summary_1, stringResource(MR.strings.app_name)) stringResource(SYMR.strings.time_between_batches_summary_1, stringResource(MR.strings.app_name))
@ -971,12 +971,12 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun autoUpdateRequirements( fun autoUpdateRequirements(
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
): Preference.PreferenceItem.MultiSelectListPreference { ): Preference.PreferenceItem.MultiSelectListPreference {
val value by unsortedPreferences.exhAutoUpdateRequirements().collectAsState() val value by exhPreferences.exhAutoUpdateRequirements().collectAsState()
val context = LocalContext.current val context = LocalContext.current
return Preference.PreferenceItem.MultiSelectListPreference( return Preference.PreferenceItem.MultiSelectListPreference(
preference = unsortedPreferences.exhAutoUpdateRequirements(), preference = exhPreferences.exhAutoUpdateRequirements(),
title = stringResource(SYMR.strings.auto_update_restrictions), title = stringResource(SYMR.strings.auto_update_restrictions),
subtitle = remember(value) { subtitle = remember(value) {
context.stringResource( context.stringResource(
@ -1139,7 +1139,7 @@ object SettingsEhScreen : SearchableSettings {
@Composable @Composable
fun updaterStatistics( fun updaterStatistics(
unsortedPreferences: UnsortedPreferences, exhPreferences: ExhPreferences,
getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata, getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata,
getFlatMetadataById: GetFlatMetadataById, getFlatMetadataById: GetFlatMetadataById,
): Preference.PreferenceItem.TextPreference { ): Preference.PreferenceItem.TextPreference {
@ -1150,7 +1150,7 @@ object SettingsEhScreen : SearchableSettings {
value = withIOContext { value = withIOContext {
try { try {
val stats = val stats =
unsortedPreferences.exhAutoUpdateStats().get().nullIfBlank()?.let { exhPreferences.exhAutoUpdateStats().get().nullIfBlank()?.let {
Json.decodeFromString<EHentaiUpdaterStats>(it) Json.decodeFromString<EHentaiUpdaterStats>(it)
} }

View File

@ -25,7 +25,6 @@ import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableMap import kotlinx.collections.immutable.toImmutableMap
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.category.interactor.GetCategories import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.interactor.ResetCategoryFlags import tachiyomi.domain.category.interactor.ResetCategoryFlags
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
@ -59,9 +58,6 @@ object SettingsLibraryScreen : SearchableSettings {
val getCategories = remember { Injekt.get<GetCategories>() } val getCategories = remember { Injekt.get<GetCategories>() }
val libraryPreferences = remember { Injekt.get<LibraryPreferences>() } val libraryPreferences = remember { Injekt.get<LibraryPreferences>() }
val allCategories by getCategories.subscribe().collectAsState(initial = emptyList()) val allCategories by getCategories.subscribe().collectAsState(initial = emptyList())
// SY -->
val unsortedPreferences = remember { Injekt.get<UnsortedPreferences>() }
// SY <--
return listOf( return listOf(
getCategoriesGroup(LocalNavigator.currentOrThrow, allCategories, libraryPreferences), getCategoriesGroup(LocalNavigator.currentOrThrow, allCategories, libraryPreferences),
@ -69,7 +65,6 @@ object SettingsLibraryScreen : SearchableSettings {
getBehaviorGroup(libraryPreferences), getBehaviorGroup(libraryPreferences),
// SY --> // SY -->
getSortingCategory(LocalNavigator.currentOrThrow, libraryPreferences), getSortingCategory(LocalNavigator.currentOrThrow, libraryPreferences),
getMigrationCategory(unsortedPreferences),
// SY <-- // SY <--
) )
} }
@ -300,22 +295,5 @@ object SettingsLibraryScreen : SearchableSettings {
), ),
) )
} }
@Composable
fun getMigrationCategory(unsortedPreferences: UnsortedPreferences): Preference.PreferenceGroup {
val skipPreMigration by unsortedPreferences.skipPreMigration().collectAsState()
val migrationSources by unsortedPreferences.migrationSources().collectAsState()
return Preference.PreferenceGroup(
stringResource(SYMR.strings.migration),
enabled = skipPreMigration || migrationSources.isNotEmpty(),
preferenceItems = persistentListOf(
Preference.PreferenceItem.SwitchPreference(
preference = unsortedPreferences.skipPreMigration(),
title = stringResource(SYMR.strings.skip_pre_migration),
subtitle = stringResource(SYMR.strings.pref_skip_pre_migration_summary),
),
),
)
}
// SY <-- // SY <--
} }

View File

@ -44,7 +44,6 @@ import logcat.LogPriority
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.core.common.util.lang.withUIContext import tachiyomi.core.common.util.lang.withUIContext
import tachiyomi.core.common.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
@ -65,14 +64,13 @@ object SettingsMangadexScreen : SearchableSettings {
@Composable @Composable
override fun getPreferences(): List<Preference> { override fun getPreferences(): List<Preference> {
val sourcePreferences: SourcePreferences = remember { Injekt.get() } val sourcePreferences: SourcePreferences = remember { Injekt.get() }
val unsortedPreferences: UnsortedPreferences = remember { Injekt.get() }
val trackPreferences: TrackPreferences = remember { Injekt.get() } val trackPreferences: TrackPreferences = remember { Injekt.get() }
val mdex = remember { MdUtil.getEnabledMangaDex(unsortedPreferences, sourcePreferences) } ?: return emptyList() val mdex = remember { MdUtil.getEnabledMangaDex(sourcePreferences) } ?: return emptyList()
return listOf( return listOf(
loginPreference(mdex, trackPreferences), loginPreference(mdex, trackPreferences),
preferredMangaDexId(unsortedPreferences, sourcePreferences), preferredMangaDexId(sourcePreferences),
syncMangaDexIntoThis(unsortedPreferences), syncMangaDexIntoThis(sourcePreferences),
syncLibraryToMangaDex(), syncLibraryToMangaDex(),
) )
} }
@ -174,11 +172,10 @@ object SettingsMangadexScreen : SearchableSettings {
@Composable @Composable
fun preferredMangaDexId( fun preferredMangaDexId(
unsortedPreferences: UnsortedPreferences,
sourcePreferences: SourcePreferences, sourcePreferences: SourcePreferences,
): Preference.PreferenceItem.ListPreference<String> { ): Preference.PreferenceItem.ListPreference<String> {
return Preference.PreferenceItem.ListPreference( return Preference.PreferenceItem.ListPreference(
preference = unsortedPreferences.preferredMangaDexId(), preference = sourcePreferences.preferredMangaDexId(),
title = stringResource(SYMR.strings.mangadex_preffered_source), title = stringResource(SYMR.strings.mangadex_preffered_source),
subtitle = stringResource(SYMR.strings.mangadex_preffered_source_summary), subtitle = stringResource(SYMR.strings.mangadex_preffered_source_summary),
entries = MdUtil.getEnabledMangaDexs(sourcePreferences) entries = MdUtil.getEnabledMangaDexs(sourcePreferences)
@ -250,7 +247,7 @@ object SettingsMangadexScreen : SearchableSettings {
} }
@Composable @Composable
fun syncMangaDexIntoThis(unsortedPreferences: UnsortedPreferences): Preference.PreferenceItem.TextPreference { fun syncMangaDexIntoThis(sourcePreferences: SourcePreferences): Preference.PreferenceItem.TextPreference {
val context = LocalContext.current val context = LocalContext.current
var dialogOpen by remember { mutableStateOf(false) } var dialogOpen by remember { mutableStateOf(false) }
if (dialogOpen) { if (dialogOpen) {
@ -258,7 +255,7 @@ object SettingsMangadexScreen : SearchableSettings {
onDismissRequest = { dialogOpen = false }, onDismissRequest = { dialogOpen = false },
onSelectionConfirmed = { items -> onSelectionConfirmed = { items ->
dialogOpen = false dialogOpen = false
unsortedPreferences.mangadexSyncToLibraryIndexes().set( sourcePreferences.mangadexSyncToLibraryIndexes().set(
List(items.size) { index -> (index + 1).toString() }.toSet(), List(items.size) { index -> (index + 1).toString() }.toSet(),
) )
LibraryUpdateJob.startNow( LibraryUpdateJob.startNow(

View File

@ -227,13 +227,6 @@ object SettingsReaderScreen : SearchableSettings {
preference = readerPreferences.skipDupe(), preference = readerPreferences.skipDupe(),
title = stringResource(MR.strings.pref_skip_dupe_chapters), title = stringResource(MR.strings.pref_skip_dupe_chapters),
), ),
// SY -->
Preference.PreferenceItem.SwitchPreference(
preference = readerPreferences.markReadDupe(),
title = stringResource(SYMR.strings.pref_mark_read_dupe_chapters),
subtitle = stringResource(SYMR.strings.pref_mark_read_dupe_chapters_summary),
),
// SY <--
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
preference = readerPreferences.alwaysShowChapterTransition(), preference = readerPreferences.alwaysShowChapterTransition(),
title = stringResource(MR.strings.pref_always_show_chapter_transition), title = stringResource(MR.strings.pref_always_show_chapter_transition),

View File

@ -328,7 +328,7 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
return super.generateFileName( return super.generateFileName(
logLevel, logLevel,
timestamp, timestamp,
) + "-${BuildConfig.BUILD_TYPE}.log" ) + "-${BuildConfig.BUILD_TYPE}.txt"
} }
} }
flattener { timeMillis, level, tag, message -> flattener { timeMillis, level, tag, message ->

View File

@ -118,13 +118,15 @@ class MangaBackupCreator(
private fun Manga.toBackupManga(/* SY --> */customMangaInfo: CustomMangaInfo?/* SY <-- */) = private fun Manga.toBackupManga(/* SY --> */customMangaInfo: CustomMangaInfo?/* SY <-- */) =
BackupManga( BackupManga(
url = this.url, url = this.url,
title = this.title, // SY -->
artist = this.artist, title = this.ogTitle,
author = this.author, artist = this.ogArtist,
description = this.description, author = this.ogAuthor,
genre = this.genre.orEmpty(), description = this.ogDescription,
status = this.status.toInt(), genre = this.ogGenre.orEmpty(),
thumbnailUrl = this.thumbnailUrl, status = this.ogStatus.toInt(),
thumbnailUrl = this.ogThumbnailUrl,
// SY <--
favorite = this.favorite, favorite = this.favorite,
source = this.source, source = this.source,
dateAdded = this.dateAdded, dateAdded = this.dateAdded,

View File

@ -139,13 +139,15 @@ class MangaRestorer(
mangasQueries.update( mangasQueries.update(
source = manga.source, source = manga.source,
url = manga.url, url = manga.url,
artist = manga.artist, // SY -->
author = manga.author, artist = manga.ogArtist,
description = manga.description, author = manga.ogAuthor,
genre = manga.genre?.joinToString(separator = ", "), description = manga.ogDescription,
title = manga.title, genre = manga.ogGenre?.joinToString(separator = ", "),
status = manga.status, title = manga.ogTitle,
thumbnailUrl = manga.thumbnailUrl, status = manga.ogStatus,
thumbnailUrl = manga.ogThumbnailUrl,
// SY <--
favorite = manga.favorite, favorite = manga.favorite,
lastUpdate = manga.lastUpdate, lastUpdate = manga.lastUpdate,
nextUpdate = null, nextUpdate = null,
@ -275,13 +277,15 @@ class MangaRestorer(
mangasQueries.insert( mangasQueries.insert(
source = manga.source, source = manga.source,
url = manga.url, url = manga.url,
artist = manga.artist, // SY -->
author = manga.author, artist = manga.ogArtist,
description = manga.description, author = manga.ogAuthor,
genre = manga.genre, description = manga.ogDescription,
title = manga.title, genre = manga.ogGenre,
status = manga.status, title = manga.ogTitle,
thumbnailUrl = manga.thumbnailUrl, status = manga.ogStatus,
thumbnailUrl = manga.ogThumbnailUrl,
// SY <--
favorite = manga.favorite, favorite = manga.favorite,
lastUpdate = manga.lastUpdate, lastUpdate = manga.lastUpdate,
nextUpdate = 0L, nextUpdate = 0L,
@ -458,6 +462,7 @@ class MangaRestorer(
} }
// SY --> // SY -->
/** /**
* Restore the categories from Json * Restore the categories from Json
* *

View File

@ -291,6 +291,7 @@ class DownloadManager(
} }
// SY --> // SY -->
/** /**
* return the list of all manga folders * return the list of all manga folders
*/ */

View File

@ -120,6 +120,7 @@ class DownloadProvider(
} }
// SY --> // SY -->
/** /**
* Returns a list of all files in manga directory * Returns a list of all files in manga directory
* *

View File

@ -23,6 +23,7 @@ import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.manga.interactor.UpdateManga import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.copyFrom import eu.kanade.domain.manga.model.copyFrom
import eu.kanade.domain.manga.model.toSManga import eu.kanade.domain.manga.model.toSManga
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.domain.sync.SyncPreferences import eu.kanade.domain.sync.SyncPreferences
import eu.kanade.domain.track.model.toDbTrack import eu.kanade.domain.track.model.toDbTrack
import eu.kanade.domain.track.model.toDomainTrack import eu.kanade.domain.track.model.toDomainTrack
@ -64,7 +65,6 @@ import tachiyomi.core.common.i18n.stringResource
import tachiyomi.core.common.preference.getAndSet import tachiyomi.core.common.preference.getAndSet
import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.core.common.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.model.Chapter
@ -558,11 +558,12 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
} }
// SY --> // SY -->
/** /**
* filter all follows from Mangadex and only add reading or rereading manga to library * filter all follows from Mangadex and only add reading or rereading manga to library
*/ */
private suspend fun syncFollows() = coroutineScope { private suspend fun syncFollows() = coroutineScope {
val preferences = Injekt.get<UnsortedPreferences>() val preferences = Injekt.get<SourcePreferences>()
var count = 0 var count = 0
val mangaDex = MdUtil.getEnabledMangaDex(preferences, sourceManager = sourceManager) val mangaDex = MdUtil.getEnabledMangaDex(preferences, sourceManager = sourceManager)
?: return@coroutineScope ?: return@coroutineScope
@ -734,6 +735,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
private const val KEY_TARGET = "target" private const val KEY_TARGET = "target"
// SY --> // SY -->
/** /**
* Key for group to update. * Key for group to update.
*/ */

View File

@ -18,8 +18,6 @@ import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR import tachiyomi.i18n.sy.SYMR
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import tachiyomi.domain.track.model.Track as DomainTrack import tachiyomi.domain.track.model.Track as DomainTrack
class MdList(id: Long) : BaseTracker(id, "MDList") { class MdList(id: Long) : BaseTracker(id, "MDList") {
@ -30,7 +28,7 @@ class MdList(id: Long) : BaseTracker(id, "MDList") {
.toImmutableList() .toImmutableList()
} }
private val mdex by lazy { MdUtil.getEnabledMangaDex(Injekt.get()) } private val mdex by lazy { MdUtil.getEnabledMangaDex() }
val interceptor = MangaDexAuthInterceptor(trackPreferences, this) val interceptor = MangaDexAuthInterceptor(trackPreferences, this)

View File

@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.di
import android.app.Application import android.app.Application
import exh.pref.DelegateSourcePreferences import exh.pref.DelegateSourcePreferences
import tachiyomi.domain.UnsortedPreferences import exh.source.ExhPreferences
import uy.kohesive.injekt.api.InjektRegistrar import uy.kohesive.injekt.api.InjektRegistrar
class SYPreferenceModule(val application: Application) : InjektModule { class SYPreferenceModule(val application: Application) : InjektModule {
@ -15,7 +15,7 @@ class SYPreferenceModule(val application: Application) : InjektModule {
} }
addSingletonFactory { addSingletonFactory {
UnsortedPreferences(get()) ExhPreferences(get())
} }
} }
} }

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.source package eu.kanade.tachiyomi.source
import android.content.Context import android.content.Context
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.extension.ExtensionManager import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
@ -19,6 +20,7 @@ import exh.source.EH_SOURCE_ID
import exh.source.EIGHTMUSES_SOURCE_ID import exh.source.EIGHTMUSES_SOURCE_ID
import exh.source.EXH_SOURCE_ID import exh.source.EXH_SOURCE_ID
import exh.source.EnhancedHttpSource import exh.source.EnhancedHttpSource
import exh.source.ExhPreferences
import exh.source.HBROWSE_SOURCE_ID import exh.source.HBROWSE_SOURCE_ID
import exh.source.MERGED_SOURCE_ID import exh.source.MERGED_SOURCE_ID
import exh.source.PURURIN_SOURCE_ID import exh.source.PURURIN_SOURCE_ID
@ -36,7 +38,6 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.source.model.StubSource import tachiyomi.domain.source.model.StubSource
import tachiyomi.domain.source.repository.StubSourceRepository import tachiyomi.domain.source.repository.StubSourceRepository
import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.source.service.SourceManager
@ -69,14 +70,15 @@ class AndroidSourceManager(
} }
// SY --> // SY -->
private val preferences: UnsortedPreferences by injectLazy() private val exhPreferences: ExhPreferences by injectLazy()
private val sourcePreferences: SourcePreferences by injectLazy()
// SY <-- // SY <--
init { init {
scope.launch { scope.launch {
extensionManager.installedExtensionsFlow extensionManager.installedExtensionsFlow
// SY --> // SY -->
.combine(preferences.enableExhentai().changes()) { extensions, enableExhentai -> .combine(exhPreferences.enableExhentai().changes()) { extensions, enableExhentai ->
extensions to enableExhentai extensions to enableExhentai
} }
// SY <-- // SY <--
@ -88,7 +90,7 @@ class AndroidSourceManager(
Injekt.get(), Injekt.get(),
Injekt.get(), Injekt.get(),
// SY --> // SY -->
preferences.allowLocalSourceHiddenFolders()::get, sourcePreferences.allowLocalSourceHiddenFolders()::get,
// SY <-- // SY <--
), ),
), ),

View File

@ -44,6 +44,7 @@ import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_WEAK
import exh.metadata.metadata.RaisedSearchMetadata.Companion.TAG_TYPE_VIRTUAL import exh.metadata.metadata.RaisedSearchMetadata.Companion.TAG_TYPE_VIRTUAL
import exh.metadata.metadata.RaisedSearchMetadata.Companion.toGenreString import exh.metadata.metadata.RaisedSearchMetadata.Companion.toGenreString
import exh.metadata.metadata.base.RaisedTag import exh.metadata.metadata.base.RaisedTag
import exh.source.ExhPreferences
import exh.ui.login.EhLoginActivity import exh.ui.login.EhLoginActivity
import exh.util.UriFilter import exh.util.UriFilter
import exh.util.UriGroup import exh.util.UriGroup
@ -84,7 +85,6 @@ import org.jsoup.nodes.TextNode
import rx.Observable import rx.Observable
import tachiyomi.core.common.util.lang.runAsObservable import tachiyomi.core.common.util.lang.runAsObservable
import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.domain.UnsortedPreferences
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.IOException import java.io.IOException
@ -117,7 +117,7 @@ class EHentai(
override val lang = "all" override val lang = "all"
override val supportsLatest = true override val supportsLatest = true
private val preferences: UnsortedPreferences by injectLazy() private val exhPreferences: ExhPreferences by injectLazy()
private val updateHelper: EHentaiUpdateHelper by injectLazy() private val updateHelper: EHentaiUpdateHelper by injectLazy()
/** /**
@ -476,7 +476,7 @@ class EHentai(
} }
private fun <T : MangasPage> T.checkValid(): MangasPage = private fun <T : MangasPage> T.checkValid(): MangasPage =
if (exh && mangas.isEmpty() && preferences.igneousVal().get().equals("mystery", true)) { if (exh && mangas.isEmpty() && exhPreferences.igneousVal().get().equals("mystery", true)) {
throw Exception( throw Exception(
"Invalid igneous cookie, try re-logging or finding a correct one to input in the login menu", "Invalid igneous cookie, try re-logging or finding a correct one to input in the login menu",
) )
@ -879,30 +879,30 @@ class EHentai(
} }
fun spPref() = if (exh) { fun spPref() = if (exh) {
preferences.exhSettingsProfile() exhPreferences.exhSettingsProfile()
} else { } else {
preferences.ehSettingsProfile() exhPreferences.ehSettingsProfile()
} }
private fun rawCookies(sp: Int): Map<String, String> { private fun rawCookies(sp: Int): Map<String, String> {
val cookies: MutableMap<String, String> = mutableMapOf() val cookies: MutableMap<String, String> = mutableMapOf()
if (preferences.enableExhentai().get()) { if (exhPreferences.enableExhentai().get()) {
cookies[EhLoginActivity.MEMBER_ID_COOKIE] = preferences.memberIdVal().get() cookies[EhLoginActivity.MEMBER_ID_COOKIE] = exhPreferences.memberIdVal().get()
cookies[EhLoginActivity.PASS_HASH_COOKIE] = preferences.passHashVal().get() cookies[EhLoginActivity.PASS_HASH_COOKIE] = exhPreferences.passHashVal().get()
cookies[EhLoginActivity.IGNEOUS_COOKIE] = preferences.igneousVal().get() cookies[EhLoginActivity.IGNEOUS_COOKIE] = exhPreferences.igneousVal().get()
cookies["sp"] = sp.toString() cookies["sp"] = sp.toString()
val sessionKey = preferences.exhSettingsKey().get() val sessionKey = exhPreferences.exhSettingsKey().get()
if (sessionKey.isNotBlank()) { if (sessionKey.isNotBlank()) {
cookies["sk"] = sessionKey cookies["sk"] = sessionKey
} }
val sessionCookie = preferences.exhSessionCookie().get() val sessionCookie = exhPreferences.exhSessionCookie().get()
if (sessionCookie.isNotBlank()) { if (sessionCookie.isNotBlank()) {
cookies["s"] = sessionCookie cookies["s"] = sessionCookie
} }
val hathPerksCookie = preferences.exhHathPerksCookies().get() val hathPerksCookie = exhPreferences.exhHathPerksCookies().get()
if (hathPerksCookie.isNotBlank()) { if (hathPerksCookie.isNotBlank()) {
cookies["hath_perks"] = hathPerksCookie cookies["hath_perks"] = hathPerksCookie
} }
@ -949,7 +949,7 @@ class EHentai(
ToplistOptions(), ToplistOptions(),
Filter.Separator(), Filter.Separator(),
AutoCompleteTags(), AutoCompleteTags(),
Watched(isEnabled = preferences.exhWatchedListDefaultState().get()), Watched(isEnabled = exhPreferences.exhWatchedListDefaultState().get()),
GenreGroup(), GenreGroup(),
AdvancedGroup(), AdvancedGroup(),
ReverseFilter(), ReverseFilter(),
@ -1360,7 +1360,7 @@ class EHentai(
private const val BLANK_PREVIEW_THUMB = "https://$THUMB_DOMAIN/g/$BLANK_THUMB" private const val BLANK_PREVIEW_THUMB = "https://$THUMB_DOMAIN/g/$BLANK_THUMB"
private val MATCH_YEAR_REGEX = "^\\d{4}\$".toRegex() private val MATCH_YEAR_REGEX = "^\\d{4}\$".toRegex()
private val MATCH_SEEK_REGEX = "^\\d{2,4}-\\d{1,2}".toRegex() private val MATCH_SEEK_REGEX = "^\\d{2,4}-\\d{1,2}(-\\d{1,2})?".toRegex()
private val MATCH_JUMP_REGEX = "^\\d+(\$|d\$|w\$|m\$|y\$|-\$)".toRegex() private val MATCH_JUMP_REGEX = "^\\d+(\$|d\$|w\$|m\$|y\$|-\$)".toRegex()
private const val EH_API_BASE = "https://api.e-hentai.org/api.php" private const val EH_API_BASE = "https://api.e-hentai.org/api.php"

View File

@ -70,7 +70,9 @@ class NHentai(delegate: HttpSource, val context: Context) :
} }
override suspend fun parseIntoMetadata(metadata: NHentaiSearchMetadata, input: Response) { override suspend fun parseIntoMetadata(metadata: NHentaiSearchMetadata, input: Response) {
val json = GALLERY_JSON_REGEX.find(input.body.string())!!.groupValues[1].replace( val body = input.body.string()
val server = MEDIA_SERVER_REGEX.find(body)?.groupValues?.get(1)?.toInt() ?: 1
val json = GALLERY_JSON_REGEX.find(body)!!.groupValues[1].replace(
UNICODE_ESCAPE_REGEX, UNICODE_ESCAPE_REGEX,
) { it.groupValues[1].toInt(radix = 16).toChar().toString() } ) { it.groupValues[1].toInt(radix = 16).toChar().toString() }
val jsonResponse = jsonParser.decodeFromString<JsonResponse>(json) val jsonResponse = jsonParser.decodeFromString<JsonResponse>(json)
@ -84,6 +86,8 @@ class NHentai(delegate: HttpSource, val context: Context) :
mediaId = jsonResponse.mediaId mediaId = jsonResponse.mediaId
mediaServer = server
jsonResponse.title?.let { title -> jsonResponse.title?.let { title ->
japaneseTitle = title.japanese japaneseTitle = title.japanese
shortTitle = title.pretty shortTitle = title.pretty
@ -190,17 +194,24 @@ class NHentai(delegate: HttpSource, val context: Context) :
return PagePreviewPage( return PagePreviewPage(
page, page,
metadata.pageImageTypes.mapIndexed { index, s -> metadata.pageImageTypes.mapIndexed { index, s ->
PagePreviewInfo(index + 1, imageUrl = thumbnailUrlFromType(metadata.mediaId!!, index + 1, s)!!) PagePreviewInfo(
index + 1,
imageUrl = thumbnailUrlFromType(metadata.mediaId!!, metadata.mediaServer ?: 1, index + 1, s)!!,
)
}, },
false, false,
1, 1,
) )
} }
private fun thumbnailUrlFromType(mediaId: String, page: Int, t: String) = private fun thumbnailUrlFromType(
NHentaiSearchMetadata.typeToExtension(t)?.let { mediaId: String,
"https://t1.nhentai.net/galleries/$mediaId/${page}t.$it" mediaServer: Int,
} page: Int,
t: String,
) = NHentaiSearchMetadata.typeToExtension(t)?.let {
"https://t$mediaServer.nhentai.net/galleries/$mediaId/${page}t.$it"
}
override suspend fun fetchPreviewImage(page: PagePreviewInfo, cacheControl: CacheControl?): Response { override suspend fun fetchPreviewImage(page: PagePreviewInfo, cacheControl: CacheControl?): Response {
return client.newCachelessCallWithProgress( return client.newCachelessCallWithProgress(
@ -221,6 +232,7 @@ class NHentai(delegate: HttpSource, val context: Context) :
} }
private val GALLERY_JSON_REGEX = Regex(".parse\\(\"(.*)\"\\);") private val GALLERY_JSON_REGEX = Regex(".parse\\(\"(.*)\"\\);")
private val MEDIA_SERVER_REGEX = Regex("media_server\\s*:\\s*(\\d+)")
private val UNICODE_ESCAPE_REGEX = Regex("\\\\u([0-9a-fA-F]{4})") private val UNICODE_ESCAPE_REGEX = Regex("\\\\u([0-9a-fA-F]{4})")
private const val TITLE_PREF = "Display manga title as:" private const val TITLE_PREF = "Display manga title as:"
} }

View File

@ -13,13 +13,13 @@ import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.components.AdaptiveSheet import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.tachiyomi.databinding.MigrationBottomSheetBinding import eu.kanade.tachiyomi.databinding.MigrationBottomSheetBinding
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import tachiyomi.core.common.preference.Preference import tachiyomi.core.common.preference.Preference
import tachiyomi.core.common.util.lang.toLong import tachiyomi.core.common.util.lang.toLong
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.i18n.sy.SYMR import tachiyomi.i18n.sy.SYMR
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -45,7 +45,7 @@ fun MigrationBottomSheetDialog(
} }
class MigrationBottomSheetDialogState(private val onStartMigration: State<(extraParam: String?) -> Unit>) { class MigrationBottomSheetDialogState(private val onStartMigration: State<(extraParam: String?) -> Unit>) {
private val preferences: UnsortedPreferences by injectLazy() private val preferences: SourcePreferences by injectLazy()
/** /**
* Init general reader preferences. * Init general reader preferences.

View File

@ -10,14 +10,12 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class PreMigrationScreenModel( class PreMigrationScreenModel(
private val sourceManager: SourceManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(),
private val prefs: UnsortedPreferences = Injekt.get(),
private val sourcePreferences: SourcePreferences = Injekt.get(), private val sourcePreferences: SourcePreferences = Injekt.get(),
) : ScreenModel { ) : ScreenModel {
@ -53,7 +51,7 @@ class PreMigrationScreenModel(
*/ */
private fun getEnabledSources(): List<MigrationSourceItem> { private fun getEnabledSources(): List<MigrationSourceItem> {
val languages = sourcePreferences.enabledLanguages().get() val languages = sourcePreferences.enabledLanguages().get()
val sourcesSaved = prefs.migrationSources().get().split("/") val sourcesSaved = sourcePreferences.migrationSources().get().split("/")
.mapNotNull { it.toLongOrNull() } .mapNotNull { it.toLongOrNull() }
val disabledSources = sourcePreferences.disabledSources().get() val disabledSources = sourcePreferences.disabledSources().get()
.mapNotNull { it.toLongOrNull() } .mapNotNull { it.toLongOrNull() }
@ -134,6 +132,6 @@ class PreMigrationScreenModel(
?.joinToString("/") { it.source.id.toString() } ?.joinToString("/") { it.source.id.toString() }
.orEmpty() .orEmpty()
prefs.migrationSources().set(listOfSources) sourcePreferences.migrationSources().set(listOfSources)
} }
} }

View File

@ -118,8 +118,7 @@ class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen
) )
val onDismissRequest = { screenModel.dialog.value = null } val onDismissRequest = { screenModel.dialog.value = null }
when when (
(
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
val dialog = dialog val dialog = dialog
) { ) {

View File

@ -8,6 +8,7 @@ import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.manga.interactor.UpdateManga import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.hasCustomCover import eu.kanade.domain.manga.model.hasCustomCover
import eu.kanade.domain.manga.model.toSManga import eu.kanade.domain.manga.model.toSManga
import eu.kanade.domain.source.service.SourcePreferences
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.data.download.DownloadManager
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
@ -38,14 +39,13 @@ import logcat.LogPriority
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.core.common.util.lang.withUIContext import tachiyomi.core.common.util.lang.withUIContext
import tachiyomi.core.common.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.category.interactor.GetCategories import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.interactor.SetMangaCategories import tachiyomi.domain.category.interactor.SetMangaCategories
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
import tachiyomi.domain.chapter.interactor.UpdateChapter import tachiyomi.domain.chapter.interactor.UpdateChapter
import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.chapter.model.ChapterUpdate import tachiyomi.domain.chapter.model.ChapterUpdate
import tachiyomi.domain.history.interactor.GetHistoryByMangaId import tachiyomi.domain.history.interactor.GetHistory
import tachiyomi.domain.history.interactor.UpsertHistory import tachiyomi.domain.history.interactor.UpsertHistory
import tachiyomi.domain.history.model.HistoryUpdate import tachiyomi.domain.history.model.HistoryUpdate
import tachiyomi.domain.manga.interactor.GetManga import tachiyomi.domain.manga.interactor.GetManga
@ -64,7 +64,7 @@ import java.util.concurrent.atomic.AtomicInteger
class MigrationListScreenModel( class MigrationListScreenModel(
private val config: MigrationProcedureConfig, private val config: MigrationProcedureConfig,
private val preferences: UnsortedPreferences = Injekt.get(), private val preferences: SourcePreferences = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(),
private val downloadManager: DownloadManager = Injekt.get(), private val downloadManager: DownloadManager = Injekt.get(),
private val coverCache: CoverCache = Injekt.get(), private val coverCache: CoverCache = Injekt.get(),
@ -75,7 +75,7 @@ class MigrationListScreenModel(
private val updateChapter: UpdateChapter = Injekt.get(), private val updateChapter: UpdateChapter = Injekt.get(),
private val getChaptersByMangaId: GetChaptersByMangaId = Injekt.get(), private val getChaptersByMangaId: GetChaptersByMangaId = Injekt.get(),
private val getMergedReferencesById: GetMergedReferencesById = Injekt.get(), private val getMergedReferencesById: GetMergedReferencesById = Injekt.get(),
private val getHistoryByMangaId: GetHistoryByMangaId = Injekt.get(), private val getHistoryByMangaId: GetHistory = Injekt.get(),
private val upsertHistory: UpsertHistory = Injekt.get(), private val upsertHistory: UpsertHistory = Injekt.get(),
private val getCategories: GetCategories = Injekt.get(), private val getCategories: GetCategories = Injekt.get(),
private val setMangaCategories: SetMangaCategories = Injekt.get(), private val setMangaCategories: SetMangaCategories = Injekt.get(),
@ -236,7 +236,7 @@ class MigrationListScreenModel(
try { try {
syncChaptersWithSource.await(chapters, localManga, source) syncChaptersWithSource.await(chapters, localManga, source)
} catch (e: Exception) { } catch (_: Exception) {
return@async2 null return@async2 null
} }
manga.progress.value = manga.progress.value =
@ -248,7 +248,7 @@ class MigrationListScreenModel(
} catch (e: CancellationException) { } catch (e: CancellationException) {
// Ignore cancellations // Ignore cancellations
throw e throw e
} catch (e: Exception) { } catch (_: Exception) {
null null
} }
} }
@ -283,7 +283,7 @@ class MigrationListScreenModel(
} catch (e: CancellationException) { } catch (e: CancellationException) {
// Ignore cancellations // Ignore cancellations
throw e throw e
} catch (e: Exception) { } catch (_: Exception) {
null null
} }
manga.progress.value = validSources.size to (index + 1) manga.progress.value = validSources.size to (index + 1)
@ -293,7 +293,7 @@ class MigrationListScreenModel(
null null
} }
}.await() }.await()
} catch (e: CancellationException) { } catch (_: CancellationException) {
// Ignore canceled migrations // Ignore canceled migrations
continue continue
} }
@ -305,7 +305,7 @@ class MigrationListScreenModel(
} catch (e: CancellationException) { } catch (e: CancellationException) {
// Ignore cancellations // Ignore cancellations
throw e throw e
} catch (e: Exception) { } catch (_: Exception) {
} }
} }
@ -460,7 +460,7 @@ class MigrationListScreenModel(
val source = sourceManager.get(manga.source)!! val source = sourceManager.get(manga.source)!!
val chapters = source.getChapterList(localManga.toSManga()) val chapters = source.getChapterList(localManga.toSManga())
syncChaptersWithSource.await(chapters, localManga, source) syncChaptersWithSource.await(chapters, localManga, source)
} catch (e: Exception) { } catch (_: Exception) {
return@async null return@async null
} }
localManga localManga
@ -473,7 +473,7 @@ class MigrationListScreenModel(
} catch (e: CancellationException) { } catch (e: CancellationException) {
// Ignore cancellations // Ignore cancellations
throw e throw e
} catch (e: Exception) { } catch (_: Exception) {
} }
migratingManga.searchResult.value = SearchResult.Result(result.id) migratingManga.searchResult.value = SearchResult.Result(result.id)

View File

@ -8,13 +8,13 @@ import androidx.compose.ui.platform.LocalContext
import cafe.adriel.voyager.core.model.rememberScreenModel import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.browse.MigrateMangaScreen import eu.kanade.presentation.browse.MigrateMangaScreen
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationScreen import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationScreen
import eu.kanade.tachiyomi.ui.manga.MangaScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -44,7 +44,7 @@ data class MigrateMangaScreen(
onClickItem = { onClickItem = {
// SY --> // SY -->
PreMigrationScreen.navigateToMigration( PreMigrationScreen.navigateToMigration(
Injekt.get<UnsortedPreferences>().skipPreMigration().get(), Injekt.get<SourcePreferences>().skipPreMigration().get(),
navigator, navigator,
listOf(it.id), listOf(it.id),
) )

View File

@ -10,6 +10,7 @@ import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.browse.MigrateSourceScreen import eu.kanade.presentation.browse.MigrateSourceScreen
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.TabContent import eu.kanade.presentation.components.TabContent
@ -19,7 +20,6 @@ import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.core.common.util.lang.withUIContext import tachiyomi.core.common.util.lang.withUIContext
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.manga.interactor.GetFavorites import tachiyomi.domain.manga.interactor.GetFavorites
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
@ -63,7 +63,7 @@ fun Screen.migrateSourceTab(): TabContent {
manga.asSequence().filter { it.source == source.id }.map { it.id }.toList() manga.asSequence().filter { it.source == source.id }.map { it.id }.toList()
withUIContext { withUIContext {
PreMigrationScreen.navigateToMigration( PreMigrationScreen.navigateToMigration(
Injekt.get<UnsortedPreferences>().skipPreMigration().get(), Injekt.get<SourcePreferences>().skipPreMigration().get(),
navigator, navigator,
sourceMangas, sourceMangas,
) )

View File

@ -1,15 +0,0 @@
package eu.kanade.tachiyomi.ui.browse.migration.sources
import androidx.compose.runtime.Composable
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.browse.BrowseTabWrapper
import eu.kanade.presentation.util.Screen
class MigrationSourcesScreen : Screen() {
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
BrowseTabWrapper(migrateSourceTab(), onBackPressed = navigator::pop)
}
}

View File

@ -36,6 +36,7 @@ import androidx.compose.ui.platform.LocalUriHandler
import cafe.adriel.voyager.core.model.rememberScreenModel import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.browse.BrowseSourceContent import eu.kanade.presentation.browse.BrowseSourceContent
import eu.kanade.presentation.browse.MissingSourceScreen import eu.kanade.presentation.browse.MissingSourceScreen
import eu.kanade.presentation.browse.components.BrowseSourceToolbar import eu.kanade.presentation.browse.components.BrowseSourceToolbar
@ -64,7 +65,6 @@ import kotlinx.coroutines.flow.receiveAsFlow
import mihon.presentation.core.util.collectAsLazyPagingItems import mihon.presentation.core.util.collectAsLazyPagingItems
import tachiyomi.core.common.Constants import tachiyomi.core.common.Constants
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.source.model.StubSource import tachiyomi.domain.source.model.StubSource
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
@ -327,7 +327,7 @@ data class BrowseSourceScreen(
onMigrate = { onMigrate = {
// SY --> // SY -->
PreMigrationScreen.navigateToMigration( PreMigrationScreen.navigateToMigration(
Injekt.get<UnsortedPreferences>().skipPreMigration().get(), Injekt.get<SourcePreferences>().skipPreMigration().get(),
navigator, navigator,
it.id, it.id,
dialog.manga.id, dialog.manga.id,

View File

@ -29,6 +29,7 @@ import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.all.MangaDex import eu.kanade.tachiyomi.source.online.all.MangaDex
import eu.kanade.tachiyomi.util.removeCovers import eu.kanade.tachiyomi.util.removeCovers
import exh.metadata.metadata.RaisedSearchMetadata import exh.metadata.metadata.RaisedSearchMetadata
import exh.source.ExhPreferences
import exh.source.getMainSource import exh.source.getMainSource
import exh.source.mangaDexSourceIds import exh.source.mangaDexSourceIds
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
@ -55,7 +56,6 @@ import tachiyomi.core.common.preference.mapAsCheckboxState
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.core.common.util.lang.launchNonCancellable import tachiyomi.core.common.util.lang.launchNonCancellable
import tachiyomi.core.common.util.lang.withUIContext import tachiyomi.core.common.util.lang.withUIContext
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.category.interactor.GetCategories import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.interactor.SetMangaCategories import tachiyomi.domain.category.interactor.SetMangaCategories
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
@ -103,7 +103,7 @@ open class BrowseSourceScreenModel(
private val getIncognitoState: GetIncognitoState = Injekt.get(), private val getIncognitoState: GetIncognitoState = Injekt.get(),
// SY --> // SY -->
unsortedPreferences: UnsortedPreferences = Injekt.get(), exhPreferences: ExhPreferences = Injekt.get(),
uiPreferences: UiPreferences = Injekt.get(), uiPreferences: UiPreferences = Injekt.get(),
private val getFlatMetadataById: GetFlatMetadataById = Injekt.get(), private val getFlatMetadataById: GetFlatMetadataById = Injekt.get(),
private val deleteSavedSearchById: DeleteSavedSearchById = Injekt.get(), private val deleteSavedSearchById: DeleteSavedSearchById = Injekt.get(),
@ -117,7 +117,7 @@ open class BrowseSourceScreenModel(
val source = sourceManager.getOrStub(sourceId) val source = sourceManager.getOrStub(sourceId)
// SY --> // SY -->
val ehentaiBrowseDisplayMode by unsortedPreferences.enhancedEHentaiView().asState(screenModelScope) val ehentaiBrowseDisplayMode by exhPreferences.enhancedEHentaiView().asState(screenModelScope)
val startExpanded by uiPreferences.expandFilters().asState(screenModelScope) val startExpanded by uiPreferences.expandFilters().asState(screenModelScope)

View File

@ -19,6 +19,7 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import cafe.adriel.voyager.navigator.tab.LocalTabNavigator import cafe.adriel.voyager.navigator.tab.LocalTabNavigator
import cafe.adriel.voyager.navigator.tab.TabOptions import cafe.adriel.voyager.navigator.tab.TabOptions
import eu.kanade.core.preference.asState import eu.kanade.core.preference.asState
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.domain.ui.UiPreferences import eu.kanade.domain.ui.UiPreferences
import eu.kanade.presentation.category.components.ChangeCategoryDialog import eu.kanade.presentation.category.components.ChangeCategoryDialog
import eu.kanade.presentation.history.HistoryScreen import eu.kanade.presentation.history.HistoryScreen
@ -36,7 +37,6 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.receiveAsFlow
import tachiyomi.core.common.i18n.stringResource import tachiyomi.core.common.i18n.stringResource
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
@ -123,7 +123,7 @@ data object HistoryTab : Tab {
onMigrate = { onMigrate = {
// SY --> // SY -->
PreMigrationScreen.navigateToMigration( PreMigrationScreen.navigateToMigration(
Injekt.get<UnsortedPreferences>().skipPreMigration().get(), Injekt.get<SourcePreferences>().skipPreMigration().get(),
navigator, navigator,
it.id, it.id,
dialog.manga.id, dialog.manga.id,

View File

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.home package eu.kanade.tachiyomi.ui.home
import android.annotation.SuppressLint
import androidx.activity.compose.PredictiveBackHandler import androidx.activity.compose.PredictiveBackHandler
import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
@ -12,7 +11,8 @@ import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Badge import androidx.compose.material3.Badge
import androidx.compose.material3.BadgedBox import androidx.compose.material3.BadgedBox
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -30,15 +30,11 @@ import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastFilter import androidx.compose.ui.util.fastFilter
import androidx.compose.ui.util.fastForEach import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.lerp import androidx.compose.ui.util.lerp
@ -89,9 +85,6 @@ object HomeScreen : Screen() {
@Suppress("ConstPropertyName") @Suppress("ConstPropertyName")
private const val TabNavigatorKey = "HomeTabs" private const val TabNavigatorKey = "HomeTabs"
@SuppressLint("ComposeCompositionLocalUsage")
val LocalHomeScreenInsetsProvider = staticCompositionLocalOf { WindowInsets(0.dp) }
private val TABS = listOf( private val TABS = listOf(
LibraryTab, LibraryTab,
UpdatesTab, UpdatesTab,
@ -154,50 +147,17 @@ object HomeScreen : Screen() {
} }
} }
}, },
contentWindowInsets = WindowInsets(0),
) { contentPadding -> ) { contentPadding ->
Box( Box(
modifier = Modifier modifier = Modifier
.padding(contentPadding)
.consumeWindowInsets(contentPadding)
.graphicsLayer { .graphicsLayer {
scaleX = scale scaleX = scale
scaleY = scale scaleY = scale
} },
.windowInsetsPadding(
remember {
object : WindowInsets {
override fun getLeft(density: Density, layoutDirection: LayoutDirection): Int {
return with(density) {
contentPadding.calculateLeftPadding(layoutDirection).roundToPx()
}
}
override fun getRight(density: Density, layoutDirection: LayoutDirection): Int {
return with(density) {
contentPadding.calculateRightPadding(layoutDirection).roundToPx()
}
}
override fun getBottom(density: Density): Int = 0
override fun getTop(density: Density): Int = 0
}
},
),
) { ) {
val insets = remember {
object : WindowInsets {
override fun getBottom(density: Density): Int {
return with(density) { contentPadding.calculateBottomPadding().roundToPx() }
}
override fun getTop(density: Density): Int {
return with(density) { contentPadding.calculateTopPadding().roundToPx() }
}
override fun getLeft(density: Density, layoutDirection: LayoutDirection): Int = 0
override fun getRight(density: Density, layoutDirection: LayoutDirection): Int = 0
}
}
AnimatedContent( AnimatedContent(
targetState = tabNavigator.current, targetState = tabNavigator.current,
transitionSpec = { transitionSpec = {
@ -206,10 +166,8 @@ object HomeScreen : Screen() {
}, },
label = "tabContent", label = "tabContent",
) { ) {
CompositionLocalProvider(LocalHomeScreenInsetsProvider provides insets) { tabNavigator.saveableState(key = "currentTab", it) {
tabNavigator.saveableState(key = "currentTab", it) { it.Content()
it.Content()
}
} }
} }
} }

View File

@ -48,6 +48,7 @@ import exh.search.QueryComponent
import exh.search.SearchEngine import exh.search.SearchEngine
import exh.search.Text import exh.search.Text
import exh.source.EH_SOURCE_ID import exh.source.EH_SOURCE_ID
import exh.source.ExhPreferences
import exh.source.MERGED_SOURCE_ID import exh.source.MERGED_SOURCE_ID
import exh.source.isEhBasedManga import exh.source.isEhBasedManga
import exh.source.isMetadataSource import exh.source.isMetadataSource
@ -86,7 +87,6 @@ import tachiyomi.core.common.util.lang.compareToWithCollator
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.core.common.util.lang.launchNonCancellable import tachiyomi.core.common.util.lang.launchNonCancellable
import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.category.interactor.GetCategories import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.interactor.SetMangaCategories import tachiyomi.domain.category.interactor.SetMangaCategories
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
@ -144,7 +144,7 @@ class LibraryScreenModel(
private val downloadCache: DownloadCache = Injekt.get(), private val downloadCache: DownloadCache = Injekt.get(),
private val trackerManager: TrackerManager = Injekt.get(), private val trackerManager: TrackerManager = Injekt.get(),
// SY --> // SY -->
private val unsortedPreferences: UnsortedPreferences = Injekt.get(), private val exhPreferences: ExhPreferences = Injekt.get(),
private val sourcePreferences: SourcePreferences = Injekt.get(), private val sourcePreferences: SourcePreferences = Injekt.get(),
private val getMergedMangaById: GetMergedMangaById = Injekt.get(), private val getMergedMangaById: GetMergedMangaById = Injekt.get(),
private val getTracks: GetTracks = Injekt.get(), private val getTracks: GetTracks = Injekt.get(),
@ -260,9 +260,9 @@ class LibraryScreenModel(
// SY --> // SY -->
combine( combine(
unsortedPreferences.isHentaiEnabled().changes(), exhPreferences.isHentaiEnabled().changes(),
sourcePreferences.disabledSources().changes(), sourcePreferences.disabledSources().changes(),
unsortedPreferences.enableExhentai().changes(), exhPreferences.enableExhentai().changes(),
) { isHentaiEnabled, disabledSources, enableExhentai -> ) { isHentaiEnabled, disabledSources, enableExhentai ->
isHentaiEnabled && (EH_SOURCE_ID.toString() !in disabledSources || enableExhentai) isHentaiEnabled && (EH_SOURCE_ID.toString() !in disabledSources || enableExhentai)
} }
@ -771,7 +771,7 @@ class LibraryScreenModel(
@OptIn(DelicateCoroutinesApi::class) @OptIn(DelicateCoroutinesApi::class)
fun syncMangaToDex() { fun syncMangaToDex() {
launchIO { launchIO {
MdUtil.getEnabledMangaDex(unsortedPreferences, sourcePreferences, sourceManager)?.let { mdex -> MdUtil.getEnabledMangaDex(sourcePreferences, sourceManager)?.let { mdex ->
state.value.selection.fastFilter { it.manga.source in mangaDexSourceIds }.fastForEach { (manga) -> state.value.selection.fastFilter { it.manga.source in mangaDexSourceIds }.fastForEach { (manga) ->
mdex.updateFollowStatus(MdUtil.getMangaId(manga.url), FollowStatus.READING) mdex.updateFollowStatus(MdUtil.getMangaId(manga.url), FollowStatus.READING)
} }
@ -1242,6 +1242,7 @@ class LibraryScreenModel(
} }
// SY --> // SY -->
/** Returns first unread chapter of a manga */ /** Returns first unread chapter of a manga */
suspend fun getFirstUnread(manga: Manga): Chapter? { suspend fun getFirstUnread(manga: Manga): Chapter? {
return getNextChapters.await(manga.id).firstOrNull() return getNextChapters.await(manga.id).firstOrNull()
@ -1346,13 +1347,13 @@ class LibraryScreenModel(
} }
fun onAcceptSyncWarning() { fun onAcceptSyncWarning() {
unsortedPreferences.exhShowSyncIntro().set(false) exhPreferences.exhShowSyncIntro().set(false)
} }
fun openFavoritesSyncDialog() { fun openFavoritesSyncDialog() {
mutableState.update { mutableState.update {
it.copy( it.copy(
dialog = if (unsortedPreferences.exhShowSyncIntro().get()) { dialog = if (exhPreferences.exhShowSyncIntro().get()) {
Dialog.SyncFavoritesWarning Dialog.SyncFavoritesWarning
} else { } else {
Dialog.SyncFavoritesConfirm Dialog.SyncFavoritesConfirm

View File

@ -28,6 +28,7 @@ import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import cafe.adriel.voyager.navigator.tab.LocalTabNavigator import cafe.adriel.voyager.navigator.tab.LocalTabNavigator
import cafe.adriel.voyager.navigator.tab.TabOptions import cafe.adriel.voyager.navigator.tab.TabOptions
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.category.components.ChangeCategoryDialog import eu.kanade.presentation.category.components.ChangeCategoryDialog
import eu.kanade.presentation.library.DeleteLibraryMangaDialog import eu.kanade.presentation.library.DeleteLibraryMangaDialog
import eu.kanade.presentation.library.LibrarySettingsDialog import eu.kanade.presentation.library.LibrarySettingsDialog
@ -63,7 +64,6 @@ import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import tachiyomi.core.common.i18n.stringResource import tachiyomi.core.common.i18n.stringResource
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.domain.library.model.LibraryGroup import tachiyomi.domain.library.model.LibraryGroup
import tachiyomi.domain.library.model.LibraryManga import tachiyomi.domain.library.model.LibraryManga
@ -201,7 +201,7 @@ data object LibraryTab : Tab {
screenModel.clearSelection() screenModel.clearSelection()
if (selectedMangaIds.isNotEmpty()) { if (selectedMangaIds.isNotEmpty()) {
PreMigrationScreen.navigateToMigration( PreMigrationScreen.navigateToMigration(
Injekt.get<UnsortedPreferences>().skipPreMigration().get(), Injekt.get<SourcePreferences>().skipPreMigration().get(),
navigator, navigator,
selectedMangaIds, selectedMangaIds,
) )

View File

@ -89,6 +89,7 @@ import exh.log.DebugModeOverlay
import exh.source.BlacklistedSources import exh.source.BlacklistedSources
import exh.source.EH_SOURCE_ID import exh.source.EH_SOURCE_ID
import exh.source.EXH_SOURCE_ID import exh.source.EXH_SOURCE_ID
import exh.source.ExhPreferences
import exh.syDebugVersion import exh.syDebugVersion
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.callbackFlow
@ -103,7 +104,6 @@ import mihon.core.migration.Migrator
import tachiyomi.core.common.Constants import tachiyomi.core.common.Constants
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.core.common.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.release.interactor.GetApplicationRelease import tachiyomi.domain.release.interactor.GetApplicationRelease
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
@ -117,7 +117,7 @@ class MainActivity : BaseActivity() {
private val preferences: BasePreferences by injectLazy() private val preferences: BasePreferences by injectLazy()
// SY --> // SY -->
private val unsortedPreferences: UnsortedPreferences by injectLazy() private val exhPreferences: ExhPreferences by injectLazy()
// SY <-- // SY <--
private val downloadCache: DownloadCache by injectLazy() private val downloadCache: DownloadCache by injectLazy()
@ -222,8 +222,8 @@ class MainActivity : BaseActivity() {
// SY --> // SY -->
initWhenIdle { initWhenIdle {
// Upload settings // Upload settings
if (unsortedPreferences.enableExhentai().get() && if (exhPreferences.enableExhentai().get() &&
unsortedPreferences.exhShowSettingsUploadWarning().get() exhPreferences.exhShowSettingsUploadWarning().get()
) { ) {
runExhConfigureDialog = true runExhConfigureDialog = true
} }
@ -335,7 +335,7 @@ class MainActivity : BaseActivity() {
} }
// SY --> // SY -->
if (!unsortedPreferences.isHentaiEnabled().get()) { if (!exhPreferences.isHentaiEnabled().get()) {
BlacklistedSources.HIDDEN_SOURCES += EH_SOURCE_ID BlacklistedSources.HIDDEN_SOURCES += EH_SOURCE_ID
BlacklistedSources.HIDDEN_SOURCES += EXH_SOURCE_ID BlacklistedSources.HIDDEN_SOURCES += EXH_SOURCE_ID
} }

View File

@ -27,6 +27,7 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.domain.manga.model.hasCustomCover import eu.kanade.domain.manga.model.hasCustomCover
import eu.kanade.domain.manga.model.toSManga import eu.kanade.domain.manga.model.toSManga
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.category.components.ChangeCategoryDialog import eu.kanade.presentation.category.components.ChangeCategoryDialog
import eu.kanade.presentation.components.NavigatorAdaptiveSheet import eu.kanade.presentation.components.NavigatorAdaptiveSheet
import eu.kanade.presentation.manga.ChapterSettingsDialog import eu.kanade.presentation.manga.ChapterSettingsDialog
@ -77,7 +78,6 @@ import tachiyomi.core.common.util.lang.launchUI
import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.core.common.util.lang.withNonCancellableContext import tachiyomi.core.common.util.lang.withNonCancellableContext
import tachiyomi.core.common.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.source.service.SourceManager
@ -470,13 +470,14 @@ class MangaScreen(
} }
// SY --> // SY -->
/** /**
* Initiates source migration for the specific manga. * Initiates source migration for the specific manga.
*/ */
private fun migrateManga(navigator: Navigator, manga: Manga, toMangaId: Long? = null) { private fun migrateManga(navigator: Navigator, manga: Manga, toMangaId: Long? = null) {
// SY --> // SY -->
PreMigrationScreen.navigateToMigration( PreMigrationScreen.navigateToMigration(
Injekt.get<UnsortedPreferences>().skipPreMigration().get(), Injekt.get<SourcePreferences>().skipPreMigration().get(),
navigator, navigator,
manga.id, manga.id,
toMangaId, toMangaId,

View File

@ -184,8 +184,6 @@ class ReaderPreferences(
fun centerMarginType() = preferenceStore.getInt("center_margin_type", PagerConfig.CenterMarginType.NONE) fun centerMarginType() = preferenceStore.getInt("center_margin_type", PagerConfig.CenterMarginType.NONE)
fun archiveReaderMode() = preferenceStore.getInt("archive_reader_mode", ArchiveReaderMode.LOAD_FROM_FILE) fun archiveReaderMode() = preferenceStore.getInt("archive_reader_mode", ArchiveReaderMode.LOAD_FROM_FILE)
fun markReadDupe() = preferenceStore.getBoolean("mark_read_dupe", false)
// SY <-- // SY <--
enum class FlashColor { enum class FlashColor {

View File

@ -42,6 +42,7 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
var currentChapter: ReaderChapter? = null var currentChapter: ReaderChapter? = null
// SY --> // SY -->
/** Page used to start the shifted pages */ /** Page used to start the shifted pages */
var pageToShift: ReaderPage? = null var pageToShift: ReaderPage? = null

View File

@ -13,7 +13,7 @@ import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.chapter.model.ChapterUpdate import tachiyomi.domain.chapter.model.ChapterUpdate
import tachiyomi.domain.chapter.repository.ChapterRepository import tachiyomi.domain.chapter.repository.ChapterRepository
import tachiyomi.domain.history.interactor.GetHistoryByMangaId import tachiyomi.domain.history.interactor.GetHistory
import tachiyomi.domain.history.interactor.RemoveHistory import tachiyomi.domain.history.interactor.RemoveHistory
import tachiyomi.domain.history.interactor.UpsertHistory import tachiyomi.domain.history.interactor.UpsertHistory
import tachiyomi.domain.history.model.History import tachiyomi.domain.history.model.History
@ -43,7 +43,7 @@ class EHentaiUpdateHelper(context: Context) {
private val chapterRepository: ChapterRepository by injectLazy() private val chapterRepository: ChapterRepository by injectLazy()
private val upsertHistory: UpsertHistory by injectLazy() private val upsertHistory: UpsertHistory by injectLazy()
private val removeHistory: RemoveHistory by injectLazy() private val removeHistory: RemoveHistory by injectLazy()
private val getHistoryByMangaId: GetHistoryByMangaId by injectLazy() private val getHistoryByMangaId: GetHistory by injectLazy()
private val insertFavoriteEntryAlternative: InsertFavoriteEntryAlternative by injectLazy() private val insertFavoriteEntryAlternative: InsertFavoriteEntryAlternative by injectLazy()
/** /**

View File

@ -27,14 +27,13 @@ import exh.debug.DebugToggles
import exh.eh.EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION import exh.eh.EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION
import exh.log.xLog import exh.log.xLog
import exh.metadata.metadata.EHentaiSearchMetadata import exh.metadata.metadata.EHentaiSearchMetadata
import exh.source.ExhPreferences
import exh.util.cancellable import exh.util.cancellable
import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import tachiyomi.core.common.preference.getAndSet import tachiyomi.core.common.preference.getAndSet
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.library.service.LibraryPreferences
@ -53,7 +52,7 @@ import kotlin.time.Duration.Companion.days
class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerParameters) : class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerParameters) :
CoroutineWorker(context, workerParams) { CoroutineWorker(context, workerParams) {
private val preferences: UnsortedPreferences by injectLazy() private val exhPreferences: ExhPreferences by injectLazy()
private val libraryPreferences: LibraryPreferences by injectLazy() private val libraryPreferences: LibraryPreferences by injectLazy()
private val sourceManager: SourceManager by injectLazy() private val sourceManager: SourceManager by injectLazy()
private val updateHelper: EHentaiUpdateHelper by injectLazy() private val updateHelper: EHentaiUpdateHelper by injectLazy()
@ -70,7 +69,7 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
override suspend fun doWork(): Result { override suspend fun doWork(): Result {
return try { return try {
if (requiresWifiConnection(preferences) && !context.isConnectedToWifi()) { if (requiresWifiConnection(exhPreferences) && !context.isConnectedToWifi()) {
Result.success() // retry again later Result.success() // retry again later
} else { } else {
setForegroundSafely() setForegroundSafely()
@ -215,7 +214,7 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
updatedThisIteration++ updatedThisIteration++
} }
} finally { } finally {
preferences.exhAutoUpdateStats().set( exhPreferences.exhAutoUpdateStats().set(
Json.encodeToString( Json.encodeToString(
EHentaiUpdaterStats( EHentaiUpdaterStats(
startTime, startTime,
@ -279,10 +278,10 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
} }
fun scheduleBackground(context: Context, prefInterval: Int? = null, prefRestrictions: Set<String>? = null) { fun scheduleBackground(context: Context, prefInterval: Int? = null, prefRestrictions: Set<String>? = null) {
val preferences = Injekt.get<UnsortedPreferences>() val exhPreferences = Injekt.get<ExhPreferences>()
val interval = prefInterval ?: preferences.exhAutoUpdateFrequency().get() val interval = prefInterval ?: exhPreferences.exhAutoUpdateFrequency().get()
if (interval > 0) { if (interval > 0) {
val restrictions = prefRestrictions ?: preferences.exhAutoUpdateRequirements().get() val restrictions = prefRestrictions ?: exhPreferences.exhAutoUpdateRequirements().get()
val acRestriction = DEVICE_CHARGING in restrictions val acRestriction = DEVICE_CHARGING in restrictions
val constraints = Constraints.Builder() val constraints = Constraints.Builder()
@ -312,8 +311,8 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
} }
} }
fun requiresWifiConnection(preferences: UnsortedPreferences): Boolean { fun requiresWifiConnection(exhPreferences: ExhPreferences): Boolean {
val restrictions = preferences.exhAutoUpdateRequirements().get() val restrictions = exhPreferences.exhAutoUpdateRequirements().get()
return DEVICE_ONLY_ON_WIFI in restrictions return DEVICE_ONLY_ON_WIFI in restrictions
} }
} }

View File

@ -14,6 +14,7 @@ import exh.eh.EHentaiUpdateWorker
import exh.log.xLog import exh.log.xLog
import exh.source.EH_SOURCE_ID import exh.source.EH_SOURCE_ID
import exh.source.EXH_SOURCE_ID import exh.source.EXH_SOURCE_ID
import exh.source.ExhPreferences
import exh.source.isEhBasedManga import exh.source.isEhBasedManga
import exh.util.ThrottleManager import exh.util.ThrottleManager
import exh.util.createPartialWakeLock import exh.util.createPartialWakeLock
@ -29,7 +30,6 @@ import okhttp3.Request
import tachiyomi.core.common.i18n.stringResource import tachiyomi.core.common.i18n.stringResource
import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.core.common.util.lang.withUIContext import tachiyomi.core.common.util.lang.withUIContext
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.category.interactor.CreateCategoryWithName import tachiyomi.domain.category.interactor.CreateCategoryWithName
import tachiyomi.domain.category.interactor.GetCategories import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.interactor.SetMangaCategories import tachiyomi.domain.category.interactor.SetMangaCategories
@ -57,7 +57,7 @@ class FavoritesSyncHelper(val context: Context) {
private val createCategoryWithName: CreateCategoryWithName by injectLazy() private val createCategoryWithName: CreateCategoryWithName by injectLazy()
private val updateCategory: UpdateCategory by injectLazy() private val updateCategory: UpdateCategory by injectLazy()
private val prefs: UnsortedPreferences by injectLazy() private val exhPreferences: ExhPreferences by injectLazy()
private val exh by lazy { private val exh by lazy {
Injekt.get<SourceManager>().get(EXH_SOURCE_ID) as? EHentai Injekt.get<SourceManager>().get(EXH_SOURCE_ID) as? EHentai
@ -90,7 +90,7 @@ class FavoritesSyncHelper(val context: Context) {
private suspend fun beginSync() { private suspend fun beginSync() {
// Check if logged in // Check if logged in
if (!prefs.enableExhentai().get()) { if (!exhPreferences.enableExhentai().get()) {
status.value = FavoritesSyncStatus.SyncError.NotLoggedInSyncError status.value = FavoritesSyncStatus.SyncError.NotLoggedInSyncError
return return
} }
@ -138,7 +138,7 @@ class FavoritesSyncHelper(val context: Context) {
status.value = FavoritesSyncStatus.Processing.CalculatingRemoteChanges status.value = FavoritesSyncStatus.Processing.CalculatingRemoteChanges
val remoteChanges = storage.getChangedRemoteEntries(favorites.first) val remoteChanges = storage.getChangedRemoteEntries(favorites.first)
val localChanges = if (prefs.exhReadOnlySync().get()) { val localChanges = if (exhPreferences.exhReadOnlySync().get()) {
null // Do not build local changes if they are not going to be applied null // Do not build local changes if they are not going to be applied
} else { } else {
status.value = FavoritesSyncStatus.Processing.CalculatingLocalChanges status.value = FavoritesSyncStatus.Processing.CalculatingLocalChanges
@ -238,7 +238,7 @@ class FavoritesSyncHelper(val context: Context) {
gallery.gid, gallery.gid,
) )
if (prefs.exhLenientSync().get()) { if (exhPreferences.exhLenientSync().get()) {
errorList += error errorList += error
} else { } else {
status.value = error status.value = error
@ -289,7 +289,7 @@ class FavoritesSyncHelper(val context: Context) {
) )
if (!explicitlyRetryExhRequest(10, request)) { if (!explicitlyRetryExhRequest(10, request)) {
if (prefs.exhLenientSync().get()) { if (exhPreferences.exhLenientSync().get()) {
errorList += FavoritesSyncStatus.SyncError.GallerySyncError.UnableToDeleteFromRemote errorList += FavoritesSyncStatus.SyncError.GallerySyncError.UnableToDeleteFromRemote
} else { } else {
status.value = FavoritesSyncStatus.SyncError.GallerySyncError.UnableToDeleteFromRemote status.value = FavoritesSyncStatus.SyncError.GallerySyncError.UnableToDeleteFromRemote
@ -392,7 +392,7 @@ class FavoritesSyncHelper(val context: Context) {
) )
} }
if (prefs.exhLenientSync().get()) { if (exhPreferences.exhLenientSync().get()) {
errorList += error errorList += error
} else { } else {
status.value = error status.value = error

View File

@ -16,14 +16,16 @@ class MangaDexLoginActivity : BaseOAuthLoginActivity() {
val code = data?.getQueryParameter("code") val code = data?.getQueryParameter("code")
if (code != null) { if (code != null) {
lifecycleScope.launchIO { lifecycleScope.launchIO {
Injekt.get<SourceManager>().isInitialized.first { it } val sourceManager = Injekt.get<SourceManager>()
MdUtil.getEnabledMangaDex(Injekt.get())?.login(code) sourceManager.isInitialized.first { it }
MdUtil.getEnabledMangaDex(sourceManager = sourceManager)?.login(code)
returnToSettings() returnToSettings()
} }
} else { } else {
lifecycleScope.launchIO { lifecycleScope.launchIO {
Injekt.get<SourceManager>().isInitialized.first { it } val sourceManager = Injekt.get<SourceManager>()
MdUtil.getEnabledMangaDex(Injekt.get())?.logout() sourceManager.isInitialized.first { it }
MdUtil.getEnabledMangaDex(sourceManager = sourceManager)?.logout()
returnToSettings() returnToSettings()
} }
} }

View File

@ -13,6 +13,7 @@ import androidx.compose.ui.platform.LocalHapticFeedback
import cafe.adriel.voyager.core.model.rememberScreenModel import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.browse.BrowseSourceContent import eu.kanade.presentation.browse.BrowseSourceContent
import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
import eu.kanade.presentation.browse.components.RemoveMangaDialog import eu.kanade.presentation.browse.components.RemoveMangaDialog
@ -26,7 +27,6 @@ import eu.kanade.tachiyomi.ui.manga.MangaScreen
import exh.ui.ifSourcesLoaded import exh.ui.ifSourcesLoaded
import mihon.presentation.core.util.collectAsLazyPagingItems import mihon.presentation.core.util.collectAsLazyPagingItems
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.i18n.sy.SYMR import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
@ -109,7 +109,7 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
onOpenManga = { navigator.push(MangaScreen(it.id)) }, onOpenManga = { navigator.push(MangaScreen(it.id)) },
onMigrate = { onMigrate = {
PreMigrationScreen.navigateToMigration( PreMigrationScreen.navigateToMigration(
Injekt.get<UnsortedPreferences>().skipPreMigration().get(), Injekt.get<SourcePreferences>().skipPreMigration().get(),
navigator, navigator,
it.id, it.id,
dialog.manga.id, dialog.manga.id,

View File

@ -17,7 +17,6 @@ import exh.source.getMainSource
import exh.util.dropBlank import exh.util.dropBlank
import exh.util.floor import exh.util.floor
import exh.util.nullIfZero import exh.util.nullIfZero
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.Headers import okhttp3.Headers
@ -26,7 +25,6 @@ import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import org.jsoup.parser.Parser import org.jsoup.parser.Parser
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -232,9 +230,9 @@ class MdUtil {
return codeVerifier ?: PkceUtil.generateCodeVerifier().also { codeVerifier = it } return codeVerifier ?: PkceUtil.generateCodeVerifier().also { codeVerifier = it }
} }
fun getEnabledMangaDex(preferences: UnsortedPreferences, sourcePreferences: SourcePreferences = Injekt.get(), sourceManager: SourceManager = Injekt.get()): MangaDex? { fun getEnabledMangaDex(sourcePreferences: SourcePreferences = Injekt.get(), sourceManager: SourceManager = Injekt.get()): MangaDex? {
return getEnabledMangaDexs(sourcePreferences, sourceManager).let { mangadexs -> return getEnabledMangaDexs(sourcePreferences, sourceManager).let { mangadexs ->
preferences.preferredMangaDexId().get().toLongOrNull()?.nullIfZero() sourcePreferences.preferredMangaDexId().get().toLongOrNull()?.nullIfZero()
?.let { preferredMangaDexId -> ?.let { preferredMangaDexId ->
mangadexs.firstOrNull { it.id == preferredMangaDexId } mangadexs.firstOrNull { it.id == preferredMangaDexId }
} }

View File

@ -6,9 +6,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.components.AdaptiveSheet import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.tachiyomi.databinding.RecommendationSearchBottomSheetBinding import eu.kanade.tachiyomi.databinding.RecommendationSearchBottomSheetBinding
import tachiyomi.domain.UnsortedPreferences
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@Composable @Composable
@ -30,7 +30,7 @@ fun RecommendationSearchBottomSheetDialog(
} }
class RecommendationSearchBottomSheetDialogState(private val onSearchRequest: () -> Unit) { class RecommendationSearchBottomSheetDialogState(private val onSearchRequest: () -> Unit) {
private val preferences: UnsortedPreferences by injectLazy() private val preferences: SourcePreferences by injectLazy()
fun initPreferences(binding: RecommendationSearchBottomSheetBinding) { fun initPreferences(binding: RecommendationSearchBottomSheetBinding) {
val flags = preferences.recommendationSearchFlags().get() val flags = preferences.recommendationSearchFlags().get()

View File

@ -6,6 +6,7 @@ import android.os.PowerManager
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.net.toUri import androidx.core.net.toUri
import eu.kanade.domain.manga.model.toSManga import eu.kanade.domain.manga.model.toSManga
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import exh.log.xLog import exh.log.xLog
@ -27,7 +28,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mihon.domain.manga.model.toDomainManga import mihon.domain.manga.model.toDomainManga
import tachiyomi.data.source.NoResultsException import tachiyomi.data.source.NoResultsException
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.library.model.LibraryManga import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.domain.manga.interactor.GetLibraryManga import tachiyomi.domain.manga.interactor.GetLibraryManga
import tachiyomi.domain.manga.interactor.NetworkToLocalManga import tachiyomi.domain.manga.interactor.NetworkToLocalManga
@ -47,7 +47,7 @@ class RecommendationSearchHelper(val context: Context) {
private val getTracks: GetTracks by injectLazy() private val getTracks: GetTracks by injectLazy()
private val networkToLocalManga: NetworkToLocalManga by injectLazy() private val networkToLocalManga: NetworkToLocalManga by injectLazy()
private val sourceManager: SourceManager by injectLazy() private val sourceManager: SourceManager by injectLazy()
private val prefs: UnsortedPreferences by injectLazy() private val preferences: SourcePreferences by injectLazy()
private var wifiLock: WifiManager.WifiLock? = null private var wifiLock: WifiManager.WifiLock? = null
private var wakeLock: PowerManager.WakeLock? = null private var wakeLock: PowerManager.WakeLock? = null
@ -70,7 +70,7 @@ class RecommendationSearchHelper(val context: Context) {
} }
private suspend fun beginSearch(mangaList: List<Manga>) { private suspend fun beginSearch(mangaList: List<Manga>) {
val flags = prefs.recommendationSearchFlags().get() val flags = preferences.recommendationSearchFlags().get()
val libraryManga = getLibraryManga.await() val libraryManga = getLibraryManga.await()
val tracks = getTracks.await() val tracks = getTracks.await()
@ -192,7 +192,7 @@ class RecommendationSearchHelper(val context: Context) {
libraryManga: List<LibraryManga>, libraryManga: List<LibraryManga>,
tracks: List<Track>, tracks: List<Track>,
): List<SManga> { ): List<SManga> {
val flags = prefs.recommendationSearchFlags().get() val flags = preferences.recommendationSearchFlags().get()
if (!SearchFlags.hasHideLibraryResults(flags)) { if (!SearchFlags.hasHideLibraryResults(flags)) {
return this return this

View File

@ -40,8 +40,10 @@ fun RecommendationSearchProgressDialog(
val context = LocalContext.current val context = LocalContext.current
val currentView = LocalView.current val currentView = LocalView.current
DisposableEffect(Unit) { DisposableEffect(status) {
currentView.keepScreenOn = true if (status != SearchStatus.Idle) {
currentView.keepScreenOn = true
}
onDispose { onDispose {
currentView.keepScreenOn = false currentView.keepScreenOn = false
} }

View File

@ -8,19 +8,19 @@ import exh.log.maybeInjectEHLogger
import exh.log.xLogD import exh.log.xLogD
import exh.source.EH_SOURCE_ID import exh.source.EH_SOURCE_ID
import exh.source.EXH_SOURCE_ID import exh.source.EXH_SOURCE_ID
import exh.source.ExhPreferences
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import tachiyomi.core.common.i18n.stringResource import tachiyomi.core.common.i18n.stringResource
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.source.service.SourceManager
import tachiyomi.i18n.sy.SYMR import tachiyomi.i18n.sy.SYMR
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.Locale import java.util.Locale
class EHConfigurator(val context: Context) { class EHConfigurator(val context: Context) {
private val prefs: UnsortedPreferences by injectLazy() private val exhPreferences: ExhPreferences by injectLazy()
private val sources: SourceManager by injectLazy() private val sourceManager: SourceManager by injectLazy()
private val configuratorClient = OkHttpClient.Builder() private val configuratorClient = OkHttpClient.Builder()
.maybeInjectEHLogger() .maybeInjectEHLogger()
@ -52,8 +52,8 @@ class EHConfigurator(val context: Context) {
private val EHentai.uconfigUrl get() = baseUrl + UCONFIG_URL private val EHentai.uconfigUrl get() = baseUrl + UCONFIG_URL
suspend fun configureAll() { suspend fun configureAll() {
val ehSource = sources.get(EH_SOURCE_ID) as EHentai val ehSource = sourceManager.get(EH_SOURCE_ID) as EHentai
val exhSource = sources.get(EXH_SOURCE_ID) as EHentai val exhSource = sourceManager.get(EXH_SOURCE_ID) as EHentai
// Get hath perks // Get hath perks
val perksPage = configuratorClient.newCall( val perksPage = configuratorClient.newCall(
@ -146,13 +146,13 @@ class EHConfigurator(val context: Context) {
}?.removePrefix("hath_perks=")?.substringBefore(';') }?.removePrefix("hath_perks=")?.substringBefore(';')
if (keyCookie != null) { if (keyCookie != null) {
prefs.exhSettingsKey().set(keyCookie) exhPreferences.exhSettingsKey().set(keyCookie)
} }
if (sessionCookie != null) { if (sessionCookie != null) {
prefs.exhSessionCookie().set(sessionCookie) exhPreferences.exhSessionCookie().set(sessionCookie)
} }
if (hathPerksCookie != null) { if (hathPerksCookie != null) {
prefs.exhHathPerksCookies().set(hathPerksCookie) exhPreferences.exhHathPerksCookies().set(hathPerksCookie)
} }
} }

View File

@ -1,18 +1,18 @@
package exh.uconfig package exh.uconfig
import exh.source.ExhPreferences
import okhttp3.FormBody import okhttp3.FormBody
import tachiyomi.domain.UnsortedPreferences
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.Locale import java.util.Locale
class EhUConfigBuilder { class EhUConfigBuilder {
private val preferences: UnsortedPreferences by injectLazy() private val exhPreferences: ExhPreferences by injectLazy()
fun build(hathPerks: EHHathPerksResponse): FormBody { fun build(hathPerks: EHHathPerksResponse): FormBody {
val configItems = mutableListOf<ConfigItem>() val configItems = mutableListOf<ConfigItem>()
configItems += when ( configItems += when (
preferences.imageQuality() exhPreferences.imageQuality()
.get() .get()
.lowercase(Locale.getDefault()) .lowercase(Locale.getDefault())
) { ) {
@ -25,19 +25,19 @@ class EhUConfigBuilder {
else -> Entry.ImageSize.AUTO else -> Entry.ImageSize.AUTO
} }
configItems += when (preferences.useHentaiAtHome().get()) { configItems += when (exhPreferences.useHentaiAtHome().get()) {
2 -> Entry.UseHentaiAtHome.NO 2 -> Entry.UseHentaiAtHome.NO
1 -> Entry.UseHentaiAtHome.DEFAULTONLY 1 -> Entry.UseHentaiAtHome.DEFAULTONLY
else -> Entry.UseHentaiAtHome.ANY else -> Entry.UseHentaiAtHome.ANY
} }
configItems += if (preferences.useJapaneseTitle().get()) { configItems += if (exhPreferences.useJapaneseTitle().get()) {
Entry.TitleDisplayLanguage.JAPANESE Entry.TitleDisplayLanguage.JAPANESE
} else { } else {
Entry.TitleDisplayLanguage.DEFAULT Entry.TitleDisplayLanguage.DEFAULT
} }
configItems += if (preferences.exhUseOriginalImages().get()) { configItems += if (exhPreferences.exhUseOriginalImages().get()) {
Entry.UseOriginalImages.YES Entry.UseOriginalImages.YES
} else { } else {
Entry.UseOriginalImages.NO Entry.UseOriginalImages.NO
@ -61,13 +61,13 @@ class EhUConfigBuilder {
configItems += Entry.UseMPV() configItems += Entry.UseMPV()
configItems += Entry.ShowPopularRightNowPane() configItems += Entry.ShowPopularRightNowPane()
configItems += Entry.TagFilteringThreshold(preferences.ehTagFilterValue().get()) configItems += Entry.TagFilteringThreshold(exhPreferences.ehTagFilterValue().get())
configItems += Entry.TagWatchingThreshold(preferences.ehTagWatchingValue().get()) configItems += Entry.TagWatchingThreshold(exhPreferences.ehTagWatchingValue().get())
configItems += Entry.LanguageSystem().getLanguages(preferences.exhSettingsLanguages().get().split("\n")) configItems += Entry.LanguageSystem().getLanguages(exhPreferences.exhSettingsLanguages().get().split("\n"))
configItems += Entry.Categories().categoryConfigs( configItems += Entry.Categories().categoryConfigs(
preferences.exhEnabledCategories().get().split(",").map { exhPreferences.exhEnabledCategories().get().split(",").map {
it.toBoolean() it.toBoolean()
}, },
) )

View File

@ -6,6 +6,7 @@ import cafe.adriel.voyager.core.model.screenModelScope
import exh.GalleryAddEvent import exh.GalleryAddEvent
import exh.GalleryAdder import exh.GalleryAdder
import exh.log.xLogE import exh.log.xLogE
import exh.source.ExhPreferences
import exh.util.trimOrNull import exh.util.trimOrNull
import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -14,13 +15,12 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import tachiyomi.core.common.i18n.stringResource import tachiyomi.core.common.i18n.stringResource
import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.i18n.sy.SYMR import tachiyomi.i18n.sy.SYMR
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class BatchAddScreenModel( class BatchAddScreenModel(
private val unsortedPreferences: UnsortedPreferences = Injekt.get(), private val exhPreferences: ExhPreferences = Injekt.get(),
) : StateScreenModel<BatchAddState>(BatchAddState()) { ) : StateScreenModel<BatchAddState>(BatchAddState()) {
private val galleryAdder by lazy { GalleryAdder() } private val galleryAdder by lazy { GalleryAdder() }
@ -37,7 +37,7 @@ class BatchAddScreenModel(
private fun addGalleries(context: Context, galleries: String) { private fun addGalleries(context: Context, galleries: String) {
val splitGalleries = if (ehVisitedRegex.containsMatchIn(galleries)) { val splitGalleries = if (ehVisitedRegex.containsMatchIn(galleries)) {
val url = if (unsortedPreferences.enableExhentai().get()) { val url = if (exhPreferences.enableExhentai().get()) {
"https://exhentai.org/g/" "https://exhentai.org/g/"
} else { } else {
"https://e-hentai.org/g/" "https://e-hentai.org/g/"

View File

@ -21,7 +21,7 @@ import eu.kanade.tachiyomi.util.system.WebViewUtil
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.setComposeContent import eu.kanade.tachiyomi.util.view.setComposeContent
import exh.log.xLogD import exh.log.xLogD
import tachiyomi.domain.UnsortedPreferences import exh.source.ExhPreferences
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.net.HttpCookie import java.net.HttpCookie
@ -31,7 +31,7 @@ import java.util.Locale
* LoginController * LoginController
*/ */
class EhLoginActivity : BaseActivity() { class EhLoginActivity : BaseActivity() {
private val preferenceManager: UnsortedPreferences by injectLazy() private val exhPreferences: ExhPreferences by injectLazy()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
@ -106,7 +106,7 @@ class EhLoginActivity : BaseActivity() {
} else if (parsedUrl.host.equals("exhentai.org", ignoreCase = true)) { } else if (parsedUrl.host.equals("exhentai.org", ignoreCase = true)) {
// At ExHentai, check that everything worked out... // At ExHentai, check that everything worked out...
if (applyExHentaiCookies(url, customIgneous)) { if (applyExHentaiCookies(url, customIgneous)) {
preferenceManager.enableExhentai().set(true) exhPreferences.enableExhentai().set(true)
setResult(RESULT_OK) setResult(RESULT_OK)
finish() finish()
} }
@ -155,9 +155,9 @@ class EhLoginActivity : BaseActivity() {
if (memberId == null || passHash == null || igneous == null) return false if (memberId == null || passHash == null || igneous == null) return false
// Update prefs // Update prefs
preferenceManager.memberIdVal().set(memberId!!) exhPreferences.memberIdVal().set(memberId!!)
preferenceManager.passHashVal().set(passHash!!) exhPreferences.passHashVal().set(passHash!!)
preferenceManager.igneousVal().set(igneous!!) exhPreferences.igneousVal().set(igneous!!)
return true return true
} }

View File

@ -50,8 +50,7 @@ class MetadataViewScreen(private val mangaId: Long, private val sourceId: Long)
) )
}, },
) { paddingValues -> ) { paddingValues ->
when when (
(
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
val state = state val state = state
) { ) {

View File

@ -46,4 +46,5 @@ val migrations: List<Migration>
MoveEncryptionSettingsToAppStateMigration(), MoveEncryptionSettingsToAppStateMigration(),
TrustExtensionRepositoryMigration(), TrustExtensionRepositoryMigration(),
CategoryPreferencesCleanupMigration(), CategoryPreferencesCleanupMigration(),
RemoveDuplicateReaderPreferenceMigration(),
) )

View File

@ -0,0 +1,26 @@
package mihon.core.migration.migrations
import android.content.SharedPreferences
import androidx.core.content.edit
import mihon.core.migration.Migration
import mihon.core.migration.MigrationContext
import tachiyomi.core.common.util.lang.withIOContext
class RemoveDuplicateReaderPreferenceMigration : Migration {
override val version: Float = 75f
override suspend fun invoke(migrationContext: MigrationContext): Boolean = withIOContext {
val prefs = migrationContext.get<SharedPreferences>() ?: return@withIOContext false
if (prefs.getBoolean("mark_read_dupe", false)) {
val readPrefSet = prefs.getStringSet("mark_duplicate_read_chapter_read", emptySet())?.toMutableSet()
readPrefSet?.add("existing")
prefs.edit {
putStringSet("mark_duplicate_read_chapter_read", readPrefSet)
remove("mark_read_dupe")
}
}
return@withIOContext true
}
}

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item>
<selector>
<item android:state_selected="true">
<color android:color="?attr/colorControlHighlight" />
</item>
<item android:state_activated="true">
<color android:color="?attr/colorControlHighlight" />
</item>
<item>
<color android:color="?android:attr/colorBackground" />
</item>
</selector>
</item>
</ripple>

View File

@ -1,46 +1,52 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout <com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
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"
android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/list_item_selector_background"> app:cardBackgroundColor="?android:attr/colorBackground"
app:cardElevation="0dp"
app:cardForegroundColor="@color/draggable_card_foreground">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView <ImageView
android:id="@+id/image" android:id="@+id/image"
android:layout_width="60dp" android:layout_width="60dp"
android:layout_height="60dp" android:layout_height="60dp"
android:paddingStart="8dp" android:paddingStart="8dp"
android:paddingEnd="8dp" android:paddingEnd="8dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/ic_launcher_round" /> app:srcCompat="@drawable/anim_browse_enter" />
<TextView <TextView
android:id="@+id/title" android:id="@+id/title"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:ellipsize="end" android:ellipsize="end"
android:gravity="center_vertical" android:gravity="center_vertical"
android:maxLines="1" android:maxLines="1"
android:paddingStart="8dp" android:paddingStart="8dp"
android:text="Title" android:text="Title"
android:textAppearance="?attr/textAppearanceTitleSmall" android:textAppearance="?attr/textAppearanceTitleSmall"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/reorder" app:layout_constraintEnd_toStartOf="@+id/reorder"
app:layout_constraintStart_toEndOf="@+id/image" app:layout_constraintStart_toEndOf="@+id/image"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<ImageView <ImageView
android:id="@+id/reorder" android:id="@+id/reorder"
android:layout_width="60dp" android:layout_width="60dp"
android:layout_height="60dp" android:layout_height="60dp"
android:scaleType="center" android:scaleType="center"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_drag_handle_24dp" app:srcCompat="@drawable/ic_drag_handle_24dp"
app:tint="?android:attr/textColorHint" /> app:tint="?android:attr/textColorHint" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -206,6 +206,7 @@ object ImageUtil {
LEFT, LEFT,
} }
// SY --> // SY -->
/** /**
* Split the image into left and right parts, then merge them into a * Split the image into left and right parts, then merge them into a
* new image with added center padding scaled relative to the height of the display view * new image with added center padding scaled relative to the height of the display view

View File

@ -89,9 +89,5 @@ class HistoryRepositoryImpl(
logcat(LogPriority.ERROR, throwable = e) logcat(LogPriority.ERROR, throwable = e)
} }
} }
override suspend fun getByMangaId(mangaId: Long): List<History> {
return handler.awaitList { historyQueries.getHistoryByMangaId(mangaId, HistoryMapper::mapHistory) }
}
// SY <-- // SY <--
} }

View File

@ -1,35 +1,16 @@
package tachiyomi.domain package exh.source
import tachiyomi.core.common.preference.Preference import tachiyomi.core.common.preference.Preference
import tachiyomi.core.common.preference.PreferenceStore import tachiyomi.core.common.preference.PreferenceStore
class UnsortedPreferences( class ExhPreferences(
private val preferenceStore: PreferenceStore, private val preferenceStore: PreferenceStore,
) { ) {
// SY --> // SY -->
fun migrateFlags() = preferenceStore.getInt("migrate_flags", Int.MAX_VALUE)
fun defaultMangaOrder() = preferenceStore.getString("default_manga_order", "")
fun migrationSources() = preferenceStore.getString("migrate_sources", "")
fun smartMigration() = preferenceStore.getBoolean("smart_migrate", false)
fun useSourceWithMost() = preferenceStore.getBoolean("use_source_with_most", false)
fun skipPreMigration() = preferenceStore.getBoolean(Preference.appStateKey("skip_pre_migration"), false)
fun hideNotFoundMigration() = preferenceStore.getBoolean("hide_not_found_migration", false)
fun showOnlyUpdatesMigration() = preferenceStore.getBoolean("show_only_updates_migration", false)
fun recommendationSearchFlags() = preferenceStore.getInt("rec_search_flags", Int.MAX_VALUE)
fun isHentaiEnabled() = preferenceStore.getBoolean("eh_is_hentai_enabled", true) fun isHentaiEnabled() = preferenceStore.getBoolean("eh_is_hentai_enabled", true)
fun enableExhentai() = preferenceStore.getBoolean(Preference.privateKey("enable_exhentai"), false) fun enableExhentai() = preferenceStore.getBoolean(Preference.Companion.privateKey("enable_exhentai"), false)
fun imageQuality() = preferenceStore.getString("ehentai_quality", "auto") fun imageQuality() = preferenceStore.getString("ehentai_quality", "auto")
@ -44,15 +25,15 @@ class UnsortedPreferences(
fun ehTagWatchingValue() = preferenceStore.getInt("eh_tag_watching_value", 0) fun ehTagWatchingValue() = preferenceStore.getInt("eh_tag_watching_value", 0)
// EH Cookies // EH Cookies
fun memberIdVal() = preferenceStore.getString(Preference.privateKey("eh_ipb_member_id"), "") fun memberIdVal() = preferenceStore.getString(Preference.Companion.privateKey("eh_ipb_member_id"), "")
fun passHashVal() = preferenceStore.getString(Preference.privateKey("eh_ipb_pass_hash"), "") fun passHashVal() = preferenceStore.getString(Preference.Companion.privateKey("eh_ipb_pass_hash"), "")
fun igneousVal() = preferenceStore.getString(Preference.privateKey("eh_igneous"), "") fun igneousVal() = preferenceStore.getString(Preference.Companion.privateKey("eh_igneous"), "")
fun ehSettingsProfile() = preferenceStore.getInt(Preference.privateKey("eh_ehSettingsProfile"), -1) fun ehSettingsProfile() = preferenceStore.getInt(Preference.Companion.privateKey("eh_ehSettingsProfile"), -1)
fun exhSettingsProfile() = preferenceStore.getInt(Preference.privateKey("eh_exhSettingsProfile"), -1) fun exhSettingsProfile() = preferenceStore.getInt(Preference.Companion.privateKey("eh_exhSettingsProfile"), -1)
fun exhSettingsKey() = preferenceStore.getString(Preference.privateKey("eh_settingsKey"), "") fun exhSettingsKey() = preferenceStore.getString(Preference.Companion.privateKey("eh_settingsKey"), "")
fun exhSessionCookie() = preferenceStore.getString(Preference.privateKey("eh_sessionCookie"), "") fun exhSessionCookie() = preferenceStore.getString(Preference.Companion.privateKey("eh_sessionCookie"), "")
fun exhHathPerksCookies() = preferenceStore.getString(Preference.privateKey("eh_hathPerksCookie"), "") fun exhHathPerksCookies() = preferenceStore.getString(Preference.Companion.privateKey("eh_hathPerksCookie"), "")
fun exhShowSyncIntro() = preferenceStore.getBoolean("eh_show_sync_intro", true) fun exhShowSyncIntro() = preferenceStore.getBoolean("eh_show_sync_intro", true)
@ -68,7 +49,7 @@ class UnsortedPreferences(
fun exhAutoUpdateRequirements() = preferenceStore.getStringSet("eh_auto_update_restrictions", emptySet()) fun exhAutoUpdateRequirements() = preferenceStore.getStringSet("eh_auto_update_restrictions", emptySet())
fun exhAutoUpdateStats() = preferenceStore.getString(Preference.appStateKey("eh_auto_update_stats"), "") fun exhAutoUpdateStats() = preferenceStore.getString(Preference.Companion.appStateKey("eh_auto_update_stats"), "")
fun exhWatchedListDefaultState() = preferenceStore.getBoolean("eh_watched_list_default_state", false) fun exhWatchedListDefaultState() = preferenceStore.getBoolean("eh_watched_list_default_state", false)
@ -86,13 +67,4 @@ class UnsortedPreferences(
) )
fun enhancedEHentaiView() = preferenceStore.getBoolean("enhanced_e_hentai_view", true) fun enhancedEHentaiView() = preferenceStore.getBoolean("enhanced_e_hentai_view", true)
fun preferredMangaDexId() = preferenceStore.getString("preferred_mangaDex_id", "0")
fun mangadexSyncToLibraryIndexes() = preferenceStore.getStringSet(
"pref_mangadex_sync_to_library_indexes",
emptySet(),
)
fun allowLocalSourceHiddenFolders() = preferenceStore.getBoolean("allow_local_source_hidden_folders", false)
} }

View File

@ -1,13 +0,0 @@
package tachiyomi.domain.history.interactor
import tachiyomi.domain.history.model.History
import tachiyomi.domain.history.repository.HistoryRepository
class GetHistoryByMangaId(
private val repository: HistoryRepository,
) {
suspend fun await(mangaId: Long): List<History> {
return repository.getByMangaId(mangaId)
}
}

View File

@ -25,7 +25,5 @@ interface HistoryRepository {
// SY --> // SY -->
suspend fun upsertHistory(historyUpdates: List<HistoryUpdate>) suspend fun upsertHistory(historyUpdates: List<HistoryUpdate>)
suspend fun getByMangaId(mangaId: Long): List<History>
// SY <-- // SY <--
} }

View File

@ -1,5 +1,5 @@
[versions] [versions]
compose-bom = "2025.05.00" compose-bom = "2025.05.01"
[libraries] [libraries]
activity = "androidx.activity:activity-compose:1.10.1" activity = "androidx.activity:activity-compose:1.10.1"

View File

@ -1,14 +1,14 @@
[versions] [versions]
kotlin_version = "2.1.20" kotlin_version = "2.1.21"
serialization_version = "1.8.1" serialization_version = "1.8.1"
xml_serialization_version = "0.91.0" xml_serialization_version = "0.91.1"
[libraries] [libraries]
reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin_version" } reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin_version" }
gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin_version" } gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin_version" }
compose-compiler-gradle = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin_version" } compose-compiler-gradle = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin_version" }
immutables = { module = "org.jetbrains.kotlinx:kotlinx-collections-immutable", version = "0.3.8" } immutables = { module = "org.jetbrains.kotlinx:kotlinx-collections-immutable", version = "0.4.0" }
coroutines-bom = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-bom", version = "1.10.2" } coroutines-bom = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-bom", version = "1.10.2" }
coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core" } coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core" }

View File

@ -8,7 +8,7 @@ sqldelight = "2.0.2"
sqlite = "2.5.1" sqlite = "2.5.1"
voyager = "1.1.0-beta03" voyager = "1.1.0-beta03"
spotless = "7.0.3" spotless = "7.0.3"
ktlint-core = "1.5.0" ktlint-core = "1.6.0"
firebase-bom = "33.13.0" firebase-bom = "33.13.0"
markdown = "0.34.0" markdown = "0.34.0"
@ -42,7 +42,7 @@ preferencektx = "androidx.preference:preference-ktx:1.2.1"
injekt = "com.github.null2264:injekt-koin:ee267b2e27" injekt = "com.github.null2264:injekt-koin:ee267b2e27"
coil-bom = { module = "io.coil-kt.coil3:coil-bom", version = "3.1.0" } coil-bom = { module = "io.coil-kt.coil3:coil-bom", version = "3.2.0" }
coil-core = { module = "io.coil-kt.coil3:coil" } coil-core = { module = "io.coil-kt.coil3:coil" }
coil-gif = { module = "io.coil-kt.coil3:coil-gif" } coil-gif = { module = "io.coil-kt.coil3:coil-gif" }
coil-compose = { module = "io.coil-kt.coil3:coil-compose" } coil-compose = { module = "io.coil-kt.coil3:coil-compose" }

View File

@ -10,7 +10,7 @@ composeRatingbar = "com.github.a914-gowtham:compose-ratingbar:1.2.3"
versionsx = "com.github.ben-manes:gradle-versions-plugin:0.51.0" versionsx = "com.github.ben-manes:gradle-versions-plugin:0.51.0"
sqlcipher = "net.zetetic:sqlcipher-android:4.8.0" sqlcipher = "net.zetetic:sqlcipher-android:4.9.0"
exifinterface = "androidx.exifinterface:exifinterface:1.3.7" exifinterface = "androidx.exifinterface:exifinterface:1.3.7"

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@ -80,4 +80,60 @@
<item quantity="many">منذُ %1$d دقيقة</item> <item quantity="many">منذُ %1$d دقيقة</item>
<item quantity="other">منذُ %1$d دقيقة</item> <item quantity="other">منذُ %1$d دقيقة</item>
</plurals> </plurals>
<plurals name="pref_tag_sorting_desc">
<item quantity="zero">العلامات في هذه القائمة . تعطيك خيار الترتيب حسب الأولوية في هذه القائمة، مما يعني أن المدخلات سيتم توزيعها حسب اختيارك</item>
<item quantity="one">هاذا الخيار يعطيك إمكانية فرز المدخلات في هذه القائمة حسب اختيارك</item>
<item quantity="two"></item>
<item quantity="few"></item>
<item quantity="many"></item>
<item quantity="other"></item>
</plurals>
<plurals name="num_lock_times">
<item quantity="zero">وقت الإنغلاق</item>
<item quantity="one">‬وقت الإغلاق</item>
<item quantity="two"></item>
<item quantity="few"></item>
<item quantity="many"></item>
<item quantity="other"></item>
</plurals>
<plurals name="migrate_entry">
<item quantity="zero">ترحيل ....... المدخل؟</item>
<item quantity="one">نقل ...... المدخلات؟</item>
<item quantity="two"></item>
<item quantity="few"></item>
<item quantity="many"></item>
<item quantity="other"></item>
</plurals>
<plurals name="humanize_month">
<item quantity="zero">%1$d شهر مضى</item>
<item quantity="one">%1$dشهور مضت</item>
<item quantity="two"></item>
<item quantity="few"></item>
<item quantity="many"></item>
<item quantity="other"></item>
</plurals>
<plurals name="browse_language_and_pages">
<item quantity="zero">....،.... الصفحة</item>
<item quantity="one">.....،... الصفحات</item>
<item quantity="two"></item>
<item quantity="few"></item>
<item quantity="many"></item>
<item quantity="other"></item>
</plurals>
<plurals name="humanize_year">
<item quantity="zero">...... سنة مضت</item>
<item quantity="one">..... سنوات مضت</item>
<item quantity="two"></item>
<item quantity="few"></item>
<item quantity="many"></item>
<item quantity="other"></item>
</plurals>
<plurals name="humanize_week">
<item quantity="zero">"%1$d اسبوع الفائت"</item>
<item quantity="one">%1$d اسابيع الماضية</item>
<item quantity="two"></item>
<item quantity="few"></item>
<item quantity="many"></item>
<item quantity="other"></item>
</plurals>
</resources> </resources>

View File

@ -537,4 +537,71 @@
<string name="favorites_sync_processing_throttle">٪1$s\n\nيتم اختناق المزامنة حاليا (لتجنب حظرها من ExHentai) وقد يستغرق وقتا طويلا حتى يكتمل.</string> <string name="favorites_sync_processing_throttle">٪1$s\n\nيتم اختناق المزامنة حاليا (لتجنب حظرها من ExHentai) وقد يستغرق وقتا طويلا حتى يكتمل.</string>
<string name="favorites_sync_notes">ملاحظات مزامنة المفضلة الهامة</string> <string name="favorites_sync_notes">ملاحظات مزامنة المفضلة الهامة</string>
<string name="eh_batch_add_finish">إنهاء</string> <string name="eh_batch_add_finish">إنهاء</string>
<string name="favorites_sync_failed_to_add_to_local_error">\'%1$s\'%2$s</string>
<string name="rating9">رائع</string>
<string name="relation_alternate_story">قصة بديلة</string>
<string name="similar_titles">عناوين متشابهة</string>
<string name="mangadex_preffered_source">مصدر MangaDex المفضل</string>
<string name="mangadex_sync_follows_to_library">مزامنة مدخلات MangaDex في مكتبتك</string>
<string name="rating6">حسنا</string>
<string name="mangadex_push_favorites_to_mangadex">مزامنة إدخالات المكتبة مع MangaDex</string>
<string name="similar">مشابه ل%1$s</string>
<string name="relation_same_franchise">نفس الامتياز</string>
<string name="humanize_fallback">لحظات مضت</string>
<string name="random">عشوائي</string>
<string name="western">غرب</string>
<string name="could_not_open_entry">لا يمكن فتح هادا الإدخال:\n\n%1$s</string>
<string name="relation_based_on">مبني على</string>
<string name="relation_adapted_from">مأخود من</string>
<string name="game_cg">لعبة</string>
<string name="total_ratings">التقييم الكلي</string>
<string name="fetch_chapter_updates">البحث عن تحديثات الفصول</string>
<string name="no_dedupe">لا تكرار</string>
<string name="deduplication_mode">وضع إزالة التكرار:</string>
<string name="mangadex_add_to_follows">اضافة تتبع ل MangaDex</string>
<string name="mangadex_preffered_source_summary">قم بتعيين مصدر MangaDex الذي اخترته، وسيتم استخدامه للتتبع ومجموعة من الميزات الأخرى في التطبيق</string>
<string name="mangadex_sync_follows_to_library_summary">نقل إدخالات MangaDex إلى مكتبتك إذا لم تتم إضافتها بالفعل.</string>
<string name="mangadex_follows">متابعة MangaDex</string>
<string name="alt_titles">عناوين بديلة</string>
<string name="community_recommendations">اقتراحات المجتمع</string>
<string name="relation_similar">مشابه</string>
<string name="relation_shared_universe">كون مشترك</string>
<string name="relation_colored">ملون</string>
<string name="include_all_read_entries">يتضمن كل ما تم قرائته</string>
<string name="scan_qr_code">امسح الرمز</string>
<string name="error_with_reason">خطأ:%1$s</string>
<string name="launching_app">فتح التطبيق…</string>
<string name="rating8">رائع</string>
<string name="page_preview_page_go_to">ادخل إلى</string>
<string name="rating2">مؤلم</string>
<string name="no_rating">لا تقييم</string>
<string name="artist_cg">‬الفنان</string>
<string name="genre">النوع</string>
<string name="merged_toggle_download_chapters_error">خطأ في تنزيل الفصول</string>
<string name="merged_references_invalid">اندماج المراجع غير صالح</string>
<string name="dedupe_priority">إزالة التكرار حسب الأولوية</string>
<string name="allow_deduplication">سماح بالتكرار:</string>
<string name="dedupe_highest_chapter">اضهار المصدر صاحب أعلى عدد من الفصول</string>
<string name="dedupe_most_chapters">اضهار المصدر مع اكثر الفصول</string>
<string name="relation_preserialization">التسلسل المسبق</string>
<string name="rating0">كارثة</string>
<string name="deduplication_entry_info">معلومات عن الإدخال:</string>
<string name="merged_chapter_updates_error">خطأ تبديل تحديثات الفصل</string>
<string name="ignore_non_library_entries">تجاهل المدخلات التي لا تنتمي إلى الكتبة</string>
<string name="md_follows_unfollowed">إزالة المتابعة</string>
<string name="rating7">جيد</string>
<string name="loading_entry">جاري التحميل…</string>
<string name="rating4">سيئ</string>
<string name="page_previews">الصفحة السابقة</string>
<string name="misc">موسيقى</string>
<string name="video">‬فيديو</string>
<string name="more_info">المزيد من المعلومات</string>
<string name="alt_title">عنوان اضافي</string>
<string name="relation_side_story">قصة جانبية</string>
<string name="relation_main_story">القصة الأساسية</string>
<string name="relation_monochrome">أحادي اللون</string>
<string name="relation_sequel">تتمة</string>
<string name="relation_prequel">مقدمة</string>
<string name="relation_alternate_version">النسخ البديلة</string>
<string name="relation_serialization">التسلسل</string>
</resources> </resources>

View File

@ -628,4 +628,5 @@
<string name="rec_hide_library_entries">Ocultar elementos que ya estén en la biblioteca</string> <string name="rec_hide_library_entries">Ocultar elementos que ya estén en la biblioteca</string>
<string name="pref_tracker_resolve_using_source_metadata_summary">Encuentra el título automáticamente si la fuente ya enlaza con el servicio de seguimiento. De momento solo funciona en MangaDex</string> <string name="pref_tracker_resolve_using_source_metadata_summary">Encuentra el título automáticamente si la fuente ya enlaza con el servicio de seguimiento. De momento solo funciona en MangaDex</string>
<string name="pref_tracker_resolve_using_source_metadata">Elegir títulos a través de los metadatos de la fuente</string> <string name="pref_tracker_resolve_using_source_metadata">Elegir títulos a través de los metadatos de la fuente</string>
<string name="scan_qr_code">Escanear un código QR</string>
</resources> </resources>

View File

@ -646,4 +646,5 @@
<string name="rec_processing_state">Pinoprosesong entry %1$d ng %2$d</string> <string name="rec_processing_state">Pinoprosesong entry %1$d ng %2$d</string>
<string name="rec_collecting">Nangongolekta ng mga rekomendasyon</string> <string name="rec_collecting">Nangongolekta ng mga rekomendasyon</string>
<string name="rec_initializing">Sinisimulan</string> <string name="rec_initializing">Sinisimulan</string>
<string name="scan_qr_code">Mag-scan ng QR code</string>
</resources> </resources>

View File

@ -159,7 +159,7 @@
<string name="library_group_updates_all_but_ungrouped">Jalankan pembaruan global hanya untuk yang tidak dikelompokkan, pembaruan kategori untuk yang lainnya</string> <string name="library_group_updates_all_but_ungrouped">Jalankan pembaruan global hanya untuk yang tidak dikelompokkan, pembaruan kategori untuk yang lainnya</string>
<string name="library_group_updates_all">Hanya jalankan pembaruan kategori</string> <string name="library_group_updates_all">Hanya jalankan pembaruan kategori</string>
<!-- Browse settings --> <!-- Browse settings -->
<string name="pref_source_source_filtering">Filter Sumber dalam kategori</string> <string name="pref_source_source_filtering">Filter sumber dalam kategori</string>
<string name="pref_source_source_filtering_summery">Saring sumber-sumber yang ada dalam kategori, agar sumber-sumber tersebut tidak dimasukkan ke dalam kategori bahasa jika berada dalam suatu kategori</string> <string name="pref_source_source_filtering_summery">Saring sumber-sumber yang ada dalam kategori, agar sumber-sumber tersebut tidak dimasukkan ke dalam kategori bahasa jika berada dalam suatu kategori</string>
<string name="pref_source_navigation">Ganti tombol Terbaru</string> <string name="pref_source_navigation">Ganti tombol Terbaru</string>
<string name="pref_source_navigation_summery">Ganti tombol Terbaru dengan tampilan penelusuran khusus yang mencakup bab terbaru dan daftar manga</string> <string name="pref_source_navigation_summery">Ganti tombol Terbaru dengan tampilan penelusuran khusus yang mencakup bab terbaru dan daftar manga</string>
@ -539,7 +539,7 @@
<string name="pref_library_mark_duplicate_chapters">Tandai bagian baru yang sudah terbaca sebagai terbaca</string> <string name="pref_library_mark_duplicate_chapters">Tandai bagian baru yang sudah terbaca sebagai terbaca</string>
<string name="update_3hour">Setiap 3 jam</string> <string name="update_3hour">Setiap 3 jam</string>
<string name="label_triggers">Pemicu</string> <string name="label_triggers">Pemicu</string>
<string name="sync_complete">Berhasil Menyinkronkan perpustakaan</string> <string name="sync_complete">Berhasil menyinkronkan perpustakaan</string>
<string name="label_sync">Sinkronisasi</string> <string name="label_sync">Sinkronisasi</string>
<string name="pref_sync_host">Host</string> <string name="pref_sync_host">Host</string>
<string name="pref_sync_host_summ">Masukkan alamat host untuk menyinkronkan perpustakaan Anda</string> <string name="pref_sync_host_summ">Masukkan alamat host untuk menyinkronkan perpustakaan Anda</string>
@ -668,4 +668,5 @@
<string name="rec_processing_state">Memproses entri %1$d dari %2$d</string> <string name="rec_processing_state">Memproses entri %1$d dari %2$d</string>
<string name="rec_collecting">Mengumpulkan rekomendasi</string> <string name="rec_collecting">Mengumpulkan rekomendasi</string>
<string name="rec_initializing">Inisialisasi</string> <string name="rec_initializing">Inisialisasi</string>
<string name="scan_qr_code">Pindai kode QR</string>
</resources> </resources>

View File

@ -142,7 +142,7 @@
<string name="wsrv">wsrv.nl</string> <string name="wsrv">wsrv.nl</string>
<string name="bandwidth_data_saver_server">Bandwidth Hero Proxy Server</string> <string name="bandwidth_data_saver_server">Bandwidth Hero Proxy Server</string>
<string name="data_saver_server_summary">ここに Bandwidth Hero Proxy server のurlを入力して下さい</string> <string name="data_saver_server_summary">ここに Bandwidth Hero Proxy server のurlを入力して下さい</string>
<string name="clear_db_exclude_read">既読の章がある作品を保留</string> <string name="clear_db_exclude_read">既読の章がある作品は保持</string>
<!-- Log Level --> <!-- Log Level -->
<string name="log_minimal">最小</string> <string name="log_minimal">最小</string>
<string name="log_extra">最大</string> <string name="log_extra">最大</string>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="cleanup_done">
<item quantity="other">ရှင်းလင်းမှုပြီးပါပြီ။ %d ဖိုင်တွဲကို ဖယ်ရှားခဲ့သည်။</item>
</plurals>
</resources>

View File

@ -42,4 +42,5 @@
<string name="tag_filtering_threshhold_error">-9999 र 0 को बीचमा हुनुपर्छ!</string> <string name="tag_filtering_threshhold_error">-9999 र 0 को बीचमा हुनुपर्छ!</string>
<string name="artist">कलाकार</string> <string name="artist">कलाकार</string>
<string name="author">लेखक</string> <string name="author">लेखक</string>
<string name="clear_db_exclude_read">अध्याय पढिएका इन्ट्रीहरू राख्नुहोस्</string>
</resources> </resources>

View File

@ -634,4 +634,22 @@
<string name="delete_tag">Excluir tag</string> <string name="delete_tag">Excluir tag</string>
<string name="too_many_in_feed">Muitas fontes no seu feed, não é possível adicionar mais de 10</string> <string name="too_many_in_feed">Muitas fontes no seu feed, não é possível adicionar mais de 10</string>
<string name="action_stop">Parar</string> <string name="action_stop">Parar</string>
<string name="rec_services_to_search">Serviços de recomendação para busca</string>
<string name="rec_hide_library_entries">Ocultar resultados já existentes em sua biblioteca</string>
<string name="scan_qr_code">Escanear um código QR</string>
<string name="rec_search">Encontre recomendações comuns</string>
<string name="rec_group_source">Recomendações de fontes</string>
<string name="rec_group_tracker">Recomendações do rastreador</string>
<string name="rec_common_recommendations">Recomendações comuns</string>
<string name="rec_search_short">Encontre recomendações</string>
<string name="rec_error_title">Falha na busca</string>
<string name="rec_error_string">Ocorreu um erro durante o processo de busca: %1$s</string>
<string name="rec_collecting">Coletando recomendações</string>
<string name="rec_initializing">Inicializando</string>
<string name="similar_titles">Títulos similares</string>
<string name="relation_sequel">Sequência</string>
<string name="feed">Feed</string>
<string name="rec_no_results">Nenhuma recomendação encontrada</string>
<string name="failed_merge">Falha ao mesclar a entrada: %1$s</string>
<string name="select_tracker">Selecione um rastreador</string>
</resources> </resources>

View File

@ -261,7 +261,7 @@
<string name="download_threads">Потоки загрузки</string> <string name="download_threads">Потоки загрузки</string>
<string name="download_threads_summary">Более высокие значения могут значительно ускорить загрузку изображений, но также могут спровоцировать блокировку источников для TachiyomiSY. Рекомендуемое значение - 2 или 3. Текущее значение: %s</string> <string name="download_threads_summary">Более высокие значения могут значительно ускорить загрузку изображений, но также могут спровоцировать блокировку источников для TachiyomiSY. Рекомендуемое значение - 2 или 3. Текущее значение: %s</string>
<string name="aggressively_load_pages">Агрессивная загрузка страниц</string> <string name="aggressively_load_pages">Агрессивная загрузка страниц</string>
<string name="aggressively_load_pages_summary">Медленно загружать всю главу во время чтения вместо загрузки в текущий момент просматреваемых страниц</string> <string name="aggressively_load_pages_summary">Медленно загружать всю главу во время чтения вместо загрузки в текущий момент просматреваемых страниц.</string>
<string name="skip_queue_on_retry">Пропускать очередь при повторной попытке</string> <string name="skip_queue_on_retry">Пропускать очередь при повторной попытке</string>
<string name="skip_queue_on_retry_summary">Обычно нажатие кнопки «Повторить» при неудачной загрузке будет ждать, пока загрузчик закончит загрузку последней страницы, прежде чем начать перезагрузку неудачной страницы. Включение этого режима заставит загрузчик немедленно начать перезагрузку неудачной страницы, как только будет нажата кнопка «Повторить».</string> <string name="skip_queue_on_retry_summary">Обычно нажатие кнопки «Повторить» при неудачной загрузке будет ждать, пока загрузчик закончит загрузку последней страницы, прежде чем начать перезагрузку неудачной страницы. Включение этого режима заставит загрузчик немедленно начать перезагрузку неудачной страницы, как только будет нажата кнопка «Повторить».</string>
<string name="reader_preload_amount">Количество страниц с предзагрузкой</string> <string name="reader_preload_amount">Количество страниц с предзагрузкой</string>
@ -671,7 +671,7 @@
<string name="alt_titles">Альт. названия</string> <string name="alt_titles">Альт. названия</string>
<string name="select_tracker">Выбрать сервис отслеживания</string> <string name="select_tracker">Выбрать сервис отслеживания</string>
<string name="fill_from_tracker">Заполнить из сервиса</string> <string name="fill_from_tracker">Заполнить из сервиса</string>
<string name="entry_not_tracked">Введённая запись не является сервисом отслеживания</string> <string name="entry_not_tracked">Введённая запись не является сервисом отслеживания.</string>
<string name="favorites_sync_unable_to_add_to_remote">Невозможно добавить галерею на удалённый сервер: \'%1$s\' (GID: %2$s)!</string> <string name="favorites_sync_unable_to_add_to_remote">Невозможно добавить галерею на удалённый сервер: \'%1$s\' (GID: %2$s)!</string>
<string name="similar_titles">Похожие имена</string> <string name="similar_titles">Похожие имена</string>
<string name="rec_hide_library_entries">Скрыть серии которые находятся в библиотеке</string> <string name="rec_hide_library_entries">Скрыть серии которые находятся в библиотеке</string>
@ -689,4 +689,5 @@
<string name="rec_search">Найти общие рекомендации</string> <string name="rec_search">Найти общие рекомендации</string>
<string name="rec_initializing">Идёт подготовка</string> <string name="rec_initializing">Идёт подготовка</string>
<string name="rec_common_recommendations">Общие рекомендации</string> <string name="rec_common_recommendations">Общие рекомендации</string>
<string name="scan_qr_code">Сканировать QR-код</string>
</resources> </resources>

View File

@ -62,7 +62,7 @@
<string name="pref_enhanced_e_hentai_view_summary">E/ExHentai için gelişmiş arama menüsü modunu açın/kapatın</string> <string name="pref_enhanced_e_hentai_view_summary">E/ExHentai için gelişmiş arama menüsü modunu açın/kapatın</string>
<string name="favorites_sync">E-Hentai Favorileri eşitleme</string> <string name="favorites_sync">E-Hentai Favorileri eşitleme</string>
<string name="disable_favorites_uploading">Favorilerin gönderilmesini kapat</string> <string name="disable_favorites_uploading">Favorilerin gönderilmesini kapat</string>
<string name="disable_favorites_uploading_summary">Favoriler yalnızca ExHentai üzerinden indirilir. Uygulama favorilere yapılan değişiklikler gönderilmeyecektir. ExHentai üzerinde favorilerin yanlışlıkla kaybolmasını önler. Silinenlerin yine de indirileceğini unutmayın (ExHentai üzerinde bir favoriyi silersemiz uygulamada da silinecektir).</string> <string name="disable_favorites_uploading_summary">Favoriler yalnızca ExHentai üzerinden indirilir. Uygulamada favorilere yapılan değişiklikler gönderilmeyecektir. ExHentai üzerinde favorilerin yanlışlıkla kaybolmasını önler. Silinenlerin yine de indirileceğini unutmayın (ExHentai üzerinde bir favoriyi silerseniz uygulamada da silinecektir).</string>
<string name="show_favorite_sync_notes">Favorilerin eşitleme notlarını göster</string> <string name="show_favorite_sync_notes">Favorilerin eşitleme notlarını göster</string>
<string name="show_favorite_sync_notes_summary">Favori eşitleme özelliği ile ilgili çeşitli bilgiler gösterir</string> <string name="show_favorite_sync_notes_summary">Favori eşitleme özelliği ile ilgili çeşitli bilgiler gösterir</string>
<string name="please_login">Lütfen giriş yapın!</string> <string name="please_login">Lütfen giriş yapın!</string>
@ -112,7 +112,7 @@
<string name="log_level_summary">Bunu değiştirmek uygulama performansını etkileyebilir. Değiştirdikten sonra uygulamayı yeniden başlatın. Şu anki değer: %s</string> <string name="log_level_summary">Bunu değiştirmek uygulama performansını etkileyebilir. Değiştirdikten sonra uygulamayı yeniden başlatın. Şu anki değer: %s</string>
<string name="enable_source_blacklist">Kaynak kara listesini etkinleştir</string> <string name="enable_source_blacklist">Kaynak kara listesini etkinleştir</string>
<string name="enable_source_blacklist_summary">%1$s ile uyumsuz uzantıları/kaynakları gizle. Değiştirdikten sonra uygulamayı yeniden başlatın.</string> <string name="enable_source_blacklist_summary">%1$s ile uyumsuz uzantıları/kaynakları gizle. Değiştirdikten sonra uygulamayı yeniden başlatın.</string>
<string name="open_debug_menu_summary"><![CDATA[NE YAPTIĞINIZI BİLMİYORSANIZ BU MENÜYE DOKUNMAYIN! <font color=\'red\'>KİTAPLIPINIZI KULLANILMAZ YAPABİLİR!</font>]]></string> <string name="open_debug_menu_summary"><![CDATA[NE YAPTIĞINIZI BİLMİYORSANIZ BU MENÜYE DOKUNMAYIN! <font color=\'red\'>KİTAPLIĞINIZI KULLANILMAZ YAPABİLİR!</font>]]></string>
<string name="starting_cleanup">Temizleme başlatılıyor</string> <string name="starting_cleanup">Temizleme başlatılıyor</string>
<string name="delete_unused_chapters">Var olmayan, yarım yüklenmiş veya okunmuş bölümleri silin</string> <string name="delete_unused_chapters">Var olmayan, yarım yüklenmiş veya okunmuş bölümleri silin</string>
<string name="no_folders_to_cleanup">Temizlenecek klasör yok</string> <string name="no_folders_to_cleanup">Temizlenecek klasör yok</string>
@ -261,7 +261,7 @@
<string name="reader_preload_amount_16_pages">16 sayfa</string> <string name="reader_preload_amount_16_pages">16 sayfa</string>
<string name="reader_preload_amount_20_pages">20 sayfa</string> <string name="reader_preload_amount_20_pages">20 sayfa</string>
<string name="reader_cache_size">Okuyucu önbellek boyutu</string> <string name="reader_cache_size">Okuyucu önbellek boyutu</string>
<string name="reader_cache_size_summary">Okurken cihazda kaydedilecek görsel sayısı. Daha yüksek değerler daha rahat bir okuma deneyimi sağlar ancak kullanılan disk alanını artırır</string> <string name="reader_cache_size_summary">Okurken cihazda kaydedilecek görsel miktarı. Daha yüksek değerler daha rahat bir okuma deneyimi sağlar ancak kullanılan disk alanını artırır</string>
<string name="preserve_reading_position">Okunmuş girdilerde okuma konumunu koru</string> <string name="preserve_reading_position">Okunmuş girdilerde okuma konumunu koru</string>
<string name="auto_webtoon_mode">Otomatik Webtoon Modu</string> <string name="auto_webtoon_mode">Otomatik Webtoon Modu</string>
<string name="auto_webtoon_mode_summary">Muhtemelen uzun şerit formatını kullandığı algılanan girdiler için otomatik webtoon modunu kullan</string> <string name="auto_webtoon_mode_summary">Muhtemelen uzun şerit formatını kullandığı algılanan girdiler için otomatik webtoon modunu kullan</string>
@ -619,4 +619,5 @@
<string name="rec_processing_state">%2$d girdiden %1$d. girdi işleniyor</string> <string name="rec_processing_state">%2$d girdiden %1$d. girdi işleniyor</string>
<string name="rec_collecting">Öneriler toplanıyor</string> <string name="rec_collecting">Öneriler toplanıyor</string>
<string name="rec_initializing">Başlatılıyor</string> <string name="rec_initializing">Başlatılıyor</string>
<string name="scan_qr_code">QR kod tarayın</string>
</resources> </resources>

View File

@ -39,7 +39,7 @@ dependencyResolutionManagement {
} }
plugins { plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.10.0" id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
} }
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

View File

@ -28,6 +28,7 @@ class NHentaiSearchMetadata : RaisedSearchMetadata() {
var favoritesCount: Long? = null var favoritesCount: Long? = null
var mediaId: String? = null var mediaId: String? = null
var mediaServer: Int? = null
var japaneseTitle by titleDelegate(TITLE_TYPE_JAPANESE) var japaneseTitle by titleDelegate(TITLE_TYPE_JAPANESE)
var englishTitle by titleDelegate(TITLE_TYPE_ENGLISH) var englishTitle by titleDelegate(TITLE_TYPE_ENGLISH)
@ -46,7 +47,7 @@ class NHentaiSearchMetadata : RaisedSearchMetadata() {
val cover = if (mediaId != null) { val cover = if (mediaId != null) {
typeToExtension(coverImageType)?.let { typeToExtension(coverImageType)?.let {
"https://t1.nhentai.net/galleries/$mediaId/cover.$it" "https://t${mediaServer ?: 1}.nhentai.net/galleries/$mediaId/cover.$it"
} }
} else { } else {
null null