Address more spotless lint errors from KMK & SY

This commit is contained in:
Cuong-Tran 2024-08-22 18:27:02 +07:00
parent e7ca892f65
commit 48d874342e
No known key found for this signature in database
GPG key ID: 733AA7624B9315C2
119 changed files with 637 additions and 380 deletions

View file

@ -32,10 +32,11 @@ class GetEnabledSources(
) { a, b, c -> Triple(a, b, c) }, ) { a, b, c -> Triple(a, b, c) },
// SY <-- // SY <--
repository.getSources(), repository.getSources(),
) { pinnedSourceIds, ) {
(enabledLanguages, disabledSources, lastUsedSource), pinnedSourceIds,
(excludedFromDataSaver, sourcesInCategories, sourceCategoriesFilter), (enabledLanguages, disabledSources, lastUsedSource),
sources, (excludedFromDataSaver, sourcesInCategories, sourceCategoriesFilter),
sources,
-> ->
val sourcesAndCategories = sourcesInCategories.map { val sourcesAndCategories = sourcesInCategories.map {

View file

@ -58,7 +58,7 @@ class SyncPreferences(
// SY --> // SY -->
customInfo = preferenceStore.getBoolean("customInfo", true).get(), customInfo = preferenceStore.getBoolean("customInfo", true).get(),
readEntries = preferenceStore.getBoolean("readEntries", true).get() readEntries = preferenceStore.getBoolean("readEntries", true).get(),
// SY <-- // SY <--
) )
} }

View file

@ -12,6 +12,6 @@ data class SyncSettings(
// SY --> // SY -->
val customInfo: Boolean = true, val customInfo: Boolean = true,
val readEntries: Boolean = true val readEntries: Boolean = true,
// SY <-- // SY <--
) )

View file

@ -72,7 +72,7 @@ private fun ExtensionFilterContent(
contentPadding = contentPadding, contentPadding = contentPadding,
// KMK --> // KMK -->
modifier = Modifier modifier = Modifier
.padding(start = MaterialTheme.padding.small) .padding(start = MaterialTheme.padding.small),
// KMK <-- // KMK <--
) { ) {
items(state.languages) { language -> items(state.languages) { language ->
@ -87,7 +87,7 @@ private fun ExtensionFilterContent(
contentDescription = language, contentDescription = language,
modifier = Modifier modifier = Modifier
.width(48.dp) .width(48.dp)
.height(32.dp) .height(32.dp),
) )
// KMK <-- // KMK <--
SwitchPreferenceWidget( SwitchPreferenceWidget(

View file

@ -376,7 +376,7 @@ private fun ExtensionItemContent(
contentDescription = extension.lang ?: "", contentDescription = extension.lang ?: "",
modifier = Modifier modifier = Modifier
.width(18.dp) .width(18.dp)
.height(12.dp) .height(12.dp),
) )
// KMK <-- // KMK <--
Text( Text(

View file

@ -127,7 +127,7 @@ internal fun GlobalSearchContent(
"", "",
"", "",
supportsLatest = false, supportsLatest = false,
isStub = false isStub = false,
) )
// KMK <-- // KMK <--

View file

@ -266,7 +266,7 @@ private fun MigrateSourceItem(
contentDescription = lang, contentDescription = lang,
modifier = Modifier modifier = Modifier
.width(18.dp) .width(18.dp)
.height(12.dp) .height(12.dp),
) )
// KMK <-- // KMK <--
Text( Text(

View file

@ -304,12 +304,12 @@ fun SourceFeedToolbar(
AppBarActions( AppBarActions(
actions = persistentListOf( actions = persistentListOf(
bulkSelectionButton(toggleSelectionMode), bulkSelectionButton(toggleSelectionMode),
) ),
) )
persistentListOf( persistentListOf(
if (sourceId != LocalSource.ID) { if (sourceId != LocalSource.ID) {
IconButton( IconButton(
onClick = onWebViewClick onClick = onWebViewClick,
) { ) {
Icon( Icon(
imageVector = Icons.Outlined.Public, imageVector = Icons.Outlined.Public,

View file

@ -280,7 +280,7 @@ fun SourcesSearch(
), ),
contentPadding = PaddingValues(12.dp), contentPadding = PaddingValues(12.dp),
) )
} },
) )
} }
@ -474,7 +474,8 @@ fun SourceOptionsDialog(
} }
// SY <-- // SY <--
// KMK --> // KMK -->
if (onClickSettings != null && source.installedExtension !== null && if (onClickSettings != null &&
source.installedExtension !== null &&
source.id !in listOf(LocalSource.ID, EH_SOURCE_ID, EXH_SOURCE_ID) source.id !in listOf(LocalSource.ID, EH_SOURCE_ID, EXH_SOURCE_ID)
) { ) {
Text( Text(

View file

@ -104,7 +104,7 @@ private val defaultContent: @Composable RowScope.(
contentDescription = lang, contentDescription = lang,
modifier = Modifier modifier = Modifier
.width(18.dp) .width(18.dp)
.height(12.dp) .height(12.dp),
) )
// KMK <-- // KMK <--
Text( Text(

View file

@ -66,7 +66,7 @@ fun GlobalSearchToolbar(
AppBarActions( AppBarActions(
actions = persistentListOf( actions = persistentListOf(
bulkSelectionButton(toggleSelectionMode), bulkSelectionButton(toggleSelectionMode),
) ),
) )
}, },
// KMK <-- // KMK <--

View file

@ -20,7 +20,7 @@ import tachiyomi.source.local.LocalSource
@Composable @Composable
fun SourceSettingsButton( fun SourceSettingsButton(
id: Long, id: Long,
@Suppress("UNUSED_PARAMETER") modifier: Modifier = Modifier @Suppress("UNUSED_PARAMETER") modifier: Modifier = Modifier,
) { ) {
// Create a fake source // Create a fake source
val source = Source(id, "", "", supportsLatest = false, isStub = false) val source = Source(id, "", "", supportsLatest = false, isStub = false)
@ -30,7 +30,7 @@ fun SourceSettingsButton(
@Composable @Composable
fun SourceSettingsButton( fun SourceSettingsButton(
source: Source, source: Source,
@Suppress("UNUSED_PARAMETER") modifier: Modifier = Modifier @Suppress("UNUSED_PARAMETER") modifier: Modifier = Modifier,
) { ) {
// Avoid E-Hentai & ExHentai which is built-in & not actually installed extensions // Avoid E-Hentai & ExHentai which is built-in & not actually installed extensions
if (source.id == LocalSource.ID || source.id == EH_SOURCE_ID || source.id == EXH_SOURCE_ID) return if (source.id == LocalSource.ID || source.id == EH_SOURCE_ID || source.id == EXH_SOURCE_ID) return

View file

@ -520,7 +520,7 @@ private fun MangaScreenSmallImpl(
style = HazeStyle( style = HazeStyle(
tint = HazeDefaults.tint(fullCoverBackground), tint = HazeDefaults.tint(fullCoverBackground),
blurRadius = 10.dp, blurRadius = 10.dp,
) ),
), ),
// KMK <-- // KMK <--
) { contentPadding -> ) { contentPadding ->
@ -928,7 +928,7 @@ private fun MangaScreenLargeImpl(
style = HazeStyle( style = HazeStyle(
tint = HazeDefaults.tint(fullCoverBackground), tint = HazeDefaults.tint(fullCoverBackground),
blurRadius = 10.dp, blurRadius = 10.dp,
) ),
), ),
// KMK <-- // KMK <--
) { contentPadding -> ) { contentPadding ->
@ -1214,7 +1214,9 @@ private fun LazyListScope.sharedChapterItems(
// SY <-- // SY <--
}, },
readProgress = item.chapter.lastPageRead readProgress = item.chapter.lastPageRead
.takeIf { /* SY --> */(!item.chapter.read || alwaysShowReadingProgress)/* SY <-- */ && it > 0L } .takeIf {
/* SY --> */(!item.chapter.read || alwaysShowReadingProgress)/* SY <-- */ && it > 0L
}
?.let { ?.let {
stringResource( stringResource(
MR.strings.chapter_progress, MR.strings.chapter_progress,

View file

@ -152,7 +152,12 @@ fun MangaChapterListItem(
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
) )
if (readProgress != null || scanlator != null/* SY --> */ || sourceName != null/* SY <-- */) DotSeparatorText() if (readProgress != null ||
scanlator != null/* SY --> */ ||
sourceName != null/* SY <-- */
) {
DotSeparatorText()
}
} }
if (readProgress != null) { if (readProgress != null) {
Text( Text(

View file

@ -86,7 +86,7 @@ enum class MangaCover(val ratio: Float) {
// KMK --> // KMK -->
loading = { loading = {
Box( Box(
modifier = modifierColored modifier = modifierColored,
) { ) {
CircularProgressIndicator( CircularProgressIndicator(
color = tint?.let { Color(it) } ?: CoverPlaceholderOnBgColor, color = tint?.let { Color(it) } ?: CoverPlaceholderOnBgColor,
@ -96,7 +96,7 @@ enum class MangaCover(val ratio: Float) {
Size.Big -> 16.dp Size.Big -> 16.dp
Size.Medium -> 24.dp Size.Medium -> 24.dp
else -> 32.dp else -> 32.dp
} },
) )
.align(Alignment.Center), .align(Alignment.Center),
strokeWidth = when (size) { strokeWidth = when (size) {
@ -108,7 +108,7 @@ enum class MangaCover(val ratio: Float) {
}, },
error = { error = {
Box( Box(
modifier = modifierColored modifier = modifierColored,
) { ) {
Image( Image(
imageVector = ImageVector.vectorResource(R.drawable.cover_error_vector), imageVector = ImageVector.vectorResource(R.drawable.cover_error_vector),
@ -119,11 +119,11 @@ enum class MangaCover(val ratio: Float) {
Size.Big -> 16.dp Size.Big -> 16.dp
Size.Medium -> 24.dp Size.Medium -> 24.dp
else -> 32.dp else -> 32.dp
} },
) )
.align(Alignment.Center), .align(Alignment.Center),
colorFilter = ColorFilter.tint( colorFilter = ColorFilter.tint(
tint?.let { Color(it) } ?: CoverPlaceholderOnBgColor tint?.let { Color(it) } ?: CoverPlaceholderOnBgColor,
), ),
) )
} }
@ -178,7 +178,7 @@ enum class MangaCoverHide(private val ratio: Float) {
) )
Box( Box(
modifier = modifierColored modifier = modifierColored,
) { ) {
Image( Image(
imageVector = ImageVector.vectorResource(R.drawable.ic_baseline_menu_book_24), imageVector = ImageVector.vectorResource(R.drawable.ic_baseline_menu_book_24),
@ -187,7 +187,7 @@ enum class MangaCoverHide(private val ratio: Float) {
.size(32.dp) .size(32.dp)
.align(Alignment.Center), .align(Alignment.Center),
colorFilter = ColorFilter.tint( colorFilter = ColorFilter.tint(
tint?.let { Color(it) } ?: CoverPlaceholderOnBgColor tint?.let { Color(it) } ?: CoverPlaceholderOnBgColor,
), ),
) )
} }

View file

@ -104,7 +104,8 @@ fun MangaToolbar(
} }
// KMK --> // KMK -->
if (isHomeEnabled && navigator != null) { if (isHomeEnabled && navigator != null) {
if (navigator.size >= 2 && navigator.items[navigator.size - 2] is MangaScreen || if (navigator.size >= 2 &&
navigator.items[navigator.size - 2] is MangaScreen ||
navigator.size >= 5 navigator.size >= 5
) { ) {
IconButton(onClick = { onHomeClicked() }) { IconButton(onClick = { onHomeClicked() }) {

View file

@ -38,12 +38,12 @@ fun OutlinedButtonWithArrow(
vertical = MaterialTheme.padding.small, vertical = MaterialTheme.padding.small,
), ),
colors = ButtonDefaults.outlinedButtonColors(), colors = ButtonDefaults.outlinedButtonColors(),
shape = RoundedCornerShape(8.dp) shape = RoundedCornerShape(8.dp),
) { ) {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center, horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically,
) { ) {
Text( Text(
text = text, text = text,
@ -51,7 +51,7 @@ fun OutlinedButtonWithArrow(
Spacer(modifier = Modifier.width(4.dp)) Spacer(modifier = Modifier.width(4.dp))
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = "Arrow" contentDescription = "Arrow",
) )
} }
} }
@ -62,6 +62,6 @@ fun OutlinedButtonWithArrow(
fun OutlinedButtonWithArrowPreview() { fun OutlinedButtonWithArrowPreview() {
OutlinedButtonWithArrow( OutlinedButtonWithArrow(
text = "Click Me", text = "Click Me",
onClick = { /* Do nothing */ } onClick = { /* Do nothing */ },
) )
} }

View file

@ -44,7 +44,7 @@ import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
private fun PagePreviewLoading( private fun PagePreviewLoading(
setMaxWidth: (Dp) -> Unit setMaxWidth: (Dp) -> Unit,
) { ) {
val density = LocalDensity.current val density = LocalDensity.current
Box( Box(
@ -63,7 +63,7 @@ private fun PagePreviewLoading(
@Composable @Composable
private fun PagePreviewRow( private fun PagePreviewRow(
onOpenPage: (Int) -> Unit, onOpenPage: (Int) -> Unit,
items: ImmutableList<PagePreview> items: ImmutableList<PagePreview>,
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
@ -88,7 +88,7 @@ private fun PagePreviewMore(
) { ) {
Box( Box(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center,
) { ) {
TextButton(onClick = onMorePreviewsClicked) { TextButton(onClick = onMorePreviewsClicked) {
Text(stringResource(SYMR.strings.more_previews)) Text(stringResource(SYMR.strings.more_previews))
@ -116,7 +116,7 @@ fun PagePreviews(
pagePreviewState.pagePreviews.take(rowCount * itemPerRowCount).chunked(itemPerRowCount).forEach { pagePreviewState.pagePreviews.take(rowCount * itemPerRowCount).chunked(itemPerRowCount).forEach {
PagePreviewRow( PagePreviewRow(
onOpenPage = onOpenPage, onOpenPage = onOpenPage,
items = remember(it) { it.toImmutableList() } items = remember(it) { it.toImmutableList() },
) )
} }
@ -153,7 +153,7 @@ fun LazyListScope.PagePreviewItems(
) { ) {
PagePreviewRow( PagePreviewRow(
onOpenPage = onOpenPage, onOpenPage = onOpenPage,
items = remember(it) { it.toImmutableList() } items = remember(it) { it.toImmutableList() },
) )
} }
item( item(

View file

@ -46,7 +46,9 @@ fun RelatedMangasRow(
) )
} }
else -> { EmptyResultItem() } else -> {
EmptyResultItem()
}
} }
} }

View file

@ -263,11 +263,15 @@ object SettingsAppearanceScreen : SearchableSettings {
Preference.PreferenceItem.SliderPreference( Preference.PreferenceItem.SliderPreference(
value = previewsRowCount, value = previewsRowCount,
title = stringResource(SYMR.strings.pref_previews_row_count), title = stringResource(SYMR.strings.pref_previews_row_count),
subtitle = if (previewsRowCount > 0) pluralStringResource( subtitle = if (previewsRowCount > 0) {
SYMR.plurals.row_count, pluralStringResource(
previewsRowCount, SYMR.plurals.row_count,
previewsRowCount, previewsRowCount,
) else stringResource(MR.strings.disabled), previewsRowCount,
)
} else {
stringResource(MR.strings.disabled)
},
min = 0, min = 0,
max = 10, max = 10,
onValueChanged = { onValueChanged = {

View file

@ -102,7 +102,7 @@ object SettingsBrowseScreen : SearchableSettings {
pref = uiPreferences.feedTabInFront(), pref = uiPreferences.feedTabInFront(),
title = stringResource(SYMR.strings.pref_feed_position), title = stringResource(SYMR.strings.pref_feed_position),
subtitle = stringResource(SYMR.strings.pref_feed_position_summery), subtitle = stringResource(SYMR.strings.pref_feed_position_summery),
enabled = hideFeedTab.not() enabled = hideFeedTab.not(),
), ),
), ),
), ),

View file

@ -230,7 +230,7 @@ object AboutScreen : Screen() {
onPreferenceClick = { onPreferenceClick = {
uriHandler.openUri( uriHandler.openUri(
"https://crowdin.com/project/komikku/" + "https://crowdin.com/project/komikku/" +
"invite?h=f922abd4193e77309b084a08c74b89872112170" "invite?h=f922abd4193e77309b084a08c74b89872112170",
) )
}, },
) )

View file

@ -26,7 +26,6 @@ import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.components.LabeledCheckbox import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.components.LazyColumnWithAction import tachiyomi.presentation.core.components.LazyColumnWithAction
import tachiyomi.presentation.core.components.SectionCard import tachiyomi.presentation.core.components.SectionCard

View file

@ -63,7 +63,7 @@ fun ExhUtils(
modifier modifier
.fillMaxWidth() .fillMaxWidth()
.background(backgroundColor), .background(backgroundColor),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
AnimatedVisibility(visible = isVisible) { AnimatedVisibility(visible = isVisible) {
Column { Column {
@ -84,7 +84,7 @@ fun ExhUtils(
) { ) {
Column( Column(
Modifier.weight(3f), Modifier.weight(3f),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Text( Text(
text = stringResource(SYMR.strings.eh_autoscroll), text = stringResource(SYMR.strings.eh_autoscroll),
@ -93,17 +93,17 @@ fun ExhUtils(
fontFamily = FontFamily.SansSerif, fontFamily = FontFamily.SansSerif,
style = MaterialTheme.typography.labelLarge, style = MaterialTheme.typography.labelLarge,
modifier = Modifier.fillMaxWidth(0.75f), modifier = Modifier.fillMaxWidth(0.75f),
textAlign = TextAlign.Center textAlign = TextAlign.Center,
) )
} }
Column( Column(
Modifier.weight(1f), Modifier.weight(1f),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Switch( Switch(
checked = isAutoScroll, checked = isAutoScroll,
onCheckedChange = null, onCheckedChange = null,
enabled = isAutoScrollEnabled enabled = isAutoScrollEnabled,
) )
} }
} }
@ -114,7 +114,7 @@ fun ExhUtils(
) { ) {
Column( Column(
Modifier.weight(3f), Modifier.weight(3f),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
var autoScrollFrequencyState by remember { var autoScrollFrequencyState by remember {
mutableStateOf(autoScrollFrequency) mutableStateOf(autoScrollFrequency)

View file

@ -109,8 +109,10 @@ internal fun LazyListScope.updatesUiItems(
readProgress = updatesItem.update.lastPageRead readProgress = updatesItem.update.lastPageRead
.takeIf { .takeIf {
/* SY --> */( /* SY --> */(
!updatesItem.update.read || (preserveReadingPosition && updatesItem.isEhBasedUpdate()) !updatesItem.update.read ||
)/* SY <-- */ && it > 0L (preserveReadingPosition && updatesItem.isEhBasedUpdate())
)/* SY <-- */ &&
it > 0L
} }
?.let { ?.let {
stringResource( stringResource(

View file

@ -185,8 +185,7 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
val syncPreferences: SyncPreferences = Injekt.get() val syncPreferences: SyncPreferences = Injekt.get()
val syncTriggerOpt = syncPreferences.getSyncTriggerOptions() val syncTriggerOpt = syncPreferences.getSyncTriggerOptions()
if (syncPreferences.isSyncEnabled() && syncTriggerOpt.syncOnAppStart if (syncPreferences.isSyncEnabled() && syncTriggerOpt.syncOnAppStart) {
) {
SyncDataJob.startNow(this@App) SyncDataJob.startNow(this@App)
} }
@ -247,8 +246,7 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
val syncPreferences: SyncPreferences = Injekt.get() val syncPreferences: SyncPreferences = Injekt.get()
val syncTriggerOpt = syncPreferences.getSyncTriggerOptions() val syncTriggerOpt = syncPreferences.getSyncTriggerOptions()
if (syncPreferences.isSyncEnabled() && syncTriggerOpt.syncOnAppResume if (syncPreferences.isSyncEnabled() && syncTriggerOpt.syncOnAppResume) {
) {
SyncDataJob.startNow(this@App) SyncDataJob.startNow(this@App)
} }
} }

View file

@ -91,11 +91,11 @@ class BackupCreator(
} }
val databaseManga = getFavorites.await() /* SY --> */ + val databaseManga = getFavorites.await() /* SY --> */ +
if (options.readEntries) { if (options.readEntries) {
handler.awaitList { mangasQueries.getReadMangaNotInLibrary(MangaMapper::mapManga) } handler.awaitList { mangasQueries.getReadMangaNotInLibrary(MangaMapper::mapManga) }
} else { } else {
emptyList() emptyList()
} + getMergedManga.await() // SY <-- } + getMergedManga.await() // SY <--
val backupManga = backupMangas(databaseManga, options) val backupManga = backupMangas(databaseManga, options)
val backup = Backup( val backup = Backup(
backupManga = backupManga, backupManga = backupManga,

View file

@ -7,7 +7,7 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class FeedBackupCreator( class FeedBackupCreator(
private val handler: DatabaseHandler = Injekt.get() private val handler: DatabaseHandler = Injekt.get(),
) { ) {
/** /**

View file

@ -7,7 +7,7 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class SavedSearchBackupCreator( class SavedSearchBackupCreator(
private val handler: DatabaseHandler = Injekt.get() private val handler: DatabaseHandler = Injekt.get(),
) { ) {
suspend fun backupSavedSearches(): List<BackupSavedSearch> { suspend fun backupSavedSearches(): List<BackupSavedSearch> {

View file

@ -36,7 +36,8 @@ data class BackupMergedMangaReference(
} }
val backupMergedMangaReferenceMapper = val backupMergedMangaReferenceMapper =
{ _: Long, {
_: Long,
isInfoManga: Boolean, isInfoManga: Boolean,
getChapterUpdates: Boolean, getChapterUpdates: Boolean,
chapterSortMode: Long, chapterSortMode: Long,

View file

@ -53,7 +53,20 @@ data class BackupTracking(
} }
val backupTrackMapper = { val backupTrackMapper = {
_: Long, _: Long, syncId: Long, mediaId: Long, libraryId: Long?, title: String, lastChapterRead: Double, totalChapters: Long, status: Long, score: Double, remoteUrl: String, startDate: Long, finishDate: Long -> _: Long,
_: Long,
syncId: Long,
mediaId: Long,
libraryId: Long?,
title: String,
lastChapterRead: Double,
totalChapters: Long,
status: Long,
score: Double,
remoteUrl: String,
startDate: Long,
finishDate: Long,
->
BackupTracking( BackupTracking(
syncId = syncId.toInt(), syncId = syncId.toInt(),
mediaId = mediaId, mediaId = mediaId,

View file

@ -23,14 +23,17 @@ data class RestoreOptions(
extensionRepoSettings, extensionRepoSettings,
sourceSettings, sourceSettings,
// SY --> // SY -->
savedSearches savedSearches,
// SY <-- // SY <--
) )
fun canRestore() = libraryEntries || categories || appSettings || extensionRepoSettings || sourceSettings || fun canRestore() =
// SY --> libraryEntries ||
savedSearches categories ||
// SY <-- appSettings ||
extensionRepoSettings ||
sourceSettings /* SY --> */ ||
savedSearches /* SY <-- */
companion object { companion object {
val options = persistentListOf( val options = persistentListOf(
@ -75,7 +78,7 @@ data class RestoreOptions(
extensionRepoSettings = array[3], extensionRepoSettings = array[3],
sourceSettings = array[4], sourceSettings = array[4],
// SY --> // SY -->
savedSearches = array[5] savedSearches = array[5],
// SY <-- // SY <--
) )
} }

View file

@ -36,8 +36,8 @@ class ChapterCache(
private val context: Context, private val context: Context,
private val json: Json, private val json: Json,
// SY --> // SY -->
readerPreferences: ReaderPreferences readerPreferences: ReaderPreferences,
//S Y <-- // SY <--
) { ) {
// --> EH // --> EH

View file

@ -89,8 +89,11 @@ object MangaCoverMetadata {
val options = BitmapFactory.Options() val options = BitmapFactory.Options()
val updateColors = mangaCover.isMangaFavorite && mangaCover.dominantCoverColors == null || val updateColors = mangaCover.isMangaFavorite &&
!onlyDominantColor && mangaCover.vibrantCoverColor == null || force mangaCover.dominantCoverColors == null ||
!onlyDominantColor &&
mangaCover.vibrantCoverColor == null ||
force
if (updateColors) { if (updateColors) {
/** /**
@ -123,7 +126,9 @@ object MangaCoverMetadata {
bufferedSource != null -> BitmapFactory.decodeStream(bufferedSource.inputStream(), null, options) bufferedSource != null -> BitmapFactory.decodeStream(bufferedSource.inputStream(), null, options)
// if the file exists and the there was still an error then the file is corrupted // if the file exists and the there was still an error then the file is corrupted
file?.exists() == true -> BitmapFactory.decodeFile(file.path, options) file?.exists() == true -> BitmapFactory.decodeFile(file.path, options)
else -> { return } else -> {
return
}
} }
if (bitmap != null) { if (bitmap != null) {

View file

@ -57,7 +57,7 @@ class PagePreviewFetcher(
source = ImageSource( source = ImageSource(
file = file.toOkioPath(), file = file.toOkioPath(),
fileSystem = FileSystem.SYSTEM, fileSystem = FileSystem.SYSTEM,
diskCacheKey = diskCacheKey diskCacheKey = diskCacheKey,
), ),
mimeType = "image/*", mimeType = "image/*",
dataSource = DataSource.DISK, dataSource = DataSource.DISK,
@ -229,7 +229,7 @@ class PagePreviewFetcher(
file = data, file = data,
fileSystem = FileSystem.SYSTEM, fileSystem = FileSystem.SYSTEM,
diskCacheKey = diskCacheKey, diskCacheKey = diskCacheKey,
closeable = this closeable = this,
) )
} }

View file

@ -121,7 +121,8 @@ class DownloadProvider(
getValidChapterDirNames(chp.name, chp.scanlator).any { dir -> getValidChapterDirNames(chp.name, chp.scanlator).any { dir ->
mangaDir.findFile(dir) != null mangaDir.findFile(dir) != null
} }
} == null || it.name?.endsWith(Downloader.TMP_DIR_SUFFIX) == true } == null ||
it.name?.endsWith(Downloader.TMP_DIR_SUFFIX) == true
} }
} }
// SY <-- // SY <--

View file

@ -375,14 +375,17 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
async { async {
semaphore.withPermit { semaphore.withPermit {
if ( if (
mdlistLogged && mangaInSource.firstOrNull() mdlistLogged &&
mangaInSource.firstOrNull()
?.let { it.manga.source in mangaDexSourceIds } == true ?.let { it.manga.source in mangaDexSourceIds } == true
) { ) {
launch { launch {
mangaInSource.forEach { (manga) -> mangaInSource.forEach { (manga) ->
try { try {
val tracks = getTracks.await(manga.id) val tracks = getTracks.await(manga.id)
if (tracks.isEmpty() || tracks.none { it.trackerId == TrackerManager.MDLIST }) { if (tracks.isEmpty() ||
tracks.none { it.trackerId == TrackerManager.MDLIST }
) {
val track = mdList.createInitialTracker(manga) val track = mdList.createInitialTracker(manga)
insertTrack.await(mdList.refresh(track).toDomainTrack(false)!!) insertTrack.await(mdList.refresh(track).toDomainTrack(false)!!)
} }
@ -412,10 +415,14 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
// SY --> // SY -->
.sortedByDescending { it.sourceOrder }.run { .sortedByDescending { it.sourceOrder }.run {
if (libraryPreferences.libraryReadDuplicateChapters().get()) { if (libraryPreferences.libraryReadDuplicateChapters().get()) {
val readChapters = getChaptersByMangaId.await(manga.id).filter { it.read } val readChapters = getChaptersByMangaId.await(manga.id).filter {
it.read
}
val newReadChapters = this.filter { chapter -> val newReadChapters = this.filter { chapter ->
chapter.chapterNumber > 0 && chapter.chapterNumber > 0 &&
readChapters.any { it.chapterNumber == chapter.chapterNumber } readChapters.any {
it.chapterNumber == chapter.chapterNumber
}
} }
if (newReadChapters.isNotEmpty()) { if (newReadChapters.isNotEmpty()) {
@ -427,7 +434,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
this this
} }
} }
//SY <-- // SY <--
if (newChapters.isNotEmpty()) { if (newChapters.isNotEmpty()) {
val categoryIds = getCategories.await(manga.id).map { it.id } val categoryIds = getCategories.await(manga.id).map { it.id }

View file

@ -164,7 +164,9 @@ class GoogleDriveSyncService(context: Context, json: Json, syncPreferences: Sync
appProperties = mapOf("deviceId" to syncData.deviceId) appProperties = mapOf("deviceId" to syncData.deviceId)
} }
drive.files().update(fileId, fileMetadata, mediaContent).execute() drive.files().update(fileId, fileMetadata, mediaContent).execute()
logcat(LogPriority.DEBUG) { "Updated existing sync data file in Google Drive with file ID: $fileId" } logcat(LogPriority.DEBUG) {
"Updated existing sync data file in Google Drive with file ID: $fileId"
}
} else { } else {
val fileMetadata = File().apply { val fileMetadata = File().apply {
name = remoteFileName name = remoteFileName
@ -175,7 +177,9 @@ class GoogleDriveSyncService(context: Context, json: Json, syncPreferences: Sync
val uploadedFile = drive.files().create(fileMetadata, mediaContent) val uploadedFile = drive.files().create(fileMetadata, mediaContent)
.setFields("id") .setFields("id")
.execute() .execute()
logcat(LogPriority.DEBUG) { "Created new sync data file in Google Drive with file ID: ${uploadedFile.id}" } logcat(LogPriority.DEBUG) {
"Created new sync data file in Google Drive with file ID: ${uploadedFile.id}"
}
} }
} }
} }

View file

@ -26,7 +26,7 @@ abstract class SyncService(
val json: Json, val json: Json,
val syncPreferences: SyncPreferences, val syncPreferences: SyncPreferences,
) { ) {
abstract suspend fun doSync(syncData: SyncData): Backup?; abstract suspend fun doSync(syncData: SyncData): Backup?
/** /**
* Merges the local and remote sync data into a single JSON string. * Merges the local and remote sync data into a single JSON string.
@ -44,7 +44,8 @@ abstract class SyncService(
remoteSyncData.backup?.backupManga, remoteSyncData.backup?.backupManga,
localSyncData.backup?.backupCategories ?: emptyList(), localSyncData.backup?.backupCategories ?: emptyList(),
remoteSyncData.backup?.backupCategories ?: emptyList(), remoteSyncData.backup?.backupCategories ?: emptyList(),
mergedCategoriesList) mergedCategoriesList,
)
val mergedSourcesList = val mergedSourcesList =
mergeSourcesLists(localSyncData.backup?.backupSources, remoteSyncData.backup?.backupSources) mergeSourcesLists(localSyncData.backup?.backupSources, remoteSyncData.backup?.backupSources)
@ -120,11 +121,13 @@ abstract class SyncService(
val mergedCategoriesMapByName = mergedCategories.associateBy { it.name } val mergedCategoriesMapByName = mergedCategories.associateBy { it.name }
fun updateCategories(theManga: BackupManga, theMap: Map<Long, BackupCategory>): BackupManga { fun updateCategories(theManga: BackupManga, theMap: Map<Long, BackupCategory>): BackupManga {
return theManga.copy(categories = theManga.categories.mapNotNull { return theManga.copy(
theMap[it]?.let { category -> categories = theManga.categories.mapNotNull {
mergedCategoriesMapByName[category.name]?.order theMap[it]?.let { category ->
} mergedCategoriesMapByName[category.name]?.order
}) }
},
)
} }
logcat(LogPriority.DEBUG, logTag) { logcat(LogPriority.DEBUG, logTag) {
@ -147,7 +150,7 @@ abstract class SyncService(
} }
updateCategories( updateCategories(
local.copy(chapters = mergeChapters(local.chapters, remote.chapters)), local.copy(chapters = mergeChapters(local.chapters, remote.chapters)),
localCategoriesMapByOrder localCategoriesMapByOrder,
) )
} else { } else {
logcat(LogPriority.DEBUG, logTag) { logcat(LogPriority.DEBUG, logTag) {
@ -155,7 +158,7 @@ abstract class SyncService(
} }
updateCategories( updateCategories(
remote.copy(chapters = mergeChapters(local.chapters, remote.chapters)), remote.copy(chapters = mergeChapters(local.chapters, remote.chapters)),
remoteCategoriesMapByOrder remoteCategoriesMapByOrder,
) )
} }
} }
@ -301,7 +304,7 @@ abstract class SyncService(
private fun mergeSourcesLists( private fun mergeSourcesLists(
localSources: List<BackupSource>?, localSources: List<BackupSource>?,
remoteSources: List<BackupSource>? remoteSources: List<BackupSource>?,
): List<BackupSource> { ): List<BackupSource> {
val logTag = "MergeSources" val logTag = "MergeSources"
@ -346,7 +349,7 @@ abstract class SyncService(
private fun mergePreferencesLists( private fun mergePreferencesLists(
localPreferences: List<BackupPreference>?, localPreferences: List<BackupPreference>?,
remotePreferences: List<BackupPreference>? remotePreferences: List<BackupPreference>?,
): List<BackupPreference> { ): List<BackupPreference> {
val logTag = "MergePreferences" val logTag = "MergePreferences"
@ -394,7 +397,7 @@ abstract class SyncService(
private fun mergeSourcePreferencesLists( private fun mergeSourcePreferencesLists(
localPreferences: List<BackupSourcePreferences>?, localPreferences: List<BackupSourcePreferences>?,
remotePreferences: List<BackupSourcePreferences>? remotePreferences: List<BackupSourcePreferences>?,
): List<BackupSourcePreferences> { ): List<BackupSourcePreferences> {
val logTag = "MergeSourcePreferences" val logTag = "MergeSourcePreferences"
@ -408,38 +411,39 @@ abstract class SyncService(
} }
// Merge both source preferences maps // Merge both source preferences maps
val mergedSourcePreferences = (localPreferencesMap.keys + remotePreferencesMap.keys).distinct().mapNotNull { sourceKey -> val mergedSourcePreferences = (localPreferencesMap.keys + remotePreferencesMap.keys).distinct()
val localSourcePreference = localPreferencesMap[sourceKey] .mapNotNull { sourceKey ->
val remoteSourcePreference = remotePreferencesMap[sourceKey] val localSourcePreference = localPreferencesMap[sourceKey]
val remoteSourcePreference = remotePreferencesMap[sourceKey]
logcat(LogPriority.DEBUG, logTag) { logcat(LogPriority.DEBUG, logTag) {
"Processing source preference key: $sourceKey. " + "Processing source preference key: $sourceKey. " +
"Local source preference: ${localSourcePreference != null}, " + "Local source preference: ${localSourcePreference != null}, " +
"Remote source preference: ${remoteSourcePreference != null}" "Remote source preference: ${remoteSourcePreference != null}"
} }
when { when {
localSourcePreference != null && remoteSourcePreference == null -> { localSourcePreference != null && remoteSourcePreference == null -> {
logcat(LogPriority.DEBUG, logTag) { logcat(LogPriority.DEBUG, logTag) {
"Using local source preference: ${localSourcePreference.sourceKey}." "Using local source preference: ${localSourcePreference.sourceKey}."
}
localSourcePreference
} }
localSourcePreference remoteSourcePreference != null && localSourcePreference == null -> {
} logcat(LogPriority.DEBUG, logTag) {
remoteSourcePreference != null && localSourcePreference == null -> { "Using remote source preference: ${remoteSourcePreference.sourceKey}."
logcat(LogPriority.DEBUG, logTag) { }
"Using remote source preference: ${remoteSourcePreference.sourceKey}." remoteSourcePreference
} }
remoteSourcePreference localSourcePreference != null && remoteSourcePreference != null -> {
// Merge the individual preferences within the source preferences
val mergedPrefs =
mergeIndividualPreferences(localSourcePreference.prefs, remoteSourcePreference.prefs)
BackupSourcePreferences(sourceKey, mergedPrefs)
}
else -> null
} }
localSourcePreference != null && remoteSourcePreference != null -> {
// Merge the individual preferences within the source preferences
val mergedPrefs =
mergeIndividualPreferences(localSourcePreference.prefs, remoteSourcePreference.prefs)
BackupSourcePreferences(sourceKey, mergedPrefs)
}
else -> null
} }
}
logcat(LogPriority.DEBUG, logTag) { logcat(LogPriority.DEBUG, logTag) {
"Source preferences merge completed. Total merged source preferences: ${mergedSourcePreferences.size}" "Source preferences merge completed. Total merged source preferences: ${mergedSourcePreferences.size}"
@ -450,7 +454,7 @@ abstract class SyncService(
private fun mergeIndividualPreferences( private fun mergeIndividualPreferences(
localPrefs: List<BackupPreference>, localPrefs: List<BackupPreference>,
remotePrefs: List<BackupPreference> remotePrefs: List<BackupPreference>,
): List<BackupPreference> { ): List<BackupPreference> {
val mergedPrefsMap = (localPrefs + remotePrefs).associateBy { it.key } val mergedPrefsMap = (localPrefs + remotePrefs).associateBy { it.key }
return mergedPrefsMap.values.toList() return mergedPrefsMap.values.toList()
@ -459,7 +463,7 @@ abstract class SyncService(
// SY --> // SY -->
private fun mergeSavedSearchesLists( private fun mergeSavedSearchesLists(
localSearches: List<BackupSavedSearch>?, localSearches: List<BackupSavedSearch>?,
remoteSearches: List<BackupSavedSearch>? remoteSearches: List<BackupSavedSearch>?,
): List<BackupSavedSearch> { ): List<BackupSavedSearch> {
val logTag = "MergeSavedSearches" val logTag = "MergeSavedSearches"

View file

@ -38,7 +38,7 @@ class SyncYomiSyncService(
try { try {
val (remoteData, etag) = pullSyncData() val (remoteData, etag) = pullSyncData()
val finalSyncData = if (remoteData != null){ val finalSyncData = if (remoteData != null) {
assert(etag.isNotEmpty()) { "ETag should never be empty if remote data is not null" } assert(etag.isNotEmpty()) { "ETag should never be empty if remote data is not null" }
logcat(LogPriority.DEBUG, "SyncService") { logcat(LogPriority.DEBUG, "SyncService") {
"Try update remote data with ETag($etag)" "Try update remote data with ETag($etag)"
@ -54,7 +54,6 @@ class SyncYomiSyncService(
pushSyncData(finalSyncData, etag) pushSyncData(finalSyncData, etag)
return finalSyncData.backup return finalSyncData.backup
} catch (e: Exception) { } catch (e: Exception) {
logcat(LogPriority.ERROR) { "Error syncing: ${e.message}" } logcat(LogPriority.ERROR) { "Error syncing: ${e.message}" }
notifier.showSyncError(e.message) notifier.showSyncError(e.message)
@ -113,7 +112,6 @@ class SyncYomiSyncService(
// return default value so we can overwrite it // return default value so we can overwrite it
Pair(null, "") Pair(null, "")
} }
} else { } else {
val responseBody = response.body.string() val responseBody = response.body.string()
notifier.showSyncError("Failed to download sync data: $responseBody") notifier.showSyncError("Failed to download sync data: $responseBody")
@ -165,11 +163,9 @@ class SyncYomiSyncService(
.takeIf { it?.isNotEmpty() == true } ?: throw SyncYomiException("Missing ETag") .takeIf { it?.isNotEmpty() == true } ?: throw SyncYomiException("Missing ETag")
syncPreferences.lastSyncEtag().set(newETag) syncPreferences.lastSyncEtag().set(newETag)
logcat(LogPriority.DEBUG) { "SyncYomi sync completed" } logcat(LogPriority.DEBUG) { "SyncYomi sync completed" }
} else if (response.code == HttpStatus.SC_PRECONDITION_FAILED) { } else if (response.code == HttpStatus.SC_PRECONDITION_FAILED) {
// other clients updated remote data, will try next time // other clients updated remote data, will try next time
logcat(LogPriority.DEBUG) { "SyncYomi sync failed with 412" } logcat(LogPriority.DEBUG) { "SyncYomi sync failed with 412" }
} else { } else {
val responseBody = response.body.string() val responseBody = response.body.string()
notifier.showSyncError("Failed to upload sync data: $responseBody") notifier.showSyncError("Failed to upload sync data: $responseBody")

View file

@ -73,6 +73,7 @@ class ExtensionManager(
val installedExtensionsFlow = installedExtensionMapFlow.mapExtensions(scope) val installedExtensionsFlow = installedExtensionMapFlow.mapExtensions(scope)
private val availableExtensionMapFlow = MutableStateFlow(emptyMap<String, Extension.Available>()) private val availableExtensionMapFlow = MutableStateFlow(emptyMap<String, Extension.Available>())
// SY --> // SY -->
val availableExtensionsFlow = availableExtensionMapFlow.map { it.filterNotBlacklisted().values.toList() } val availableExtensionsFlow = availableExtensionMapFlow.map { it.filterNotBlacklisted().values.toList() }
.stateIn(scope, SharingStarted.Lazily, availableExtensionMapFlow.value.values.toList()) .stateIn(scope, SharingStarted.Lazily, availableExtensionMapFlow.value.values.toList())

View file

@ -36,8 +36,10 @@ internal class ExtensionApi {
private val getExtensionRepo: GetExtensionRepo by injectLazy() private val getExtensionRepo: GetExtensionRepo by injectLazy()
private val updateExtensionRepo: UpdateExtensionRepo by injectLazy() private val updateExtensionRepo: UpdateExtensionRepo by injectLazy()
private val extensionManager: ExtensionManager by injectLazy() private val extensionManager: ExtensionManager by injectLazy()
// SY --> // SY -->
private val sourcePreferences: SourcePreferences by injectLazy() private val sourcePreferences: SourcePreferences by injectLazy()
// SY <-- // SY <--
private val json: Json by injectLazy() private val json: Json by injectLazy()

View file

@ -383,7 +383,7 @@ class EHentai(
doc.select("#gdd .gdt1").find { el -> doc.select("#gdd .gdt1").find { el ->
el.text().lowercase() == "posted:" el.text().lowercase() == "posted:"
}!!.nextElementSibling()!!.text(), }!!.nextElementSibling()!!.text(),
MetadataUtil.EX_DATE_FORMAT.withZone(ZoneOffset.UTC) MetadataUtil.EX_DATE_FORMAT.withZone(ZoneOffset.UTC),
)!!.toInstant().toEpochMilli(), )!!.toInstant().toEpochMilli(),
scanlator = EHentaiSearchMetadata.galleryId(location), scanlator = EHentaiSearchMetadata.galleryId(location),
) )
@ -401,7 +401,7 @@ class EHentai(
chapter_number = index + 2f, chapter_number = index + 2f,
date_upload = ZonedDateTime.parse( date_upload = ZonedDateTime.parse(
posted, posted,
MetadataUtil.EX_DATE_FORMAT.withZone(ZoneOffset.UTC) MetadataUtil.EX_DATE_FORMAT.withZone(ZoneOffset.UTC),
).toInstant().toEpochMilli(), ).toInstant().toEpochMilli(),
scanlator = EHentaiSearchMetadata.galleryId(link), scanlator = EHentaiSearchMetadata.galleryId(link),
) )
@ -542,9 +542,10 @@ class EHentai(
if ( if (
MATCH_SEEK_REGEX.matches(jumpSeekValue) || MATCH_SEEK_REGEX.matches(jumpSeekValue) ||
( (
MATCH_YEAR_REGEX.matches(jumpSeekValue) && jumpSeekValue.toIntOrNull()?.let { MATCH_YEAR_REGEX.matches(jumpSeekValue) &&
it in 2007..2099 jumpSeekValue.toIntOrNull()?.let {
} == true it in 2007..2099
} == true
) )
) { ) {
uri.appendQueryParameter("seek", jumpSeekValue) uri.appendQueryParameter("seek", jumpSeekValue)
@ -715,7 +716,7 @@ class EHentai(
when (left.removeSuffix(":").lowercase()) { when (left.removeSuffix(":").lowercase()) {
"posted" -> datePosted = ZonedDateTime.parse( "posted" -> datePosted = ZonedDateTime.parse(
right, right,
MetadataUtil.EX_DATE_FORMAT.withZone(ZoneOffset.UTC) MetadataUtil.EX_DATE_FORMAT.withZone(ZoneOffset.UTC),
).toInstant().toEpochMilli() ).toInstant().toEpochMilli()
// Example gallery with parent: https://e-hentai.org/g/1390451/7f181c2426/ // Example gallery with parent: https://e-hentai.org/g/1390451/7f181c2426/
// Example JP gallery: https://exhentai.org/g/1375385/03519d541b/ // Example JP gallery: https://exhentai.org/g/1375385/03519d541b/

View file

@ -119,12 +119,13 @@ class MergedSource : HttpSource() {
"Manga references are empty, chapters unavailable, merge is likely corrupted" "Manga references are empty, chapters unavailable, merge is likely corrupted"
} }
val ifDownloadNewChapters = downloadChapters && manga.shouldDownloadNewChapters( val ifDownloadNewChapters = downloadChapters &&
getCategories.await(manga.id).map { manga.shouldDownloadNewChapters(
it.id getCategories.await(manga.id).map {
}, it.id
downloadPreferences, },
) downloadPreferences,
)
val semaphore = Semaphore(5) val semaphore = Semaphore(5)
var exception: Exception? = null var exception: Exception? = null
return supervisorScope { return supervisorScope {

View file

@ -73,16 +73,17 @@ interface SecureActivityDelegate {
} }
val lockedDays = preferences.authenticatorDays().get() val lockedDays = preferences.authenticatorDays().get()
val canLockToday = lockedDays == LOCK_ALL_DAYS || when (today.get(Calendar.DAY_OF_WEEK)) { val canLockToday = lockedDays == LOCK_ALL_DAYS ||
Calendar.SUNDAY -> (lockedDays and LOCK_SUNDAY) == LOCK_SUNDAY when (today.get(Calendar.DAY_OF_WEEK)) {
Calendar.MONDAY -> (lockedDays and LOCK_MONDAY) == LOCK_MONDAY Calendar.SUNDAY -> (lockedDays and LOCK_SUNDAY) == LOCK_SUNDAY
Calendar.TUESDAY -> (lockedDays and LOCK_TUESDAY) == LOCK_TUESDAY Calendar.MONDAY -> (lockedDays and LOCK_MONDAY) == LOCK_MONDAY
Calendar.WEDNESDAY -> (lockedDays and LOCK_WEDNESDAY) == LOCK_WEDNESDAY Calendar.TUESDAY -> (lockedDays and LOCK_TUESDAY) == LOCK_TUESDAY
Calendar.THURSDAY -> (lockedDays and LOCK_THURSDAY) == LOCK_THURSDAY Calendar.WEDNESDAY -> (lockedDays and LOCK_WEDNESDAY) == LOCK_WEDNESDAY
Calendar.FRIDAY -> (lockedDays and LOCK_FRIDAY) == LOCK_FRIDAY Calendar.THURSDAY -> (lockedDays and LOCK_THURSDAY) == LOCK_THURSDAY
Calendar.SATURDAY -> (lockedDays and LOCK_SATURDAY) == LOCK_SATURDAY Calendar.FRIDAY -> (lockedDays and LOCK_FRIDAY) == LOCK_FRIDAY
else -> false Calendar.SATURDAY -> (lockedDays and LOCK_SATURDAY) == LOCK_SATURDAY
} else -> false
}
return canLockNow && canLockToday return canLockNow && canLockToday
} }
@ -99,11 +100,13 @@ interface SecureActivityDelegate {
// `requireUnlock` can be true on process start or if app was closed in locked state // `requireUnlock` can be true on process start or if app was closed in locked state
if (!AuthenticatorUtil.isAuthenticating && !requireUnlock) { if (!AuthenticatorUtil.isAuthenticating && !requireUnlock) {
requireUnlock = /* SY --> */ canLockNow(preferences) && /* SY <-- */ when (val lockDelay = preferences.lockAppAfter().get()) { requireUnlock =
-1 -> false // Never /* SY --> */ canLockNow(preferences) &&
0 -> true // Always /* SY <-- */ when (val lockDelay = preferences.lockAppAfter().get()) {
else -> lastClosedPref.get() + lockDelay * 60_000 <= System.currentTimeMillis() -1 -> false // Never
} 0 -> true // Always
else -> lastClosedPref.get() + lockDelay * 60_000 <= System.currentTimeMillis()
}
} }
lastClosedPref.delete() lastClosedPref.delete()

View file

@ -202,7 +202,7 @@ fun feedTab(
onMoveBottom = { onMoveBottom = {
dialog.nextFeed?.let { screenModel.moveToBottom(dialog.feedItem.feed) } dialog.nextFeed?.let { screenModel.moveToBottom(dialog.feedItem.feed) }
screenModel.dismissDialog() screenModel.dismissDialog()
} },
) )
} }
// KMK <-- // KMK <--

View file

@ -124,7 +124,11 @@ class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen
) )
val onDismissRequest = { screenModel.dialog.value = null } val onDismissRequest = { screenModel.dialog.value = null }
when (@Suppress("NAME_SHADOWING") val dialog = dialog) { when
(
@Suppress("NAME_SHADOWING")
val dialog = dialog
) {
is MigrationListScreenModel.Dialog.MigrateMangaDialog -> { is MigrationListScreenModel.Dialog.MigrateMangaDialog -> {
MigrationMangaDialog( MigrationMangaDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,

View file

@ -225,7 +225,9 @@ class MigrationListScreenModel(
smartSearchEngine.normalSearch(source, mangaObj.ogTitle) smartSearchEngine.normalSearch(source, mangaObj.ogTitle)
} }
if (searchResult != null && !(searchResult.url == mangaObj.url && source.id == mangaObj.source)) { if (searchResult != null &&
!(searchResult.url == mangaObj.url && source.id == mangaObj.source)
) {
val localManga = networkToLocalManga.await(searchResult) val localManga = networkToLocalManga.await(searchResult)
val chapters = if (source is EHentai) { val chapters = if (source is EHentai) {
@ -239,7 +241,8 @@ class MigrationListScreenModel(
} catch (e: Exception) { } catch (e: Exception) {
return@async2 null return@async2 null
} }
manga.progress.value = validSources.size to processedSources.incrementAndGet() manga.progress.value =
validSources.size to processedSources.incrementAndGet()
localManga to chapters.size localManga to chapters.size
} else { } else {
null null
@ -319,7 +322,8 @@ class MigrationListScreenModel(
if (result == null && hideNotFound) { if (result == null && hideNotFound) {
removeManga(manga) removeManga(manga)
} }
if (result != null && showOnlyUpdates && if (result != null &&
showOnlyUpdates &&
(getChapterInfo(result.id).latestChapter ?: 0.0) <= (manga.chapterInfo.latestChapter ?: 0.0) (getChapterInfo(result.id).latestChapter ?: 0.0) <= (manga.chapterInfo.latestChapter ?: 0.0)
) { ) {
removeManga(manga) removeManga(manga)
@ -368,7 +372,10 @@ class MigrationListScreenModel(
dbChapters.forEach { chapter -> dbChapters.forEach { chapter ->
if (chapter.isRecognizedNumber) { if (chapter.isRecognizedNumber) {
val prevChapter = prevMangaChapters.find { it.isRecognizedNumber && it.chapterNumber == chapter.chapterNumber } val prevChapter = prevMangaChapters.find {
it.isRecognizedNumber &&
it.chapterNumber == chapter.chapterNumber
}
if (prevChapter != null) { if (prevChapter != null) {
chapterUpdates += ChapterUpdate( chapterUpdates += ChapterUpdate(
id = chapter.id, id = chapter.id,

View file

@ -101,7 +101,7 @@ data class SourceSearchScreen(
AppBarActions( AppBarActions(
actions = persistentListOf( actions = persistentListOf(
bulkSelectionButton(bulkFavoriteScreenModel::toggleSelectionMode), bulkSelectionButton(bulkFavoriteScreenModel::toggleSelectionMode),
) ),
) )
}, },
// KMK <-- // KMK <--

View file

@ -102,7 +102,7 @@ class SourcesScreenModel(
// KMK <-- // KMK <--
categories: List<String>, categories: List<String>,
showLatest: Boolean, showLatest: Boolean,
showPin: Boolean showPin: Boolean,
) { ) {
// KMK --> // KMK -->
val searchQuery = filters.first val searchQuery = filters.first
@ -156,7 +156,10 @@ class SourcesScreenModel(
items = byLang items = byLang
.flatMap { .flatMap {
listOf( listOf(
SourceUiModel.Header(it.key.removePrefix(CATEGORY_KEY_PREFIX), it.value.firstOrNull()?.category != null), SourceUiModel.Header(
it.key.removePrefix(CATEGORY_KEY_PREFIX),
it.value.firstOrNull()?.category != null,
),
*it.value.map { source -> *it.value.map { source ->
SourceUiModel.Item(source) SourceUiModel.Item(source)
}.toTypedArray(), }.toTypedArray(),

View file

@ -316,7 +316,7 @@ data class BrowseSourceScreen(
val duplicateManga = screenModel.getDuplicateLibraryManga(manga) val duplicateManga = screenModel.getDuplicateLibraryManga(manga)
when { when {
manga.favorite -> screenModel.setDialog( manga.favorite -> screenModel.setDialog(
BrowseSourceScreenModel.Dialog.RemoveManga(manga) BrowseSourceScreenModel.Dialog.RemoveManga(manga),
) )
duplicateManga != null -> screenModel.setDialog( duplicateManga != null -> screenModel.setDialog(
BrowseSourceScreenModel.Dialog.AddDuplicateManga( BrowseSourceScreenModel.Dialog.AddDuplicateManga(

View file

@ -497,7 +497,7 @@ open class BrowseSourceScreenModel(
val filterable: Boolean = true, val filterable: Boolean = true,
// SY <-- // SY <--
// KMK --> // KMK -->
val mangaDisplayingList: MutableSet<Manga> = mutableSetOf() val mangaDisplayingList: MutableSet<Manga> = mutableSetOf(),
// KMK <-- // KMK <--
) { ) {
val isUserQuery get() = listing is Listing.Search && !listing.query.isNullOrEmpty() val isUserQuery get() = listing is Listing.Search && !listing.query.isNullOrEmpty()

View file

@ -48,7 +48,15 @@ class BiometricTimesScreen : Screen() {
fun showTimePicker(startTime: Duration? = null) { fun showTimePicker(startTime: Duration? = null) {
val activity = context as? MainActivity ?: return val activity = context as? MainActivity ?: return
val picker = MaterialTimePicker.Builder() val picker = MaterialTimePicker.Builder()
.setTitleText(if (startTime == null) SYMR.strings.biometric_lock_start_time.getString(context) else SYMR.strings.biometric_lock_end_time.getString(context)) .setTitleText(
if (startTime ==
null
) {
SYMR.strings.biometric_lock_start_time.getString(context)
} else {
SYMR.strings.biometric_lock_end_time.getString(context)
},
)
.setInputMode(MaterialTimePicker.INPUT_MODE_CLOCK) .setInputMode(MaterialTimePicker.INPUT_MODE_CLOCK)
.build() .build()
picker.addOnPositiveButtonClickListener { picker.addOnPositiveButtonClickListener {

View file

@ -72,7 +72,7 @@ object DownloadQueueScreen : Screen() {
val screenModel = rememberScreenModel { val screenModel = rememberScreenModel {
DownloadQueueScreenModel( DownloadQueueScreenModel(
// KMK --> // KMK -->
navigator = navigator navigator = navigator,
// KMK <-- // KMK <--
) )
} }

View file

@ -152,7 +152,7 @@ object HomeScreen : Screen() {
materialFadeThroughOut(durationMillis = TAB_FADE_DURATION) materialFadeThroughOut(durationMillis = TAB_FADE_DURATION)
}, },
label = "tabContent", label = "tabContent",
contentKey = { it.key } contentKey = { it.key },
) { ) {
tabNavigator.saveableState(key = "currentTab", it) { tabNavigator.saveableState(key = "currentTab", it) {
it.Content() it.Content()

View file

@ -394,7 +394,8 @@ class LibraryScreenModel(
.asSequence() .asSequence()
.mapNotNull { .mapNotNull {
val list = it.split("|") val list = it.split("|")
(list.getOrNull(0)?.toIntOrNull() ?: return@mapNotNull null) to (list.getOrNull(1) ?: return@mapNotNull null) (list.getOrNull(0)?.toIntOrNull() ?: return@mapNotNull null) to
(list.getOrNull(1) ?: return@mapNotNull null)
} }
.sortedBy { it.first } .sortedBy { it.first }
.map { it.second } .map { it.second }
@ -460,8 +461,12 @@ class LibraryScreenModel(
} }
// SY --> // SY -->
LibrarySort.Type.TagList -> { LibrarySort.Type.TagList -> {
val manga1IndexOfTag = listOfTags.indexOfFirst { i1.libraryManga.manga.genre?.contains(it) ?: false } val manga1IndexOfTag = listOfTags.indexOfFirst {
val manga2IndexOfTag = listOfTags.indexOfFirst { i2.libraryManga.manga.genre?.contains(it) ?: false } i1.libraryManga.manga.genre?.contains(it) ?: false
}
val manga2IndexOfTag = listOfTags.indexOfFirst {
i2.libraryManga.manga.genre?.contains(it) ?: false
}
manga1IndexOfTag.compareTo(manga2IndexOfTag) manga1IndexOfTag.compareTo(manga2IndexOfTag)
} }
// SY <-- // SY <--
@ -572,7 +577,7 @@ class LibraryScreenModel(
source.lang, source.lang,
source.name, source.name,
supportsLatest = false, supportsLatest = false,
isStub = source is StubSource isStub = source is StubSource,
) )
} else { } else {
null null
@ -854,9 +859,12 @@ class LibraryScreenModel(
if (source != null) { if (source != null) {
if (source is MergedSource) { if (source is MergedSource) {
val mergedMangas = getMergedMangaById.await(manga.id) val mergedMangas = getMergedMangaById.await(manga.id)
val sources = mergedMangas.distinctBy { it.source }.map { sourceManager.getOrStub(it.source) } val sources = mergedMangas.distinctBy {
it.source
}.map { sourceManager.getOrStub(it.source) }
mergedMangas.forEach merge@{ mergedManga -> mergedMangas.forEach merge@{ mergedManga ->
val mergedSource = sources.firstOrNull { mergedManga.source == it.id } as? HttpSource ?: return@merge val mergedSource =
sources.firstOrNull { mergedManga.source == it.id } as? HttpSource ?: return@merge
downloadManager.deleteManga(mergedManga, mergedSource) downloadManager.deleteManga(mergedManga, mergedSource)
} }
} else { } else {
@ -934,10 +942,11 @@ class LibraryScreenModel(
} else { } else {
categoryName categoryName
} }
LibraryGroup.BY_TRACK_STATUS -> TrackStatus.entries LibraryGroup.BY_TRACK_STATUS ->
.find { it.int.toLong() == category?.id } TrackStatus.entries
.let { it ?: TrackStatus.OTHER } .find { it.int.toLong() == category?.id }
.let { context.stringResource(it.res) } .let { it ?: TrackStatus.OTHER }
.let { context.stringResource(it.res) }
LibraryGroup.UNGROUPED -> context.stringResource(SYMR.strings.ungrouped) LibraryGroup.UNGROUPED -> context.stringResource(SYMR.strings.ungrouped)
else -> categoryName else -> categoryName
} }
@ -1024,49 +1033,66 @@ class LibraryScreenModel(
(manga.description?.contains(query, true) == true) || (manga.description?.contains(query, true) == true) ||
(source?.name?.contains(query, true) == true) || (source?.name?.contains(query, true) == true) ||
(sourceIdString != null && sourceIdString == query) || (sourceIdString != null && sourceIdString == query) ||
(loggedInTrackServices.isNotEmpty() && tracks != null && filterTracks(query, tracks, context)) || (
loggedInTrackServices.isNotEmpty() &&
tracks != null &&
filterTracks(query, tracks, context)
) ||
(genre.fastAny { it.contains(query, true) }) || (genre.fastAny { it.contains(query, true) }) ||
(searchTags?.fastAny { it.name.contains(query, true) } == true) || (searchTags?.fastAny { it.name.contains(query, true) } == true) ||
(searchTitles?.fastAny { it.title.contains(query, true) } == true) (searchTitles?.fastAny { it.title.contains(query, true) } == true)
} }
is Namespace -> { is Namespace -> {
searchTags != null && searchTags.fastAny { searchTags != null &&
val tag = queryComponent.tag searchTags.fastAny {
(it.namespace.equals(queryComponent.namespace, true) && tag?.run { it.name.contains(tag.asQuery(), true) } == true) || val tag = queryComponent.tag
(tag == null && it.namespace.equals(queryComponent.namespace, true)) (
} it.namespace.equals(queryComponent.namespace, true) &&
tag?.run { it.name.contains(tag.asQuery(), true) } == true
) ||
(tag == null && it.namespace.equals(queryComponent.namespace, true))
}
} }
else -> true else -> true
} }
true -> when (queryComponent) { true -> when (queryComponent) {
is Text -> { is Text -> {
val query = queryComponent.asQuery() val query = queryComponent.asQuery()
query.isBlank() || ( query.isBlank() ||
(!manga.title.contains(query, true)) && (
(manga.author?.contains(query, true) != true) && (!manga.title.contains(query, true)) &&
(manga.artist?.contains(query, true) != true) && (manga.author?.contains(query, true) != true) &&
(manga.description?.contains(query, true) != true) && (manga.artist?.contains(query, true) != true) &&
(source?.name?.contains(query, true) != true) && (manga.description?.contains(query, true) != true) &&
(sourceIdString != null && sourceIdString != query) && (source?.name?.contains(query, true) != true) &&
(loggedInTrackServices.isEmpty() || tracks == null || !filterTracks(query, tracks, context)) && (sourceIdString != null && sourceIdString != query) &&
(!genre.fastAny { it.contains(query, true) }) && (
(searchTags?.fastAny { it.name.contains(query, true) } != true) && loggedInTrackServices.isEmpty() ||
(searchTitles?.fastAny { it.title.contains(query, true) } != true) tracks == null ||
) !filterTracks(query, tracks, context)
) &&
(!genre.fastAny { it.contains(query, true) }) &&
(searchTags?.fastAny { it.name.contains(query, true) } != true) &&
(searchTitles?.fastAny { it.title.contains(query, true) } != true)
)
} }
is Namespace -> { is Namespace -> {
val searchedTag = queryComponent.tag?.asQuery() val searchedTag = queryComponent.tag?.asQuery()
searchTags == null || (queryComponent.namespace.isBlank() && searchedTag.isNullOrBlank()) || searchTags.fastAll { mangaTag -> searchTags == null ||
if (queryComponent.namespace.isBlank() && !searchedTag.isNullOrBlank()) { (queryComponent.namespace.isBlank() && searchedTag.isNullOrBlank()) ||
!mangaTag.name.contains(searchedTag, true) searchTags.fastAll { mangaTag ->
} else if (searchedTag.isNullOrBlank()) { if (queryComponent.namespace.isBlank() && !searchedTag.isNullOrBlank()) {
mangaTag.namespace == null || !mangaTag.namespace.equals(queryComponent.namespace, true) !mangaTag.name.contains(searchedTag, true)
} else if (mangaTag.namespace.isNullOrBlank()) { } else if (searchedTag.isNullOrBlank()) {
true mangaTag.namespace == null ||
} else { !mangaTag.namespace.equals(queryComponent.namespace, true)
!mangaTag.name.contains(searchedTag, true) || !mangaTag.namespace.equals(queryComponent.namespace, true) } else if (mangaTag.namespace.isNullOrBlank()) {
true
} else {
!mangaTag.name.contains(searchedTag, true) ||
!mangaTag.namespace.equals(queryComponent.namespace, true)
}
} }
}
} }
else -> true else -> true
} }

View file

@ -364,8 +364,10 @@ class MainActivity : BaseActivity() {
mutableStateOf( mutableStateOf(
// KMK --> // KMK -->
// BuildConfig.DEBUG || // BuildConfig.DEBUG ||
isReleaseBuildType && didMigration || isReleaseBuildType &&
isPreviewBuildType && previewCurrentVersion > previewLastVersion.get() didMigration ||
isPreviewBuildType &&
previewCurrentVersion > previewLastVersion.get(),
// KMK <-- // KMK <--
) )
} }

View file

@ -186,7 +186,7 @@ class MangaScreen(
val seedColor = successState.seedColor val seedColor = successState.seedColor
TachiyomiTheme( TachiyomiTheme(
seedColor = seedColor.takeIf { screenModel.themeCoverBased } seedColor = seedColor.takeIf { screenModel.themeCoverBased },
) { ) {
content() content()
} }
@ -329,10 +329,14 @@ class MangaScreen(
) )
}, },
onEditInfoClicked = screenModel::showEditMangaInfoDialog, onEditInfoClicked = screenModel::showEditMangaInfoDialog,
onRecommendClicked = { openRecommends(context, navigator, screenModel.source?.getMainSource(), successState.manga) }, onRecommendClicked = {
openRecommends(context, navigator, screenModel.source?.getMainSource(), successState.manga)
},
onMergedSettingsClicked = screenModel::showEditMergedSettingsDialog, onMergedSettingsClicked = screenModel::showEditMergedSettingsDialog,
onMergeClicked = { openSmartSearch(navigator, successState.manga) }, onMergeClicked = { openSmartSearch(navigator, successState.manga) },
onMergeWithAnotherClicked = { mergeWithAnother(navigator, context, successState.manga, screenModel::smartSearchMerge) }, onMergeWithAnotherClicked = {
mergeWithAnother(navigator, context, successState.manga, screenModel::smartSearchMerge)
},
onOpenPagePreview = { page -> onOpenPagePreview = { page ->
openPagePreview(context, successState.chapters.minByOrNull { it.chapter.sourceOrder }?.chapter, page) openPagePreview(context, successState.chapters.minByOrNull { it.chapter.sourceOrder }?.chapter, page)
}, },
@ -620,7 +624,8 @@ class MangaScreen(
// KMK --> // KMK -->
navigator.popUntil { screen -> navigator.popUntil { screen ->
screen is HomeScreen || screen is HomeScreen ||
!library && (screen is BrowseSourceScreen || screen is SourceFeedScreen) !library &&
(screen is BrowseSourceScreen || screen is SourceFeedScreen)
} }
// KMK <-- // KMK <--

View file

@ -300,7 +300,10 @@ class MangaScreenModel(
} }
} }
.onEach { (manga, chapters) -> .onEach { (manga, chapters) ->
if (chapters.isNotEmpty() && manga.isEhBasedManga() && DebugToggles.ENABLE_EXH_ROOT_REDIRECT.enabled) { if (chapters.isNotEmpty() &&
manga.isEhBasedManga() &&
DebugToggles.ENABLE_EXH_ROOT_REDIRECT.enabled
) {
// Check for gallery in library and accept manga with lowest id // Check for gallery in library and accept manga with lowest id
// Find chapters sharing same root // Find chapters sharing same root
launchIO { launchIO {
@ -388,7 +391,7 @@ class MangaScreenModel(
} else { } else {
flowOf(emptySet()) flowOf(emptySet())
} }
} },
) { mangaScanlators, mergeScanlators -> ) { mangaScanlators, mergeScanlators ->
mangaScanlators + mergeScanlators mangaScanlators + mergeScanlators
} // SY <-- } // SY <--
@ -405,7 +408,15 @@ class MangaScreenModel(
val manga = getMangaAndChapters.awaitManga(mangaId) val manga = getMangaAndChapters.awaitManga(mangaId)
// SY --> // SY -->
val chapters = (if (manga.source == MERGED_SOURCE_ID) getMergedChaptersByMangaId.await(mangaId, applyScanlatorFilter = true) else getMangaAndChapters.awaitChapters(mangaId, applyScanlatorFilter = true)) val chapters = (
if (manga.source ==
MERGED_SOURCE_ID
) {
getMergedChaptersByMangaId.await(mangaId, applyScanlatorFilter = true)
} else {
getMangaAndChapters.awaitChapters(mangaId, applyScanlatorFilter = true)
}
)
.toChapterListItems(manga, null) .toChapterListItems(manga, null)
val mergedData = getMergedReferencesById.await(mangaId).takeIf { it.isNotEmpty() }?.let { references -> val mergedData = getMergedReferencesById.await(mangaId).takeIf { it.isNotEmpty() }?.let { references ->
MergedMangaData( MergedMangaData(
@ -460,7 +471,8 @@ class MangaScreenModel(
} else { } else {
PagePreviewState.Unused PagePreviewState.Unused
}, },
alwaysShowReadingProgress = readerPreferences.preserveReadingPosition().get() && manga.isEhBasedManga(), alwaysShowReadingProgress =
readerPreferences.preserveReadingPosition().get() && manga.isEhBasedManga(),
previewsRowCount = uiPreferences.previewsRowCount().get(), previewsRowCount = uiPreferences.previewsRowCount().get(),
// SY <-- // SY <--
) )
@ -542,7 +554,7 @@ class MangaScreenModel(
// } // }
}, },
) )
.build() .build(),
) )
} }
@ -1066,7 +1078,12 @@ class MangaScreenModel(
screenModelScope.launchIO { screenModelScope.launchIO {
downloadManager.statusFlow() downloadManager.statusFlow()
.filter { .filter {
/* SY --> */ if (isMergedSource) it.manga.id in mergedIds else /* SY <-- */ it.manga.id == successState?.manga?.id /* SY --> */ if (isMergedSource) {
it.manga.id in mergedIds
} else {
/* SY <-- */ it.manga.id ==
successState?.manga?.id
}
} }
.catch { error -> logcat(LogPriority.ERROR, error) } .catch { error -> logcat(LogPriority.ERROR, error) }
.collect { .collect {
@ -1079,7 +1096,12 @@ class MangaScreenModel(
screenModelScope.launchIO { screenModelScope.launchIO {
downloadManager.progressFlow() downloadManager.progressFlow()
.filter { .filter {
/* SY --> */ if (isMergedSource) it.manga.id in mergedIds else /* SY <-- */ it.manga.id == successState?.manga?.id /* SY --> */ if (isMergedSource) {
it.manga.id in mergedIds
} else {
/* SY <-- */ it.manga.id ==
successState?.manga?.id
}
} }
.catch { error -> logcat(LogPriority.ERROR, error) } .catch { error -> logcat(LogPriority.ERROR, error) }
.collect { .collect {
@ -1755,7 +1777,8 @@ class MangaScreenModel(
} }
// SY --> // SY -->
.map { (tracks, supportedTrackers) -> .map { (tracks, supportedTrackers) ->
val supportedTrackerTracks = if (manga.source in mangaDexSourceIds || state.mergedData?.manga?.values.orEmpty().any { val supportedTrackerTracks = if (manga.source in mangaDexSourceIds ||
state.mergedData?.manga?.values.orEmpty().any {
it.source in mangaDexSourceIds it.source in mangaDexSourceIds
} }
) { ) {
@ -1937,7 +1960,7 @@ class MangaScreenModel(
* a list of <keyword, related mangas> * a list of <keyword, related mangas>
*/ */
val relatedMangaCollection: List<RelatedManga>? = null, val relatedMangaCollection: List<RelatedManga>? = null,
val seedColor: Color? = manga.asMangaCover().vibrantCoverColor?.let { Color(it) } val seedColor: Color? = manga.asMangaCover().vibrantCoverColor?.let { Color(it) },
// KMK <-- // KMK <--
) : State { ) : State {
// KMK --> // KMK -->

View file

@ -39,7 +39,7 @@ class PaletteScreen(
val seedColor = seedColor?.let { Color(it) } ?: MaterialTheme.colorScheme.primary val seedColor = seedColor?.let { Color(it) } ?: MaterialTheme.colorScheme.primary
TachiyomiTheme( TachiyomiTheme(
seedColor = seedColor.takeIf { themeCoverBased } seedColor = seedColor.takeIf { themeCoverBased },
) { ) {
MaterialThemeContent(seedColor) MaterialThemeContent(seedColor)
} }
@ -76,7 +76,7 @@ class PaletteScreen(
"primary", "primary",
MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.primary,
"primaryContainer", "primaryContainer",
MaterialTheme.colorScheme.primaryContainer MaterialTheme.colorScheme.primaryContainer,
) )
} }
item { item {
@ -84,7 +84,7 @@ class PaletteScreen(
"secondary", "secondary",
MaterialTheme.colorScheme.secondary, MaterialTheme.colorScheme.secondary,
"secondaryContainer", "secondaryContainer",
MaterialTheme.colorScheme.secondaryContainer MaterialTheme.colorScheme.secondaryContainer,
) )
} }
item { item {
@ -92,7 +92,7 @@ class PaletteScreen(
"tertiary", "tertiary",
MaterialTheme.colorScheme.tertiary, MaterialTheme.colorScheme.tertiary,
"tertiaryContainer", "tertiaryContainer",
MaterialTheme.colorScheme.tertiaryContainer MaterialTheme.colorScheme.tertiaryContainer,
) )
} }
item { item {
@ -100,7 +100,7 @@ class PaletteScreen(
"surface", "surface",
MaterialTheme.colorScheme.surface, MaterialTheme.colorScheme.surface,
"surfaceVariant", "surfaceVariant",
MaterialTheme.colorScheme.surfaceVariant MaterialTheme.colorScheme.surfaceVariant,
) )
} }
item { item {
@ -108,7 +108,7 @@ class PaletteScreen(
"inverseSurface", "inverseSurface",
MaterialTheme.colorScheme.inverseSurface, MaterialTheme.colorScheme.inverseSurface,
"surfaceTint", "surfaceTint",
MaterialTheme.colorScheme.surfaceTint MaterialTheme.colorScheme.surfaceTint,
) )
} }
item { item {
@ -116,7 +116,7 @@ class PaletteScreen(
"inversePrimary", "inversePrimary",
MaterialTheme.colorScheme.inversePrimary, MaterialTheme.colorScheme.inversePrimary,
"background", "background",
MaterialTheme.colorScheme.background MaterialTheme.colorScheme.background,
) )
} }
item { item {
@ -124,7 +124,7 @@ class PaletteScreen(
"error", "error",
MaterialTheme.colorScheme.error, MaterialTheme.colorScheme.error,
"errorContainer", "errorContainer",
MaterialTheme.colorScheme.errorContainer MaterialTheme.colorScheme.errorContainer,
) )
} }
item { item {
@ -132,7 +132,7 @@ class PaletteScreen(
"outline", "outline",
MaterialTheme.colorScheme.outline, MaterialTheme.colorScheme.outline,
"outlineVariant", "outlineVariant",
MaterialTheme.colorScheme.outlineVariant MaterialTheme.colorScheme.outlineVariant,
) )
} }
item { item {
@ -140,7 +140,7 @@ class PaletteScreen(
"scrim", "scrim",
MaterialTheme.colorScheme.scrim, MaterialTheme.colorScheme.scrim,
"surfaceBright", "surfaceBright",
MaterialTheme.colorScheme.surfaceBright MaterialTheme.colorScheme.surfaceBright,
) )
} }
item { item {
@ -148,7 +148,7 @@ class PaletteScreen(
"surfaceDim", "surfaceDim",
MaterialTheme.colorScheme.surfaceDim, MaterialTheme.colorScheme.surfaceDim,
"surfaceContainer", "surfaceContainer",
MaterialTheme.colorScheme.surfaceContainer MaterialTheme.colorScheme.surfaceContainer,
) )
} }
item { item {
@ -156,7 +156,7 @@ class PaletteScreen(
"surfaceContainerHigh", "surfaceContainerHigh",
MaterialTheme.colorScheme.surfaceContainerHigh, MaterialTheme.colorScheme.surfaceContainerHigh,
"surfaceContainerHighest", "surfaceContainerHighest",
MaterialTheme.colorScheme.surfaceContainerHighest MaterialTheme.colorScheme.surfaceContainerHighest,
) )
} }
item { item {
@ -164,7 +164,7 @@ class PaletteScreen(
"surfaceContainerLow", "surfaceContainerLow",
MaterialTheme.colorScheme.surfaceContainerLow, MaterialTheme.colorScheme.surfaceContainerLow,
"surfaceContainerLowest", "surfaceContainerLowest",
MaterialTheme.colorScheme.surfaceContainerLowest MaterialTheme.colorScheme.surfaceContainerLowest,
) )
} }
} }
@ -184,7 +184,7 @@ fun ButtonsColor(
Row( Row(
modifier = Modifier modifier = Modifier
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)
.fillMaxWidth() .fillMaxWidth(),
) { ) {
Button( Button(
onClick = { }, onClick = { },
@ -194,7 +194,7 @@ fun ButtonsColor(
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = color1, containerColor = color1,
contentColor = contentColor1, contentColor = contentColor1,
) ),
) { ) {
Text( Text(
text = name1, text = name1,
@ -211,7 +211,7 @@ fun ButtonsColor(
), ),
) { ) {
Text( Text(
text = name2 text = name2,
) )
} }
} }

View file

@ -59,7 +59,8 @@ class EditMergedSettingsState(
}.map { reference -> mergedManga.firstOrNull { it.id == reference.mangaId } to reference } }.map { reference -> mergedManga.firstOrNull { it.id == reference.mangaId } to reference }
mergeReference = mergedReferences.firstOrNull { it.mangaSourceId == MERGED_SOURCE_ID } mergeReference = mergedReferences.firstOrNull { it.mangaSourceId == MERGED_SOURCE_ID }
val isPriorityOrder = mergeReference?.let { it.chapterSortMode == MergedMangaReference.CHAPTER_SORT_PRIORITY } ?: false val isPriorityOrder =
mergeReference?.let { it.chapterSortMode == MergedMangaReference.CHAPTER_SORT_PRIORITY } ?: false
mergedMangaAdapter = EditMergedMangaAdapter(this, isPriorityOrder) mergedMangaAdapter = EditMergedMangaAdapter(this, isPriorityOrder)
mergedMangaHeaderAdapter = EditMergedSettingsHeaderAdapter(this, mergedMangaAdapter!!) mergedMangaHeaderAdapter = EditMergedSettingsHeaderAdapter(this, mergedMangaAdapter!!)

View file

@ -161,7 +161,8 @@ class EditMergedSettingsHeaderAdapter(private val state: EditMergedSettingsState
} }
} }
fun canMove() = state.mergeReference?.let { it.chapterSortMode == MergedMangaReference.CHAPTER_SORT_PRIORITY } ?: false fun canMove() =
state.mergeReference?.let { it.chapterSortMode == MergedMangaReference.CHAPTER_SORT_PRIORITY } ?: false
interface SortingListener { interface SortingListener {
fun onSetPrioritySort(isPriorityOrder: Boolean) fun onSetPrioritySort(isPriorityOrder: Boolean)

View file

@ -476,10 +476,12 @@ class ReaderActivity : BaseActivity() {
val landscapeVerticalSeekbar by readerPreferences.landscapeVerticalSeekbar().collectAsState() val landscapeVerticalSeekbar by readerPreferences.landscapeVerticalSeekbar().collectAsState()
val leftHandedVerticalSeekbar by readerPreferences.leftVerticalSeekbar().collectAsState() val leftHandedVerticalSeekbar by readerPreferences.leftVerticalSeekbar().collectAsState()
val configuration = LocalConfiguration.current val configuration = LocalConfiguration.current
val verticalSeekbarLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && landscapeVerticalSeekbar val verticalSeekbarLandscape =
configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && landscapeVerticalSeekbar
val verticalSeekbarHorizontal = configuration.orientation == Configuration.ORIENTATION_PORTRAIT val verticalSeekbarHorizontal = configuration.orientation == Configuration.ORIENTATION_PORTRAIT
val viewerIsVertical = (state.viewer is WebtoonViewer || state.viewer is VerticalPagerViewer) val viewerIsVertical = (state.viewer is WebtoonViewer || state.viewer is VerticalPagerViewer)
val showVerticalSeekbar = !forceHorizontalSeekbar && (verticalSeekbarLandscape || verticalSeekbarHorizontal) && viewerIsVertical val showVerticalSeekbar =
!forceHorizontalSeekbar && (verticalSeekbarLandscape || verticalSeekbarHorizontal) && viewerIsVertical
val navBarType = when { val navBarType = when {
!showVerticalSeekbar -> NavBarType.Bottom !showVerticalSeekbar -> NavBarType.Bottom
leftHandedVerticalSeekbar -> NavBarType.VerticalLeft leftHandedVerticalSeekbar -> NavBarType.VerticalLeft
@ -940,7 +942,8 @@ class ReaderActivity : BaseActivity() {
} else { } else {
if (readerPreferences.fullscreen().get()) { if (readerPreferences.fullscreen().get()) {
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE windowInsetsController.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
} }
} }
} }
@ -1160,7 +1163,13 @@ class ReaderActivity : BaseActivity() {
// SY --> // SY -->
val currentPageText = if (hasExtraPage) { val currentPageText = if (hasExtraPage) {
val invertDoublePage = (viewModel.state.value.viewer as? PagerViewer)?.config?.invertDoublePages ?: false val invertDoublePage = (viewModel.state.value.viewer as? PagerViewer)?.config?.invertDoublePages ?: false
if ((resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR) xor invertDoublePage) "${page.number}-${page.number + 1}" else "${page.number + 1}-${page.number}" if ((resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR) xor
invertDoublePage
) {
"${page.number}-${page.number + 1}"
} else {
"${page.number + 1}-${page.number}"
}
} else { } else {
"${page.number}" "${page.number}"
} }
@ -1222,7 +1231,16 @@ class ReaderActivity : BaseActivity() {
// SY --> // SY -->
val text = if (secondPage != null) { val text = if (secondPage != null) {
stringResource(SYMR.strings.share_pages_info, manga.title, chapter.name, if (resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR) "${page.number}-${page.number + 1}" else "${page.number + 1}-${page.number}") stringResource(
SYMR.strings.share_pages_info, manga.title, chapter.name,
if (resources.configuration.layoutDirection ==
View.LAYOUT_DIRECTION_LTR
) {
"${page.number}-${page.number + 1}"
} else {
"${page.number + 1}-${page.number}"
},
)
} else { } else {
stringResource(MR.strings.share_page_info, manga.title, chapter.name, page.number) stringResource(MR.strings.share_page_info, manga.title, chapter.name, page.number)
} }
@ -1386,11 +1404,14 @@ class ReaderActivity : BaseActivity() {
.onEach { .onEach {
if (viewModel.state.value.viewer !is PagerViewer) return@onEach if (viewModel.state.value.viewer !is PagerViewer) return@onEach
reloadChapters( reloadChapters(
!it && when (readerPreferences.pageLayout().get()) { !it &&
PagerConfig.PageLayout.DOUBLE_PAGES -> true when (readerPreferences.pageLayout().get()) {
PagerConfig.PageLayout.AUTOMATIC -> resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE PagerConfig.PageLayout.DOUBLE_PAGES -> true
else -> false PagerConfig.PageLayout.AUTOMATIC ->
}, resources.configuration.orientation ==
Configuration.ORIENTATION_LANDSCAPE
else -> false
},
true, true,
) )
} }

View file

@ -134,7 +134,7 @@ class ReaderViewModel @JvmOverloads constructor(
private val getMergedMangaById: GetMergedMangaById = Injekt.get(), private val getMergedMangaById: GetMergedMangaById = Injekt.get(),
private val getMergedReferencesById: GetMergedReferencesById = Injekt.get(), private val getMergedReferencesById: GetMergedReferencesById = Injekt.get(),
private val getMergedChaptersByMangaId: GetMergedChaptersByMangaId = Injekt.get(), private val getMergedChaptersByMangaId: GetMergedChaptersByMangaId = Injekt.get(),
private val setReadStatus: SetReadStatus = Injekt.get() private val setReadStatus: SetReadStatus = Injekt.get(),
// SY <-- // SY <--
) : ViewModel() { ) : ViewModel() {
@ -189,8 +189,9 @@ class ReaderViewModel @JvmOverloads constructor(
// SY --> // SY -->
val (chapters, mangaMap) = runBlocking { val (chapters, mangaMap) = runBlocking {
if (manga.source == MERGED_SOURCE_ID) { if (manga.source == MERGED_SOURCE_ID) {
getMergedChaptersByMangaId.await(manga.id, applyScanlatorFilter = true) to getMergedMangaById.await(manga.id) getMergedChaptersByMangaId.await(manga.id, applyScanlatorFilter = true) to
.associateBy { it.id } getMergedMangaById.await(manga.id)
.associateBy { it.id }
} else { } else {
getChaptersByMangaId.await(manga.id, applyScanlatorFilter = true) to null getChaptersByMangaId.await(manga.id, applyScanlatorFilter = true) to null
} }

View file

@ -62,9 +62,11 @@ class ChapterLoader(
// If the chapter is partially read, set the starting page to the last the user read // If the chapter is partially read, set the starting page to the last the user read
// otherwise use the requested page. // otherwise use the requested page.
if (!chapter.chapter.read /* --> EH */ || readerPrefs if (!chapter.chapter.read /* --> EH */ ||
readerPrefs
.preserveReadingPosition() .preserveReadingPosition()
.get() || page != null // <-- EH .get() ||
page != null // <-- EH
) { ) {
chapter.requestedPage = /* SY --> */ page ?: /* SY <-- */ chapter.chapter.last_page_read chapter.requestedPage = /* SY --> */ page ?: /* SY <-- */ chapter.chapter.last_page_read
} }

View file

@ -285,7 +285,7 @@ class ReaderPreferences(
val archiveModeTypes = listOf( val archiveModeTypes = listOf(
SYMR.strings.archive_mode_load_from_file, SYMR.strings.archive_mode_load_from_file,
SYMR.strings.archive_mode_load_into_memory, SYMR.strings.archive_mode_load_into_memory,
SYMR.strings.archive_mode_cache_to_disk SYMR.strings.archive_mode_cache_to_disk,
) )
// SY <-- // SY <--
} }

View file

@ -71,7 +71,7 @@ enum class ReadingMode(
preference: Int?, preference: Int?,
activity: ReaderActivity, activity: ReaderActivity,
// KMK --> // KMK -->
@ColorInt seedColor: Int? @ColorInt seedColor: Int?,
// KMK <-- // KMK <--
): Viewer { ): Viewer {
return when (fromPreference(preference)) { return when (fromPreference(preference)) {

View file

@ -116,7 +116,12 @@ open class ReaderPageImageView @JvmOverloads constructor(
} }
private fun SubsamplingScaleImageView.landscapeZoom(forward: Boolean) { private fun SubsamplingScaleImageView.landscapeZoom(forward: Boolean) {
if (config != null && config!!.landscapeZoom && config!!.minimumScaleType == SCALE_TYPE_CENTER_INSIDE && sWidth > sHeight && scale == minScale) { if (config != null &&
config!!.landscapeZoom &&
config!!.minimumScaleType == SCALE_TYPE_CENTER_INSIDE &&
sWidth > sHeight &&
scale == minScale
) {
handler?.postDelayed(500) { handler?.postDelayed(500) {
val point = when (config!!.zoomStartPosition) { val point = when (config!!.zoomStartPosition) {
ZoomStartPosition.LEFT -> if (forward) PointF(0F, 0F) else PointF(sWidth.toFloat(), 0F) ZoomStartPosition.LEFT -> if (forward) PointF(0F, 0F) else PointF(sWidth.toFloat(), 0F)

View file

@ -52,7 +52,7 @@ class ReaderProgressIndicator @JvmOverloads constructor(
// KMK <-- // KMK <--
TachiyomiTheme( TachiyomiTheme(
// KMK --> // KMK -->
seedColor = seedColor?.let { Color(seedColor) }.takeIf { themeCoverBased } seedColor = seedColor?.let { Color(seedColor) }.takeIf { themeCoverBased },
// KMK <-- // KMK <--
) { ) {
CombinedCircularProgressIndicator(progress = { progress }) CombinedCircularProgressIndicator(progress = { progress })

View file

@ -68,7 +68,7 @@ class ReaderTransitionView @JvmOverloads constructor(
// KMK <-- // KMK <--
TachiyomiTheme( TachiyomiTheme(
// KMK --> // KMK -->
seedColor = seedColor?.let { Color(seedColor) }.takeIf { themeCoverBased } seedColor = seedColor?.let { Color(seedColor) }.takeIf { themeCoverBased },
// KMK <-- // KMK <--
) { ) {
CompositionLocalProvider( CompositionLocalProvider(

View file

@ -57,7 +57,8 @@ class PagerConfig(
var shiftDoublePage = false var shiftDoublePage = false
var doublePages = readerPreferences.pageLayout().get() == PageLayout.DOUBLE_PAGES && !readerPreferences.dualPageSplitPaged().get() var doublePages =
readerPreferences.pageLayout().get() == PageLayout.DOUBLE_PAGES && !readerPreferences.dualPageSplitPaged().get()
set(value) { set(value) {
field = value field = value
if (!value) { if (!value) {

View file

@ -318,9 +318,9 @@ class PagerPageHolder(
private fun handleWideImage(imageSource: BufferedSource): BufferedSource { private fun handleWideImage(imageSource: BufferedSource): BufferedSource {
return if ( return if (
!ImageUtil.isAnimatedAndSupported(imageSource) && !ImageUtil.isAnimatedAndSupported(imageSource) &&
ImageUtil.isWideImage(imageSource) && ImageUtil.isWideImage(imageSource) &&
viewer.config.centerMarginType and PagerConfig.CenterMarginType.WIDE_PAGE_CENTER_MARGIN > 0 && viewer.config.centerMarginType and PagerConfig.CenterMarginType.WIDE_PAGE_CENTER_MARGIN > 0 &&
!viewer.config.imageCropBorders !viewer.config.imageCropBorders
) { ) {
ImageUtil.addHorizontalCenterMargin(imageSource, height, context) ImageUtil.addHorizontalCenterMargin(imageSource, height, context)
} else { } else {
@ -338,7 +338,9 @@ class PagerPageHolder(
} }
private fun calculateCenterMargin(height: Int, height2: Int): Int { private fun calculateCenterMargin(height: Int, height2: Int): Int {
return if (viewer.config.centerMarginType and PagerConfig.CenterMarginType.DOUBLE_PAGE_CENTER_MARGIN > 0 && !viewer.config.imageCropBorders) { return if (viewer.config.centerMarginType and PagerConfig.CenterMarginType.DOUBLE_PAGE_CENTER_MARGIN > 0 &&
!viewer.config.imageCropBorders
) {
96 / (this.height.coerceAtLeast(1) / max(height, height2).coerceAtLeast(1)).coerceAtLeast(1) 96 / (this.height.coerceAtLeast(1) / max(height, height2).coerceAtLeast(1)).coerceAtLeast(1)
} else { } else {
0 0
@ -381,8 +383,10 @@ class PagerPageHolder(
} }
} }
val sideMargin = if ((viewer.config.centerMarginType and PagerConfig.CenterMarginType.DOUBLE_PAGE_CENTER_MARGIN) > 0 && val sideMargin = if ((viewer.config.centerMarginType and PagerConfig.CenterMarginType.DOUBLE_PAGE_CENTER_MARGIN) >
viewer.config.doublePages && !viewer.config.imageCropBorders 0 &&
viewer.config.doublePages &&
!viewer.config.imageCropBorders
) { ) {
48 48
} else { } else {

View file

@ -302,7 +302,9 @@ abstract class PagerViewer(
* Sets the active [chapters] on this pager. * Sets the active [chapters] on this pager.
*/ */
private fun setChaptersInternal(chapters: ViewerChapters) { private fun setChaptersInternal(chapters: ViewerChapters) {
val forceTransition = config.alwaysShowChapterTransition || adapter.joinedItems.getOrNull(pager.currentItem)?.first is ChapterTransition val forceTransition =
config.alwaysShowChapterTransition ||
adapter.joinedItems.getOrNull(pager.currentItem)?.first is ChapterTransition
adapter.setChapters(chapters, forceTransition) adapter.setChapters(chapters, forceTransition)
// Layout the pager once a chapter is being set // Layout the pager once a chapter is being set

View file

@ -271,7 +271,9 @@ class PagerViewerAdapter(
subItems.forEach { readerItem -> subItems.forEach { readerItem ->
when (readerItem) { when (readerItem) {
is ReaderPage -> { is ReaderPage -> {
if (pagedItems.last().isNotEmpty() && pagedItems.last().last()?.chapter?.chapter?.id != readerItem.chapter.chapter.id) { if (pagedItems.last().isNotEmpty() &&
pagedItems.last().last()?.chapter?.chapter?.id != readerItem.chapter.chapter.id
) {
pagedItems.add(mutableListOf()) pagedItems.add(mutableListOf())
} }
pagedItems.last().add(readerItem) pagedItems.last().add(readerItem)
@ -321,9 +323,10 @@ class PagerViewerAdapter(
// Add a 'blank' page after each full page. It will be used when chunked to solo a page // Add a 'blank' page after each full page. It will be used when chunked to solo a page
items.add(itemIndex + 1, null) items.add(itemIndex + 1, null)
if ( if (
currentItem.fullPage && itemIndex > 0 && currentItem.fullPage &&
items[itemIndex - 1] != null && itemIndex > 0 &&
(itemIndex - 1) % 2 == 0 items[itemIndex - 1] != null &&
(itemIndex - 1) % 2 == 0
) { ) {
// If a page is a full page, check if the previous page needs to be isolated // If a page is a full page, check if the previous page needs to be isolated
// we should check if it's an even or odd page, since even pages need shifting // we should check if it's an even or odd page, since even pages need shifting
@ -363,7 +366,8 @@ class PagerViewerAdapter(
// We will however shift to the first page of the new chapter if the last page we were are // We will however shift to the first page of the new chapter if the last page we were are
// on is not in the new chapter that has loaded // on is not in the new chapter that has loaded
val newPage = when { val newPage = when {
oldCurrent?.first is ReaderPage && (oldCurrent.first as ReaderPage).chapter != currentChapter && oldCurrent?.first is ReaderPage &&
(oldCurrent.first as ReaderPage).chapter != currentChapter &&
(oldCurrent.second as? ChapterTransition)?.from != currentChapter -> (oldCurrent.second as? ChapterTransition)?.from != currentChapter ->
subItems.find { it is ReaderPage && it.chapter == currentChapter } subItems.find { it is ReaderPage && it.chapter == currentChapter }
useSecondPage -> oldCurrent?.second ?: oldCurrent?.first useSecondPage -> oldCurrent?.second ?: oldCurrent?.first
@ -372,7 +376,10 @@ class PagerViewerAdapter(
val index = when (newPage) { val index = when (newPage) {
is ChapterTransition -> { is ChapterTransition -> {
val filteredPages = joinedItems.filter { it.first is ReaderPage && (it.first as ReaderPage).chapter == newPage.to } val filteredPages = joinedItems.filter {
it.first is ReaderPage &&
(it.first as ReaderPage).chapter == newPage.to
}
val page = if (newPage is ChapterTransition.Next) { val page = if (newPage is ChapterTransition.Next) {
filteredPages.minByOrNull { (it.first as ReaderPage).index }?.first filteredPages.minByOrNull { (it.first as ReaderPage).index }?.first
} else { } else {

View file

@ -203,7 +203,9 @@ class WebtoonPageHolder(
ReaderPageImageView.Config( ReaderPageImageView.Config(
zoomDuration = viewer.config.doubleTapAnimDuration, zoomDuration = viewer.config.doubleTapAnimDuration,
minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_FIT_WIDTH, minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_FIT_WIDTH,
cropBorders = (viewer.config.imageCropBorders && viewer.isContinuous) || (viewer.config.continuousCropBorders && !viewer.isContinuous), cropBorders =
(viewer.config.imageCropBorders && viewer.isContinuous) ||
(viewer.config.continuousCropBorders && !viewer.isContinuous),
), ),
) )
removeErrorLayout() removeErrorLayout()

View file

@ -23,7 +23,10 @@ fun Context.notify(id: Int, channelId: String, block: (NotificationCompat.Builde
} }
fun Context.notify(id: Int, notification: Notification) { fun Context.notify(id: Int, notification: Notification) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && PermissionChecker.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PermissionChecker.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
PermissionChecker.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) !=
PermissionChecker.PERMISSION_GRANTED
) {
return return
} }
@ -31,7 +34,10 @@ fun Context.notify(id: Int, notification: Notification) {
} }
fun Context.notify(notificationWithIdAndTags: List<NotificationWithIdAndTag>) { fun Context.notify(notificationWithIdAndTags: List<NotificationWithIdAndTag>) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && PermissionChecker.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PermissionChecker.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
PermissionChecker.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) !=
PermissionChecker.PERMISSION_GRANTED
) {
return return
} }

View file

@ -46,11 +46,13 @@ class GalleryAdder(
return sourceManager.getVisibleCatalogueSources() return sourceManager.getVisibleCatalogueSources()
.mapNotNull { it.getMainSource<UrlImportableSource>() } .mapNotNull { it.getMainSource<UrlImportableSource>() }
.filter { .filter {
it.lang in filters.enabledLangs && it.id !in filters.disabledSources && try { it.lang in filters.enabledLangs &&
it.matchesUri(uri) it.id !in filters.disabledSources &&
} catch (e: Exception) { try {
false it.matchesUri(uri)
} } catch (e: Exception) {
false
}
} }
} }
@ -82,11 +84,13 @@ class GalleryAdder(
sourceManager.getVisibleCatalogueSources() sourceManager.getVisibleCatalogueSources()
.mapNotNull { it.getMainSource<UrlImportableSource>() } .mapNotNull { it.getMainSource<UrlImportableSource>() }
.find { .find {
it.lang in filters.enabledLangs && it.id !in filters.disabledSources && try { it.lang in filters.enabledLangs &&
it.matchesUri(uri) it.id !in filters.disabledSources &&
} catch (e: Exception) { try {
false it.matchesUri(uri)
} } catch (e: Exception) {
false
}
} ?: return GalleryAddEvent.Fail.UnknownSource(url, context) } ?: return GalleryAddEvent.Fail.UnknownSource(url, context)
} }

View file

@ -9,6 +9,7 @@ import kotlin.collections.List as ____KtList
public object EhAssets public object EhAssets
@Suppress("ObjectPropertyName", "ktlint:standard:backing-property-naming")
private var __AllAssets: ____KtList<ImageVector>? = null private var __AllAssets: ____KtList<ImageVector>? = null
public val EhAssets.AllAssets: ____KtList<ImageVector> public val EhAssets.AllAssets: ____KtList<ImageVector>

View file

@ -165,4 +165,5 @@ public val EhAssets.EhLogo: ImageVector
return _ehLogo!! return _ehLogo!!
} }
@Suppress("ObjectPropertyName", "ktlint:standard:backing-property-naming")
private var _ehLogo: ImageVector? = null private var _ehLogo: ImageVector? = null

View file

@ -427,4 +427,5 @@ public val EhAssets.MangadexLogo: ImageVector
return _mangadexLogo!! return _mangadexLogo!!
} }
@Suppress("ObjectPropertyName", "ktlint:standard:backing-property-naming")
private var _mangadexLogo: ImageVector? = null private var _mangadexLogo: ImageVector? = null

View file

@ -11,6 +11,7 @@ public object ExhGroup
public val EhAssets.Exh: ExhGroup public val EhAssets.Exh: ExhGroup
get() = ExhGroup get() = ExhGroup
@Suppress("ObjectPropertyName", "ktlint:standard:backing-property-naming")
private var __AllAssets: ____KtList<ImageVector>? = null private var __AllAssets: ____KtList<ImageVector>? = null
public val ExhGroup.AllAssets: ____KtList<ImageVector> public val ExhGroup.AllAssets: ____KtList<ImageVector>

View file

@ -11,6 +11,7 @@ public object AssetsGroup
public val ExhGroup.Assets: AssetsGroup public val ExhGroup.Assets: AssetsGroup
get() = AssetsGroup get() = AssetsGroup
@Suppress("ObjectPropertyName", "ktlint:standard:backing-property-naming")
private var __AllAssets: ____KtList<ImageVector>? = null private var __AllAssets: ____KtList<ImageVector>? = null
public val AssetsGroup.AllAssets: ____KtList<ImageVector> public val AssetsGroup.AllAssets: ____KtList<ImageVector>

View file

@ -9,6 +9,7 @@ public object EhassetsGroup
public val AssetsGroup.Ehassets: EhassetsGroup public val AssetsGroup.Ehassets: EhassetsGroup
get() = EhassetsGroup get() = EhassetsGroup
@Suppress("ObjectPropertyName", "ktlint:standard:backing-property-naming")
private var __AllAssets: ____KtList<ImageVector>? = null private var __AllAssets: ____KtList<ImageVector>? = null
public val EhassetsGroup.AllAssets: ____KtList<ImageVector> public val EhassetsGroup.AllAssets: ____KtList<ImageVector>

View file

@ -88,7 +88,12 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
val raisedMeta = meta.raise<EHentaiSearchMetadata>() val raisedMeta = meta.raise<EHentaiSearchMetadata>()
// Don't update galleries too frequently // Don't update galleries too frequently
if (raisedMeta.aged || (curTime - raisedMeta.lastUpdateCheck < MIN_BACKGROUND_UPDATE_FREQ && DebugToggles.RESTRICT_EXH_GALLERY_UPDATE_CHECK_FREQUENCY.enabled)) { if (raisedMeta.aged ||
(
curTime - raisedMeta.lastUpdateCheck < MIN_BACKGROUND_UPDATE_FREQ &&
DebugToggles.RESTRICT_EXH_GALLERY_UPDATE_CHECK_FREQUENCY.enabled
)
) {
return@mapNotNull null return@mapNotNull null
} }

View file

@ -96,7 +96,8 @@ class FavoritesSyncHelper(val context: Context) {
} }
// Validate library state // Validate library state
status.value = FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_verifying_library)) status.value =
FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_verifying_library))
val libraryManga = getLibraryManga.await() val libraryManga = getLibraryManga.await()
val seenManga = HashSet<Long>(libraryManga.size) val seenManga = HashSet<Long>(libraryManga.size)
libraryManga.forEach { (manga) -> libraryManga.forEach { (manga) ->
@ -116,10 +117,12 @@ class FavoritesSyncHelper(val context: Context) {
// Download remote favorites // Download remote favorites
val favorites = try { val favorites = try {
status.value = FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_downloading)) status.value =
FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_downloading))
exh.fetchFavorites() exh.fetchFavorites()
} catch (e: Exception) { } catch (e: Exception) {
status.value = FavoritesSyncStatus.Error(context.stringResource(SYMR.strings.favorites_sync_failed_to_featch)) status.value =
FavoritesSyncStatus.Error(context.stringResource(SYMR.strings.favorites_sync_failed_to_featch))
logger.e(context.stringResource(SYMR.strings.favorites_sync_could_not_fetch), e) logger.e(context.stringResource(SYMR.strings.favorites_sync_could_not_fetch), e)
return return
} }
@ -179,7 +182,8 @@ class FavoritesSyncHelper(val context: Context) {
applyChangeSetToRemote(errorList, localChanges) applyChangeSetToRemote(errorList, localChanges)
} }
status.value = FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_cleaning_up)) status.value =
FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_cleaning_up))
storage.snapshotEntries() storage.snapshotEntries()
withUIContext { withUIContext {

View file

@ -88,7 +88,14 @@ class LocalFavoritesStorage(
private fun FavoriteEntry.urlEquals(other: FavoriteEntry) = (gid == other.gid && token == other.token) || private fun FavoriteEntry.urlEquals(other: FavoriteEntry) = (gid == other.gid && token == other.token) ||
(otherGid != null && otherToken != null && (otherGid == other.gid && otherToken == other.token)) || (otherGid != null && otherToken != null && (otherGid == other.gid && otherToken == other.token)) ||
(other.otherGid != null && other.otherToken != null && (gid == other.otherGid && token == other.otherToken)) || (other.otherGid != null && other.otherToken != null && (gid == other.otherGid && token == other.otherToken)) ||
(otherGid != null && otherToken != null && other.otherGid != null && other.otherToken != null && otherGid == other.otherGid && otherToken == other.otherToken) (
otherGid != null &&
otherToken != null &&
other.otherGid != null &&
other.otherToken != null &&
otherGid == other.otherGid &&
otherToken == other.otherToken
)
private fun queryListForEntry(list: List<FavoriteEntry>, entry: FavoriteEntry) = private fun queryListForEntry(list: List<FavoriteEntry>, entry: FavoriteEntry) =
list.find { it.urlEquals(entry) && it.category == entry.category } list.find { it.urlEquals(entry) && it.category == entry.category }

View file

@ -60,7 +60,14 @@ class EnhancedFilePrinter internal constructor(
val lastFileName = writer.lastFileName val lastFileName = writer.lastFileName
if (fileNameGenerator.isFileNameChangeable) { if (fileNameGenerator.isFileNameChangeable) {
val newFileName = fileNameGenerator.generateFileName(logLevel, System.currentTimeMillis()) val newFileName = fileNameGenerator.generateFileName(logLevel, System.currentTimeMillis())
require(!(newFileName == null || newFileName.trim { it <= ' ' }.isEmpty())) { "File name should not be empty." } require(
!(
newFileName == null ||
newFileName.trim {
it <= ' '
}.isEmpty()
),
) { "File name should not be empty." }
if (newFileName != lastFileName) { if (newFileName != lastFileName) {
if (writer.isOpened) { if (writer.isOpened) {
writer.close() writer.close()

View file

@ -133,7 +133,7 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
val duplicateManga = screenModel.getDuplicateLibraryManga(manga) val duplicateManga = screenModel.getDuplicateLibraryManga(manga)
when { when {
manga.favorite -> screenModel.setDialog( manga.favorite -> screenModel.setDialog(
BrowseSourceScreenModel.Dialog.RemoveManga(manga) BrowseSourceScreenModel.Dialog.RemoveManga(manga),
) )
duplicateManga != null -> screenModel.setDialog( duplicateManga != null -> screenModel.setDialog(
BrowseSourceScreenModel.Dialog.AddDuplicateManga( BrowseSourceScreenModel.Dialog.AddDuplicateManga(
@ -169,7 +169,7 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
dialog.duplicate.id, dialog.duplicate.id,
dialog.manga.id, dialog.manga.id,
) )
} },
) )
} }
is BrowseSourceScreenModel.Dialog.RemoveManga -> { is BrowseSourceScreenModel.Dialog.RemoveManga -> {

View file

@ -131,10 +131,14 @@ class ApiMangaParser(
// things that will go with the genre tags but aren't actually genre // things that will go with the genre tags but aren't actually genre
val nonGenres = listOfNotNull( val nonGenres = listOfNotNull(
mangaAttributesDto.publicationDemographic mangaAttributesDto.publicationDemographic
?.let { RaisedTag("Demographic", it.capitalize(Locale.US), MangaDexSearchMetadata.TAG_TYPE_DEFAULT) }, ?.let {
RaisedTag("Demographic", it.capitalize(Locale.US), MangaDexSearchMetadata.TAG_TYPE_DEFAULT)
},
mangaAttributesDto.contentRating mangaAttributesDto.contentRating
?.takeUnless { it == "safe" } ?.takeUnless { it == "safe" }
?.let { RaisedTag("Content Rating", it.capitalize(Locale.US), MangaDexSearchMetadata.TAG_TYPE_DEFAULT) }, ?.let {
RaisedTag("Content Rating", it.capitalize(Locale.US), MangaDexSearchMetadata.TAG_TYPE_DEFAULT)
},
) )
val genres = nonGenres + mangaAttributesDto.tags val genres = nonGenres + mangaAttributesDto.tags

View file

@ -36,7 +36,7 @@ class NamicomiHandler(currentClient: OkHttpClient, userAgent: String) {
val hash = data.jsonObject["hash"]!!.jsonPrimitive.content val hash = data.jsonObject["hash"]!!.jsonPrimitive.content
/* Available quality levels: source, high, medium, low */ /* Available quality levels: source, high, medium, low */
val quality = if(dataSaver) "low" else "high" val quality = if (dataSaver) "low" else "high"
return data return data
.jsonObject[quality]!! .jsonObject[quality]!!

View file

@ -15,7 +15,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.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.FormBody import okhttp3.FormBody

View file

@ -60,7 +60,11 @@ class MetadataViewScreen(
) )
}, },
) { paddingValues -> ) { paddingValues ->
when (@Suppress("NAME_SHADOWING") val state = state) { when
(
@Suppress("NAME_SHADOWING")
val state = state
) {
MetadataViewState.Loading -> LoadingScreen() MetadataViewState.Loading -> LoadingScreen()
MetadataViewState.MetadataNotFound -> EmptyScreen(MR.strings.no_results_found) MetadataViewState.MetadataNotFound -> EmptyScreen(MR.strings.no_results_found)
MetadataViewState.SourceNotFound -> EmptyScreen(MR.strings.source_empty_screen) MetadataViewState.SourceNotFound -> EmptyScreen(MR.strings.source_empty_screen)
@ -68,7 +72,8 @@ class MetadataViewScreen(
val context = LocalContext.current val context = LocalContext.current
val items = remember(state.meta) { state.meta.getExtraInfoPairs(context) } val items = remember(state.meta) { state.meta.getExtraInfoPairs(context) }
ScrollbarLazyColumn( ScrollbarLazyColumn(
contentPadding = paddingValues + WindowInsets.navigationBars.asPaddingValues() + topSmallPaddingValues, contentPadding =
paddingValues + WindowInsets.navigationBars.asPaddingValues() + topSmallPaddingValues,
) { ) {
items(items) { (title, text) -> items(items) { (title, text) ->
Row( Row(
@ -109,7 +114,7 @@ class MetadataViewScreen(
// KMK --> // KMK -->
TachiyomiTheme( TachiyomiTheme(
seedColor = seedColor?.let { Color(seedColor) }.takeIf { screenModel.themeCoverBased } seedColor = seedColor?.let { Color(seedColor) }.takeIf { screenModel.themeCoverBased },
) { ) {
// KMK <-- // KMK <--
content() content()

View file

@ -58,7 +58,11 @@ fun EHentaiDescription(
?: meta.genre ?: meta.genre
?: context.stringResource(MR.strings.unknown) ?: context.stringResource(MR.strings.unknown)
binding.visible.text = context.stringResource(SYMR.strings.is_visible, meta.visible ?: context.stringResource(MR.strings.unknown)) binding.visible.text =
context.stringResource(
SYMR.strings.is_visible,
meta.visible ?: context.stringResource(MR.strings.unknown),
)
// KMK --> // KMK -->
binding.visible.setTextColor(textColor) binding.visible.setTextColor(textColor)
// KMK <-- // KMK <--
@ -100,7 +104,8 @@ fun EHentaiDescription(
val ratingFloat = meta.averageRating?.toFloat() val ratingFloat = meta.averageRating?.toFloat()
binding.ratingBar.rating = ratingFloat ?: 0F binding.ratingBar.rating = ratingFloat ?: 0F
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
binding.rating.text = (ratingFloat ?: 0F).toString() + " - " + MetadataUIUtil.getRatingString(context, ratingFloat?.times(2)) binding.rating.text =
(ratingFloat ?: 0F).toString() + " - " + MetadataUIUtil.getRatingString(context, ratingFloat?.times(2))
// KMK --> // KMK -->
binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor) binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor)
binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor) binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor)

View file

@ -36,7 +36,8 @@ fun HBrowseDescription(state: State.Success, openMetadataViewer: () -> Unit) {
if (meta == null || meta !is HBrowseSearchMetadata) return@AndroidView if (meta == null || meta !is HBrowseSearchMetadata) return@AndroidView
val binding = DescriptionAdapterHbBinding.bind(it) val binding = DescriptionAdapterHbBinding.bind(it)
binding.pages.text = context.pluralStringResource(SYMR.plurals.num_pages, meta.length ?: 0, meta.length ?: 0) binding.pages.text =
context.pluralStringResource(SYMR.plurals.num_pages, meta.length ?: 0, meta.length ?: 0)
// KMK --> // KMK -->
binding.pages.bindDrawable(context, R.drawable.ic_baseline_menu_book_24, iconColor) binding.pages.bindDrawable(context, R.drawable.ic_baseline_menu_book_24, iconColor)
binding.pages.setTextColor(textColor) binding.pages.setTextColor(textColor)

View file

@ -45,7 +45,8 @@ fun MangaDexDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val ratingFloat = meta.rating val ratingFloat = meta.rating
binding.ratingBar.rating = ratingFloat?.div(2F) ?: 0F binding.ratingBar.rating = ratingFloat?.div(2F) ?: 0F
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
binding.rating.text = (round((ratingFloat ?: 0F) * 100.0) / 100.0).toString() + " - " + getRatingString(context, ratingFloat) binding.rating.text =
(round((ratingFloat ?: 0F) * 100.0) / 100.0).toString() + " - " + getRatingString(context, ratingFloat)
binding.rating.isVisible = ratingFloat != null binding.rating.isVisible = ratingFloat != null
binding.ratingBar.isVisible = ratingFloat != null binding.ratingBar.isVisible = ratingFloat != null
// KMK --> // KMK -->

View file

@ -70,7 +70,7 @@ fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
binding.whenPosted.text = MetadataUtil.EX_DATE_FORMAT binding.whenPosted.text = MetadataUtil.EX_DATE_FORMAT
.format( .format(
ZonedDateTime ZonedDateTime
.ofInstant(Instant.ofEpochSecond(meta.uploadDate ?: 0), ZoneId.systemDefault()) .ofInstant(Instant.ofEpochSecond(meta.uploadDate ?: 0), ZoneId.systemDefault()),
) )
// KMK --> // KMK -->
binding.whenPosted.setTextColor(textColor) binding.whenPosted.setTextColor(textColor)

View file

@ -42,16 +42,17 @@ fun PururinDescription(state: State.Success, openMetadataViewer: () -> Unit) {
if (meta == null || meta !is PururinSearchMetadata) return@AndroidView if (meta == null || meta !is PururinSearchMetadata) return@AndroidView
val binding = DescriptionAdapterPuBinding.bind(it) val binding = DescriptionAdapterPuBinding.bind(it)
binding.genre.text = meta.tags.find { it.namespace == PururinSearchMetadata.TAG_NAMESPACE_CATEGORY }.let { genre -> binding.genre.text =
genre?.let { tag -> MetadataUIUtil.getGenreAndColour(context, tag.name) } meta.tags.find { it.namespace == PururinSearchMetadata.TAG_NAMESPACE_CATEGORY }.let { genre ->
?.let { (genre, name) -> genre?.let { tag -> MetadataUIUtil.getGenreAndColour(context, tag.name) }
binding.genre.setBackgroundColor(genre.color) ?.let { (genre, name) ->
// KMK --> binding.genre.setBackgroundColor(genre.color)
binding.genre.setTextColor(genreTextColor(genre)) // KMK -->
// KMK <-- binding.genre.setTextColor(genreTextColor(genre))
name // KMK <--
} ?: genre?.name ?: context.stringResource(MR.strings.unknown) name
} } ?: genre?.name ?: context.stringResource(MR.strings.unknown)
}
binding.uploader.text = meta.uploaderDisp ?: meta.uploader.orEmpty() binding.uploader.text = meta.uploaderDisp ?: meta.uploader.orEmpty()
// KMK --> // KMK -->
@ -73,7 +74,9 @@ fun PururinDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val ratingFloat = meta.averageRating?.toFloat() val ratingFloat = meta.averageRating?.toFloat()
binding.ratingBar.rating = ratingFloat ?: 0F binding.ratingBar.rating = ratingFloat ?: 0F
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
binding.rating.text = (round((ratingFloat ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUIUtil.getRatingString(context, ratingFloat?.times(2)) binding.rating.text =
(round((ratingFloat ?: 0F) * 100.0) / 100.0).toString() + " - " +
MetadataUIUtil.getRatingString(context, ratingFloat?.times(2))
// KMK --> // KMK -->
binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor) binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor)
binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor) binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor)

View file

@ -68,7 +68,8 @@ fun TsuminoDescription(state: State.Success, openMetadataViewer: () -> Unit) {
binding.uploader.setTextColor(textColor) binding.uploader.setTextColor(textColor)
// KMK <-- // KMK <--
binding.pages.text = context.pluralStringResource(SYMR.plurals.num_pages, meta.length ?: 0, meta.length ?: 0) binding.pages.text =
context.pluralStringResource(SYMR.plurals.num_pages, meta.length ?: 0, meta.length ?: 0)
// KMK --> // KMK -->
binding.pages.bindDrawable(context, R.drawable.ic_baseline_menu_book_24, iconColor) binding.pages.bindDrawable(context, R.drawable.ic_baseline_menu_book_24, iconColor)
binding.pages.setTextColor(textColor) binding.pages.setTextColor(textColor)
@ -76,7 +77,9 @@ fun TsuminoDescription(state: State.Success, openMetadataViewer: () -> Unit) {
binding.ratingBar.rating = meta.averageRating ?: 0F binding.ratingBar.rating = meta.averageRating ?: 0F
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
binding.rating.text = (round((meta.averageRating ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUIUtil.getRatingString(context, meta.averageRating?.times(2)) binding.rating.text =
(round((meta.averageRating ?: 0F) * 100.0) / 100.0).toString() + " - " +
MetadataUIUtil.getRatingString(context, meta.averageRating?.times(2))
// KMK --> // KMK -->
binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor) binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor)
binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor) binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor)

View file

@ -92,20 +92,21 @@ private class WsrvNlDataSaver(preferences: SourcePreferences) : DataSaver {
private fun getUrl(imageUrl: String): String { private fun getUrl(imageUrl: String): String {
// Network Request sent to wsrv // Network Request sent to wsrv
return "https://wsrv.nl/?url=$imageUrl" + if (imageUrl.contains(".webp", true) || imageUrl.contains(".gif", true)) { return "https://wsrv.nl/?url=$imageUrl" +
if (!format) { if (imageUrl.contains(".webp", true) || imageUrl.contains(".gif", true)) {
// Preserve output image extension for animated images(.webp and .gif) if (!format) {
"&q=$quality&n=-1" // Preserve output image extension for animated images(.webp and .gif)
"&q=$quality&n=-1"
} else {
// Do not preserve output Extension if User asked to convert into Jpeg
"&output=jpg&q=$quality&n=-1"
}
} else { } else {
// Do not preserve output Extension if User asked to convert into Jpeg if (format) {
"&output=jpg&q=$quality&n=-1" "&output=jpg&q=$quality"
} else {
"&output=webp&q=$quality"
}
} }
} else {
if (format) {
"&output=jpg&q=$quality"
} else {
"&output=webp&q=$quality"
}
}
} }
} }

View file

@ -1,7 +1,11 @@
package exh.util package exh.util
inline fun <T> ignore(expr: () -> T): T? { inline fun <T> ignore(expr: () -> T): T? {
return try { expr() } catch (t: Throwable) { null } return try {
expr()
} catch (t: Throwable) {
null
}
} }
fun <T : Throwable> T.withRootCause(cause: Throwable): T { fun <T : Throwable> T.withRootCause(cause: Throwable): T {

Some files were not shown because too many files have changed in this diff Show more