add KMK comment

This commit is contained in:
Tran M. Cuong 2024-06-16 19:09:17 +07:00
parent 854ea8c7f0
commit 7a99a9a9b5
No known key found for this signature in database
GPG key ID: 733AA7624B9315C2
79 changed files with 517 additions and 70 deletions

View file

@ -13,7 +13,9 @@ class TrustExtension(
) { ) {
suspend fun isTrusted(pkgInfo: PackageInfo, fingerprints: List<String>): Boolean { suspend fun isTrusted(pkgInfo: PackageInfo, fingerprints: List<String>): Boolean {
// KMK -->
if (fingerprints.contains(CreateExtensionRepo.OFFICIAL_REPO_SIGNATURE)) return true if (fingerprints.contains(CreateExtensionRepo.OFFICIAL_REPO_SIGNATURE)) return true
// KMK <--
val trustedFingerprints = extensionRepoRepository.getAll().map { it.signingKeyFingerprint }.toHashSet() val trustedFingerprints = extensionRepoRepository.getAll().map { it.signingKeyFingerprint }.toHashSet()
val key = "${pkgInfo.packageName}:${PackageInfoCompat.getLongVersionCode(pkgInfo)}:${fingerprints.last()}" val key = "${pkgInfo.packageName}:${PackageInfoCompat.getLongVersionCode(pkgInfo)}:${fingerprints.last()}"
return trustedFingerprints.any { fingerprints.contains(it) } || key in preferences.trustedExtensions().get() return trustedFingerprints.any { fingerprints.contains(it) } || key in preferences.trustedExtensions().get()

View file

@ -19,6 +19,7 @@ class SyncChapterProgressWithTrack(
private val getChaptersByMangaId: GetChaptersByMangaId, private val getChaptersByMangaId: GetChaptersByMangaId,
) { ) {
val trackPreferences: TrackPreferences = Injekt.get() val trackPreferences: TrackPreferences = Injekt.get()
suspend fun await( suspend fun await(
mangaId: Long, mangaId: Long,
remoteTrack: Track, remoteTrack: Track,
@ -32,12 +33,15 @@ class SyncChapterProgressWithTrack(
// Current chapters in database // Current chapters in database
val dbChapters = getChaptersByMangaId.await(mangaId) val dbChapters = getChaptersByMangaId.await(mangaId)
// KMK -->
.reversed() .reversed()
// KMK <--
.filter { it.isRecognizedNumber } .filter { it.isRecognizedNumber }
val sortedChapters = dbChapters val sortedChapters = dbChapters
.sortedBy { it.chapterNumber } .sortedBy { it.chapterNumber }
// KMK -->
// Chapters to update to follow tracker: only continuous incremental chapters // Chapters to update to follow tracker: only continuous incremental chapters
// any abnormal chapter number will stop it from updating read status further // any abnormal chapter number will stop it from updating read status further
var lastCheckChapter: Double var lastCheckChapter: Double
@ -49,6 +53,7 @@ class SyncChapterProgressWithTrack(
chapter.chapterNumber >= lastCheckChapter && chapter.chapterNumber <= remoteTrack.lastChapterRead chapter.chapterNumber >= lastCheckChapter && chapter.chapterNumber <= remoteTrack.lastChapterRead
} }
.filter { chapter -> !chapter.read } .filter { chapter -> !chapter.read }
// KMK <--
.map { it.copy(read = true).toChapterUpdate() } .map { it.copy(read = true).toChapterUpdate() }
// only take into account continuous reading // only take into account continuous reading

View file

@ -35,6 +35,10 @@ class TrackPreferences(
fun anilistScoreType() = preferenceStore.getString("anilist_score_type", Anilist.POINT_10) fun anilistScoreType() = preferenceStore.getString("anilist_score_type", Anilist.POINT_10)
fun autoUpdateTrack() = preferenceStore.getBoolean("pref_auto_update_manga_sync_key", true) fun autoUpdateTrack() = preferenceStore.getBoolean("pref_auto_update_manga_sync_key", true)
// KMK -->
fun updateTrackMarkedRead() = preferenceStore.getBoolean("pref_update_tracking_marked_read_key", false) fun updateTrackMarkedRead() = preferenceStore.getBoolean("pref_update_tracking_marked_read_key", false)
fun autoSyncReadChapters() = preferenceStore.getBoolean("pref_auto_sync_read_chapters_key", false) fun autoSyncReadChapters() = preferenceStore.getBoolean("pref_auto_sync_read_chapters_key", false)
// KMK <--
} }

View file

@ -25,9 +25,11 @@ class UiPreferences(
fun themeDarkAmoled() = preferenceStore.getBoolean("pref_theme_dark_amoled_key", false) fun themeDarkAmoled() = preferenceStore.getBoolean("pref_theme_dark_amoled_key", false)
// KMK -->
fun themeCoverBased() = preferenceStore.getBoolean("pref_theme_cover_based_key", true) fun themeCoverBased() = preferenceStore.getBoolean("pref_theme_cover_based_key", true)
fun themeCoverBasedStyle() = preferenceStore.getEnum("pref_theme_cover_based_style_key", PaletteStyle.Vibrant) fun themeCoverBasedStyle() = preferenceStore.getEnum("pref_theme_cover_based_style_key", PaletteStyle.Vibrant)
// KMK <--
fun relativeTime() = preferenceStore.getBoolean("relative_time_v2", true) fun relativeTime() = preferenceStore.getBoolean("relative_time_v2", true)
@ -43,7 +45,9 @@ class UiPreferences(
fun feedTabInFront() = preferenceStore.getBoolean("latest_tab_position", false) fun feedTabInFront() = preferenceStore.getBoolean("latest_tab_position", false)
// KMK -->
fun expandRelatedTitles() = preferenceStore.getBoolean("expand_related_titles", true) fun expandRelatedTitles() = preferenceStore.getBoolean("expand_related_titles", true)
// KMK <--
fun recommendsInOverflow() = preferenceStore.getBoolean("recommends_in_overflow", true) fun recommendsInOverflow() = preferenceStore.getBoolean("recommends_in_overflow", true)

View file

@ -70,8 +70,10 @@ fun ExtensionDetailsScreen(
navigateUp: () -> Unit, navigateUp: () -> Unit,
state: ExtensionDetailsScreenModel.State, state: ExtensionDetailsScreenModel.State,
onClickSourcePreferences: (sourceId: Long) -> Unit, onClickSourcePreferences: (sourceId: Long) -> Unit,
// KMK -->
onClickWhatsNew: () -> Unit, onClickWhatsNew: () -> Unit,
onClickReadme: () -> Unit, onClickReadme: () -> Unit,
// KMK <--
onClickEnableAll: () -> Unit, onClickEnableAll: () -> Unit,
onClickDisableAll: () -> Unit, onClickDisableAll: () -> Unit,
onClickClearCookies: () -> Unit, onClickClearCookies: () -> Unit,

View file

@ -59,9 +59,9 @@ private fun ExtensionFilterContent(
items(state.languages) { language -> items(state.languages) { language ->
SwitchPreferenceWidget( SwitchPreferenceWidget(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemPlacement(),
title = LocaleHelper.getSourceDisplayName(language, context) title = LocaleHelper.getSourceDisplayName(language, context) +
// KMK --> // KMK -->
+ " (${LocaleHelper.getDisplayName(language)})", " (${LocaleHelper.getDisplayName(language)})",
// KMK <-- // KMK <--
checked = language in state.enabledLanguages, checked = language in state.enabledLanguages,
onCheckedChanged = { onClickLang(language) }, onCheckedChanged = { onClickLang(language) },

View file

@ -210,12 +210,15 @@ fun FeedAddSearchDialog(
val context = LocalContext.current val context = LocalContext.current
val savedSearchStrings = remember { val savedSearchStrings = remember {
savedSearches.map { savedSearches.map {
// KMK --> it?.name
it?.name ?: if (source.supportsLatest) { // KMK -->
context.stringResource(MR.strings.latest) ?: if (source.supportsLatest) {
} else { // KMK <--
context.stringResource(MR.strings.popular) context.stringResource(MR.strings.latest)
} // KMK -->
} else {
context.stringResource(MR.strings.popular)
}
// KMK <-- // KMK <--
}.toImmutableList() }.toImmutableList()
} }
@ -244,8 +247,8 @@ fun FeedAddSearchDialog(
@Composable @Composable
fun <T> RadioSelector( fun <T> RadioSelector(
options: ImmutableList<T>, options: ImmutableList<T>,
selected: Int?,
optionStrings: ImmutableList<String> = remember { options.map { it.toString() }.toImmutableList() }, optionStrings: ImmutableList<String> = remember { options.map { it.toString() }.toImmutableList() },
selected: Int?,
onSelectOption: (Int) -> Unit = {}, onSelectOption: (Int) -> Unit = {},
) { ) {
Column(Modifier.verticalScroll(rememberScrollState())) { Column(Modifier.verticalScroll(rememberScrollState())) {

View file

@ -98,7 +98,10 @@ fun SourcesScreen(
when { when {
state.isLoading -> LoadingScreen(Modifier.padding(contentPadding)) state.isLoading -> LoadingScreen(Modifier.padding(contentPadding))
state.isEmpty && state.searchQuery.isNullOrBlank() -> EmptyScreen( // KMK -->
state.searchQuery.isNullOrBlank() &&
// KMK <--
state.isEmpty -> EmptyScreen(
MR.strings.source_empty_screen, MR.strings.source_empty_screen,
modifier = Modifier.padding(contentPadding), modifier = Modifier.padding(contentPadding),
) )

View file

@ -57,9 +57,11 @@ private val defaultContent: @Composable RowScope.(Source, String?) -> Unit = { s
Text( Text(
text = source.name + text = source.name +
// KMK --> // KMK -->
(source.installedExtension?.let { extension -> (
" (${extension.name})".takeIf {extension.name != source.name } source.installedExtension?.let { extension ->
} ?: ""), " (${extension.name})".takeIf { extension.name != source.name }
} ?: ""
),
// KMK <-- // KMK <--
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,

View file

@ -99,11 +99,10 @@ internal fun BrowseSourceComfortableGridItem(
ogUrl = manga.thumbnailUrl, ogUrl = manga.thumbnailUrl,
lastModified = manga.coverLastModified, lastModified = manga.coverLastModified,
), ),
// KMK -->
isSelected = isSelected, isSelected = isSelected,
coverAlpha = when { // KMK <--
manga.favorite -> CommonMangaItemDefaults.BrowseFavoriteCoverAlpha coverAlpha = if (manga.favorite) CommonMangaItemDefaults.BrowseFavoriteCoverAlpha else 1f,
else -> 1f
},
coverBadgeStart = { coverBadgeStart = {
InLibraryBadge(enabled = manga.favorite) InLibraryBadge(enabled = manga.favorite)
}, },

View file

@ -99,11 +99,10 @@ internal fun BrowseSourceCompactGridItem(
ogUrl = manga.thumbnailUrl, ogUrl = manga.thumbnailUrl,
lastModified = manga.coverLastModified, lastModified = manga.coverLastModified,
), ),
// KMK -->
isSelected = isSelected, isSelected = isSelected,
coverAlpha = when { // KMK <--
manga.favorite -> CommonMangaItemDefaults.BrowseFavoriteCoverAlpha coverAlpha = if (manga.favorite) CommonMangaItemDefaults.BrowseFavoriteCoverAlpha else 1f,
else -> 1f
},
coverBadgeStart = { coverBadgeStart = {
InLibraryBadge(enabled = manga.favorite) InLibraryBadge(enabled = manga.favorite)
}, },

View file

@ -92,11 +92,10 @@ internal fun BrowseSourceListItem(
ogUrl = manga.thumbnailUrl, ogUrl = manga.thumbnailUrl,
lastModified = manga.coverLastModified, lastModified = manga.coverLastModified,
), ),
// KMK -->
isSelected = isSelected, isSelected = isSelected,
coverAlpha = when { // KMK <--
manga.favorite -> CommonMangaItemDefaults.BrowseFavoriteCoverAlpha coverAlpha = if (manga.favorite) CommonMangaItemDefaults.BrowseFavoriteCoverAlpha else 1f,
else -> 1f
},
badge = { badge = {
InLibraryBadge(enabled = manga.favorite) InLibraryBadge(enabled = manga.favorite)
// SY --> // SY -->

View file

@ -78,11 +78,10 @@ internal fun MangaItem(
coverBadgeStart = { coverBadgeStart = {
InLibraryBadge(enabled = isFavorite) InLibraryBadge(enabled = isFavorite)
}, },
// KMK -->
isSelected = isSelected, isSelected = isSelected,
coverAlpha = when { // KMK <--
isFavorite -> CommonMangaItemDefaults.BrowseFavoriteCoverAlpha coverAlpha = if (isFavorite) CommonMangaItemDefaults.BrowseFavoriteCoverAlpha else 1f,
else -> 1f
},
onClick = onClick, onClick = onClick,
onLongClick = onLongClick, onLongClick = onLongClick,
) )

View file

@ -49,15 +49,19 @@ fun HistoryItem(
.padding(horizontal = MaterialTheme.padding.medium, vertical = MaterialTheme.padding.small), .padding(horizontal = MaterialTheme.padding.medium, vertical = MaterialTheme.padding.small),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
// KMK -->
val mangaCover = history.coverData val mangaCover = history.coverData
val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) } val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) }
val onBgColor = mangaCover.dominantCoverColors?.second val onBgColor = mangaCover.dominantCoverColors?.second
// KMK <--
MangaCover.Book( MangaCover.Book(
modifier = Modifier.fillMaxHeight(), modifier = Modifier.fillMaxHeight(),
data = mangaCover, data = mangaCover,
onClick = onClickCover, onClick = onClickCover,
// KMK -->
bgColor = bgColor, bgColor = bgColor,
tint = onBgColor, tint = onBgColor,
// KMK <--
) )
Column( Column(
modifier = Modifier modifier = Modifier

View file

@ -71,10 +71,14 @@ fun MangaCompactGridItem(
coverAlpha: Float = 1f, coverAlpha: Float = 1f,
coverBadgeStart: @Composable (RowScope.() -> Unit)? = null, coverBadgeStart: @Composable (RowScope.() -> Unit)? = null,
coverBadgeEnd: @Composable (RowScope.() -> Unit)? = null, coverBadgeEnd: @Composable (RowScope.() -> Unit)? = null,
// KMK -->
libraryColored: Boolean? = null, libraryColored: Boolean? = null,
// KMK <--
) { ) {
// KMK -->
val bgColor = libraryColored?.let { coverData.dominantCoverColors?.first?.let { Color(it) } } val bgColor = libraryColored?.let { coverData.dominantCoverColors?.first?.let { Color(it) } }
val onBgColor = libraryColored?.let { coverData.dominantCoverColors?.second } val onBgColor = libraryColored?.let { coverData.dominantCoverColors?.second }
// KMK <--
GridItemSelectable( GridItemSelectable(
isSelected = isSelected, isSelected = isSelected,
onClick = onClick, onClick = onClick,
@ -84,11 +88,16 @@ fun MangaCompactGridItem(
cover = { cover = {
MangaCover.Book( MangaCover.Book(
modifier = Modifier modifier = Modifier
// KMK -->
// .alpha(if (isSelected) GridSelectedCoverAlpha else coverAlpha)
// KMK <--
.fillMaxWidth(), .fillMaxWidth(),
alpha = if (isSelected) GridSelectedCoverAlpha else coverAlpha,
data = coverData, data = coverData,
// KMK -->
alpha = if (isSelected) GridSelectedCoverAlpha else coverAlpha,
bgColor = bgColor, bgColor = bgColor,
tint = onBgColor, tint = onBgColor,
// KMK <--
) )
}, },
badgesStart = coverBadgeStart, badgesStart = coverBadgeStart,
@ -178,10 +187,14 @@ fun MangaComfortableGridItem(
coverBadgeStart: (@Composable RowScope.() -> Unit)? = null, coverBadgeStart: (@Composable RowScope.() -> Unit)? = null,
coverBadgeEnd: (@Composable RowScope.() -> Unit)? = null, coverBadgeEnd: (@Composable RowScope.() -> Unit)? = null,
onClickContinueReading: (() -> Unit)? = null, onClickContinueReading: (() -> Unit)? = null,
// KMK -->
libraryColored: Boolean? = null, libraryColored: Boolean? = null,
// KMK <--
) { ) {
// KMK -->
val bgColor = libraryColored?.let { coverData.dominantCoverColors?.first?.let { Color(it) } } val bgColor = libraryColored?.let { coverData.dominantCoverColors?.first?.let { Color(it) } }
val onBgColor = libraryColored?.let { coverData.dominantCoverColors?.second } val onBgColor = libraryColored?.let { coverData.dominantCoverColors?.second }
// KMK <--
GridItemSelectable( GridItemSelectable(
isSelected = isSelected, isSelected = isSelected,
onClick = onClick, onClick = onClick,
@ -192,11 +205,16 @@ fun MangaComfortableGridItem(
cover = { cover = {
MangaCover.Book( MangaCover.Book(
modifier = Modifier modifier = Modifier
// KMK -->
// .alpha(if (isSelected) GridSelectedCoverAlpha else coverAlpha)
// KMK <--
.fillMaxWidth(), .fillMaxWidth(),
alpha = if (isSelected) GridSelectedCoverAlpha else coverAlpha,
data = coverData, data = coverData,
// KMK -->
alpha = if (isSelected) GridSelectedCoverAlpha else coverAlpha,
bgColor = bgColor, bgColor = bgColor,
tint = onBgColor, tint = onBgColor,
// KMK <--
) )
}, },
badgesStart = coverBadgeStart, badgesStart = coverBadgeStart,
@ -334,10 +352,14 @@ fun MangaListItem(
isSelected: Boolean = false, isSelected: Boolean = false,
coverAlpha: Float = 1f, coverAlpha: Float = 1f,
onClickContinueReading: (() -> Unit)? = null, onClickContinueReading: (() -> Unit)? = null,
// KMK -->
libraryColored: Boolean? = null, libraryColored: Boolean? = null,
// KMK <--
) { ) {
// KMK -->
val bgColor = libraryColored?.let { coverData.dominantCoverColors?.first?.let { Color(it) } } val bgColor = libraryColored?.let { coverData.dominantCoverColors?.first?.let { Color(it) } }
val onBgColor = libraryColored?.let { coverData.dominantCoverColors?.second } val onBgColor = libraryColored?.let { coverData.dominantCoverColors?.second }
// KMK <--
Row( Row(
modifier = Modifier modifier = Modifier
.selectedBackground(isSelected) .selectedBackground(isSelected)
@ -351,11 +373,16 @@ fun MangaListItem(
) { ) {
MangaCover.Square( MangaCover.Square(
modifier = Modifier modifier = Modifier
// KMK -->
// .alpha(coverAlpha)
// KMK <--
.fillMaxHeight(), .fillMaxHeight(),
alpha = coverAlpha,
data = coverData, data = coverData,
// KMK -->
alpha = coverAlpha,
bgColor = bgColor, bgColor = bgColor,
tint = onBgColor, tint = onBgColor,
// KMK <--
) )
Text( Text(
text = title, text = title,

View file

@ -61,7 +61,9 @@ internal fun LibraryComfortableGrid(
} else { } else {
null null
}, },
// KMK -->
libraryColored = true, libraryColored = true,
// KMK <--
) )
} }
} }

View file

@ -62,7 +62,9 @@ internal fun LibraryCompactGrid(
} else { } else {
null null
}, },
// KMK -->
libraryColored = true, libraryColored = true,
// KMK <--
) )
} }
} }

View file

@ -69,7 +69,9 @@ internal fun LibraryList(
} else { } else {
null null
}, },
// KMK -->
libraryColored = true, libraryColored = true,
// KMK <--
) )
} }
} }

View file

@ -445,7 +445,9 @@ private fun MangaScreenSmallImpl(
actionModeCounter = selectedChapterCount, actionModeCounter = selectedChapterCount,
onSelectAll = { onAllChapterSelected(true) }, onSelectAll = { onAllChapterSelected(true) },
onInvertSelection = { onInvertSelection() }, onInvertSelection = { onInvertSelection() },
// KMK -->
onPaletteScreenClick = onPaletteScreenClick, onPaletteScreenClick = onPaletteScreenClick,
// KMK <--
) )
}, },
bottomBar = { bottomBar = {
@ -669,7 +671,9 @@ private fun MangaScreenSmallImpl(
chapterCount = chapters.size, chapterCount = chapters.size,
missingChapterCount = missingChapterCount, missingChapterCount = missingChapterCount,
onClick = onFilterClicked, onClick = onFilterClicked,
// KMK -->
hasFilters = state.filterActive, hasFilters = state.filterActive,
// KMK <--
) )
} }
@ -820,7 +824,9 @@ private fun MangaScreenLargeImpl(
actionModeCounter = selectedChapterCount, actionModeCounter = selectedChapterCount,
onSelectAll = { onAllChapterSelected(true) }, onSelectAll = { onAllChapterSelected(true) },
onInvertSelection = { onInvertSelection() }, onInvertSelection = { onInvertSelection() },
// KMK -->
onPaletteScreenClick = onPaletteScreenClick, onPaletteScreenClick = onPaletteScreenClick,
// KMK <--
) )
}, },
bottomBar = { bottomBar = {
@ -1029,7 +1035,9 @@ private fun MangaScreenLargeImpl(
chapterCount = chapters.size, chapterCount = chapters.size,
missingChapterCount = missingChapterCount, missingChapterCount = missingChapterCount,
onClick = onFilterButtonClicked, onClick = onFilterButtonClicked,
// KMK -->
hasFilters = state.filterActive, hasFilters = state.filterActive,
// KMK <--
) )
} }

View file

@ -102,7 +102,7 @@ private fun NotDownloadedIndicator(
painter = painterResource(R.drawable.ic_download_chapter_24dp), painter = painterResource(R.drawable.ic_download_chapter_24dp),
contentDescription = stringResource(MR.strings.manga_download), contentDescription = stringResource(MR.strings.manga_download),
modifier = Modifier.size(IndicatorSize), modifier = Modifier.size(IndicatorSize),
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary, // KMK: onSurfaceVariant
) )
} }
} }
@ -128,7 +128,7 @@ private fun DownloadingIndicator(
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,
) { ) {
val arrowColor: Color val arrowColor: Color
val strokeColor = MaterialTheme.colorScheme.primary val strokeColor = MaterialTheme.colorScheme.primary // KMK: onSurfaceVariant
val downloadProgress = downloadProgressProvider() val downloadProgress = downloadProgressProvider()
val indeterminate = downloadState == Download.State.QUEUE || val indeterminate = downloadState == Download.State.QUEUE ||
(downloadState == Download.State.DOWNLOADING && downloadProgress == 0) (downloadState == Download.State.DOWNLOADING && downloadProgress == 0)
@ -208,7 +208,7 @@ private fun DownloadedIndicator(
imageVector = Icons.Filled.CheckCircle, imageVector = Icons.Filled.CheckCircle,
contentDescription = null, contentDescription = null,
modifier = Modifier.size(IndicatorSize), modifier = Modifier.size(IndicatorSize),
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary, // KMK: onSurfaceVariant
) )
DropdownMenu(expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false }) { DropdownMenu(expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false }) {
DropdownMenuItem( DropdownMenuItem(

View file

@ -29,11 +29,15 @@ fun ChapterHeader(
chapterCount: Int?, chapterCount: Int?,
missingChapterCount: Int, missingChapterCount: Int,
onClick: () -> Unit, onClick: () -> Unit,
// KMK -->
hasFilters: Boolean, hasFilters: Boolean,
// KMK <--
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
// KMK -->
val filterTint = if (hasFilters) MaterialTheme.colorScheme.active else MaterialTheme.colorScheme.primary val filterTint = if (hasFilters) MaterialTheme.colorScheme.active else MaterialTheme.colorScheme.primary
Row( Row(
// KMK <--
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.clickable( .clickable(
@ -41,9 +45,11 @@ fun ChapterHeader(
onClick = onClick, onClick = onClick,
) )
.padding(horizontal = 16.dp, vertical = 4.dp), .padding(horizontal = 16.dp, vertical = 4.dp),
// KMK -->
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
// KMK <--
Column( Column(
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall), verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall),
) { ) {
@ -60,11 +66,13 @@ fun ChapterHeader(
MissingChaptersWarning(missingChapterCount) MissingChaptersWarning(missingChapterCount)
} }
// KMK -->
Icon( Icon(
imageVector = Icons.Outlined.FilterList, imageVector = Icons.Outlined.FilterList,
contentDescription = null, contentDescription = null,
tint = filterTint, tint = filterTint,
) )
// KMK <--
} }
} }

View file

@ -41,11 +41,14 @@ enum class MangaCover(val ratio: Float) {
contentDescription: String = "", contentDescription: String = "",
shape: Shape = MaterialTheme.shapes.extraSmall, shape: Shape = MaterialTheme.shapes.extraSmall,
onClick: (() -> Unit)? = null, onClick: (() -> Unit)? = null,
// KMK -->
alpha: Float = 1f, alpha: Float = 1f,
bgColor: Color? = null, bgColor: Color? = null,
@ColorInt tint: Int? = null, @ColorInt tint: Int? = null,
onCoverLoaded: ((DomainMangaCover) -> Unit)? = null, onCoverLoaded: ((DomainMangaCover) -> Unit)? = null,
// KMK <--
) { ) {
// KMK -->
val animatedImageVector = AnimatedImageVector.animatedVectorResource(R.drawable.anim_waiting) val animatedImageVector = AnimatedImageVector.animatedVectorResource(R.drawable.anim_waiting)
var atEnd by remember { mutableStateOf(false) } var atEnd by remember { mutableStateOf(false) }
@ -61,9 +64,12 @@ enum class MangaCover(val ratio: Float) {
} }
var succeed by remember { mutableStateOf(false) } var succeed by remember { mutableStateOf(false) }
// KMK <--
AsyncImage( AsyncImage(
model = data, model = data,
// KMK -->
// placeholder = ColorPainter(CoverPlaceholderColor),
placeholder = rememberAnimatedVectorPainter(animatedImageVector = animatedImageVector, atEnd = atEnd), placeholder = rememberAnimatedVectorPainter(animatedImageVector = animatedImageVector, atEnd = atEnd),
error = rememberResourceBitmapPainter(id = R.drawable.cover_error, tint), error = rememberResourceBitmapPainter(id = R.drawable.cover_error, tint),
fallback = rememberResourceBitmapPainter(id = R.drawable.cover_error, tint), fallback = rememberResourceBitmapPainter(id = R.drawable.cover_error, tint),
@ -76,12 +82,15 @@ enum class MangaCover(val ratio: Float) {
} }
} }
}, },
// KMK <--
contentDescription = contentDescription, contentDescription = contentDescription,
modifier = modifier modifier = modifier
.aspectRatio(ratio) .aspectRatio(ratio)
.clip(shape) .clip(shape)
// KMK -->
.alpha(if (succeed) alpha else 1f) .alpha(if (succeed) alpha else 1f)
.background(bgColor ?: Color.Transparent) .background(bgColor ?: Color.Transparent)
// KMK <--
.then( .then(
if (onClick != null) { if (onClick != null) {
Modifier.clickable( Modifier.clickable(

View file

@ -132,12 +132,17 @@ fun MangaInfoBox(
drawRect( drawRect(
brush = Brush.verticalGradient( brush = Brush.verticalGradient(
colors = backdropGradientColors, colors = backdropGradientColors,
// KMK -->
startY = size.height / 2, startY = size.height / 2,
// KMKM <--
), ),
) )
} }
// KMK -->
.background(MaterialTheme.colorScheme.surfaceTint.copy(alpha = 0.4f)) .background(MaterialTheme.colorScheme.surfaceTint.copy(alpha = 0.4f))
.blur(7.dp) .blur(7.dp)
// .blur(4.dp)
// KMK <--
.alpha(0.2f), .alpha(0.2f),
) )
@ -234,7 +239,11 @@ fun MangaActionRow(
) )
}, },
icon = Icons.Default.HourglassEmpty, icon = Icons.Default.HourglassEmpty,
color = if (isUserIntervalMode || nextUpdateDays?.let { it <= 1 } == true) { color = if (isUserIntervalMode ||
// KMK -->
nextUpdateDays?.let { it <= 1 } == true
// KMK <--
) {
MaterialTheme.colorScheme.primary MaterialTheme.colorScheme.primary
} else { } else {
defaultActionButtonColor defaultActionButtonColor
@ -255,7 +264,7 @@ fun MangaActionRow(
MangaActionButton( MangaActionButton(
title = stringResource(MR.strings.action_web_view), title = stringResource(MR.strings.action_web_view),
icon = Icons.Outlined.Public, icon = Icons.Outlined.Public,
color = MaterialTheme.colorScheme.primary, color = MaterialTheme.colorScheme.primary, // KMK: defaultActionButtonColor
onClick = onWebViewClicked, onClick = onWebViewClicked,
onLongClick = onWebViewLongClicked, onLongClick = onWebViewLongClicked,
) )
@ -265,7 +274,7 @@ fun MangaActionRow(
MangaActionButton( MangaActionButton(
title = stringResource(SYMR.strings.merge), title = stringResource(SYMR.strings.merge),
icon = Icons.AutoMirrored.Outlined.CallMerge, icon = Icons.AutoMirrored.Outlined.CallMerge,
color = MaterialTheme.colorScheme.primary, color = MaterialTheme.colorScheme.primary, // KMK: defaultActionButtonColor
onClick = onMergeClicked, onClick = onMergeClicked,
) )
} }
@ -286,8 +295,10 @@ fun ExpandableMangaDescription(
// SY <-- // SY <--
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
// KMK -->
val uiPreferences = Injekt.get<UiPreferences>() val uiPreferences = Injekt.get<UiPreferences>()
val pureDarkMode = uiPreferences.themeDarkAmoled().get() val pureDarkMode = uiPreferences.themeDarkAmoled().get()
// KMK <--
Column(modifier = modifier) { Column(modifier = modifier) {
val (expanded, onExpanded) = rememberSaveable { val (expanded, onExpanded) = rememberSaveable {
mutableStateOf(defaultExpandState) mutableStateOf(defaultExpandState)
@ -355,7 +366,9 @@ fun ExpandableMangaDescription(
tagSelected = it tagSelected = it
showMenu = true showMenu = true
}, },
// KMK -->
pureDarkMode = pureDarkMode, pureDarkMode = pureDarkMode,
// KMK <--
) )
} else { } else {
// SY <-- // SY <--
@ -371,7 +384,9 @@ fun ExpandableMangaDescription(
tagSelected = it tagSelected = it
showMenu = true showMenu = true
}, },
// KMK -->
pureDarkMode = pureDarkMode, pureDarkMode = pureDarkMode,
// KMK <--
) )
} }
} }
@ -389,7 +404,9 @@ fun ExpandableMangaDescription(
tagSelected = it tagSelected = it
showMenu = true showMenu = true
}, },
// KMK -->
pureDarkMode = pureDarkMode, pureDarkMode = pureDarkMode,
// KMK <--
) )
} }
} }
@ -427,7 +444,9 @@ private fun MangaAndSourceTitlesLarge(
data = coverDataProvider(), data = coverDataProvider(),
contentDescription = stringResource(MR.strings.manga_cover), contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick, onClick = onCoverClick,
// KMK -->
onCoverLoaded = { mangaCover -> onCoverLoaded(mangaCover) }, onCoverLoaded = { mangaCover -> onCoverLoaded(mangaCover) },
// KMK <--
) )
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
MangaContentInfo( MangaContentInfo(
@ -477,7 +496,9 @@ private fun MangaAndSourceTitlesSmall(
data = coverDataProvider(), data = coverDataProvider(),
contentDescription = stringResource(MR.strings.manga_cover), contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick, onClick = onCoverClick,
// KMK -->
onCoverLoaded = { mangaCover -> onCoverLoaded(mangaCover) }, onCoverLoaded = { mangaCover -> onCoverLoaded(mangaCover) },
// KMK <--
) )
Column( Column(
verticalArrangement = Arrangement.spacedBy(2.dp), verticalArrangement = Arrangement.spacedBy(2.dp),
@ -636,6 +657,7 @@ private fun ColumnScope.MangaContentInfo(
text = sourceName, text = sourceName,
modifier = Modifier.clickableNoIndication { modifier = Modifier.clickableNoIndication {
// KMK --> // KMK -->
// doSearch(sourceName, false)
onSourceClick() onSourceClick()
// KMK <-- // KMK <--
}, },
@ -695,7 +717,9 @@ private fun MangaSummary(
contentDescription = stringResource( contentDescription = stringResource(
if (expanded) MR.strings.manga_info_collapse else MR.strings.manga_info_expand, if (expanded) MR.strings.manga_info_collapse else MR.strings.manga_info_expand,
), ),
tint = MaterialTheme.colorScheme.primary, // KMK -->
tint = MaterialTheme.colorScheme.primary, // KMK: onBackground
// KMK <--
modifier = Modifier.background(Brush.radialGradient(colors = colors.asReversed())), modifier = Modifier.background(Brush.radialGradient(colors = colors.asReversed())),
) )
} }

View file

@ -56,7 +56,9 @@ fun MangaToolbar(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
backgroundAlphaProvider: () -> Float = titleAlphaProvider, backgroundAlphaProvider: () -> Float = titleAlphaProvider,
// KMK -->
onPaletteScreenClick: () -> Unit, onPaletteScreenClick: () -> Unit,
// KMK <--
) { ) {
Column( Column(
modifier = modifier, modifier = modifier,

View file

@ -99,7 +99,9 @@ value class SearchMetadataChips(
fun NamespaceTags( fun NamespaceTags(
tags: SearchMetadataChips, tags: SearchMetadataChips,
onClick: (item: String) -> Unit, onClick: (item: String) -> Unit,
// KMK -->
pureDarkMode: Boolean = false, pureDarkMode: Boolean = false,
// KMK <--
) { ) {
Column(Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(4.dp)) { Column(Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(4.dp)) {
tags.tags.forEach { (namespace, tags) -> tags.tags.forEach { (namespace, tags) ->
@ -109,7 +111,9 @@ fun NamespaceTags(
modifier = Modifier.padding(top = 4.dp), modifier = Modifier.padding(top = 4.dp),
text = namespace, text = namespace,
onClick = null, onClick = null,
// KMK -->
pureDarkMode = pureDarkMode, pureDarkMode = pureDarkMode,
// KMK <--
) )
} }
FlowRow( FlowRow(
@ -125,20 +129,28 @@ fun NamespaceTags(
border = borderDp?.let { border = borderDp?.let {
SuggestionChipDefaults.suggestionChipBorder( SuggestionChipDefaults.suggestionChipBorder(
borderWidth = it, borderWidth = it,
// KMK -->
borderColor = MaterialTheme.colorScheme.primary, borderColor = MaterialTheme.colorScheme.primary,
// KMK <--
) )
} ?: SuggestionChipDefaults.suggestionChipBorder( } ?: SuggestionChipDefaults.suggestionChipBorder(
// KMK -->
borderColor = MaterialTheme.colorScheme.primary, borderColor = MaterialTheme.colorScheme.primary,
// KMK <--
), ),
borderM3 = borderDp?.let { borderM3 = borderDp?.let {
SuggestionChipDefaultsM3.suggestionChipBorder( SuggestionChipDefaultsM3.suggestionChipBorder(
enabled = true, enabled = true,
borderWidth = it, borderWidth = it,
// KMK -->
borderColor = MaterialTheme.colorScheme.primary, borderColor = MaterialTheme.colorScheme.primary,
// KMK <--
) )
} ?: SuggestionChipDefaultsM3.suggestionChipBorder( } ?: SuggestionChipDefaultsM3.suggestionChipBorder(
enabled = true, enabled = true,
// KMK -->
borderColor = MaterialTheme.colorScheme.primary, borderColor = MaterialTheme.colorScheme.primary,
// KMK <--
), ),
) )
} }
@ -154,12 +166,17 @@ fun TagsChip(
onClick: (() -> Unit)?, onClick: (() -> Unit)?,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
border: ChipBorder? = SuggestionChipDefaults.suggestionChipBorder(), border: ChipBorder? = SuggestionChipDefaults.suggestionChipBorder(),
// KMK -->
// borderM3: BorderStroke? = SuggestionChipDefaultsM3.suggestionChipBorder(enabled = true),
borderM3: BorderStroke? = null, borderM3: BorderStroke? = null,
pureDarkMode: Boolean = false, pureDarkMode: Boolean = false,
// KMK <--
) { ) {
CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) { CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
if (onClick != null) { if (onClick != null) {
// KMK -->
if (borderM3 != null || pureDarkMode) { if (borderM3 != null || pureDarkMode) {
// KMK <--
SuggestionChip( SuggestionChip(
modifier = modifier, modifier = modifier,
onClick = onClick, onClick = onClick,
@ -171,10 +188,12 @@ fun TagsChip(
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
) )
}, },
border = borderM3 ?: SuggestionChipDefaultsM3.suggestionChipBorder( border = borderM3
enabled = true, // KMK -->
borderColor = MaterialTheme.colorScheme.primary, ?: SuggestionChipDefaultsM3.suggestionChipBorder(
), enabled = true,
borderColor = MaterialTheme.colorScheme.primary,
),
) )
} else { } else {
ElevatedSuggestionChip( ElevatedSuggestionChip(
@ -193,6 +212,7 @@ fun TagsChip(
), ),
) )
} }
// KMK <--
} else { } else {
SuggestionChip( SuggestionChip(
modifier = modifier, modifier = modifier,

View file

@ -451,7 +451,9 @@ object SettingsAdvancedScreen : SearchableSettings {
} }
}, },
), ),
// KMK -->
Preference.PreferenceItem.InfoPreference(stringResource(KMR.strings.pref_private_installer_warning)), Preference.PreferenceItem.InfoPreference(stringResource(KMR.strings.pref_private_installer_warning)),
// KMK <--
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
title = stringResource(MR.strings.ext_revoke_trust), title = stringResource(MR.strings.ext_revoke_trust),
onClick = { onClick = {

View file

@ -47,7 +47,9 @@ object SettingsAppearanceScreen : SearchableSettings {
return listOf( return listOf(
getThemeGroup(uiPreferences = uiPreferences), getThemeGroup(uiPreferences = uiPreferences),
// KMK -->
getDetailsPageThemeGroup(uiPreferences = uiPreferences), getDetailsPageThemeGroup(uiPreferences = uiPreferences),
// KMK <--
getDisplayGroup(uiPreferences = uiPreferences), getDisplayGroup(uiPreferences = uiPreferences),
// SY --> // SY -->
getNavbarGroup(uiPreferences = uiPreferences), getNavbarGroup(uiPreferences = uiPreferences),
@ -106,6 +108,7 @@ object SettingsAppearanceScreen : SearchableSettings {
) )
} }
// KMK -->
@Composable @Composable
private fun getDetailsPageThemeGroup( private fun getDetailsPageThemeGroup(
uiPreferences: UiPreferences, uiPreferences: UiPreferences,
@ -132,6 +135,7 @@ object SettingsAppearanceScreen : SearchableSettings {
), ),
) )
} }
// KMK <--
@Composable @Composable
private fun getDisplayGroup( private fun getDisplayGroup(
@ -192,7 +196,9 @@ object SettingsAppearanceScreen : SearchableSettings {
@Composable @Composable
fun getForkGroup(uiPreferences: UiPreferences): Preference.PreferenceGroup { fun getForkGroup(uiPreferences: UiPreferences): Preference.PreferenceGroup {
val previewsRowCount by uiPreferences.previewsRowCount().collectAsState() val previewsRowCount by uiPreferences.previewsRowCount().collectAsState()
// KMK -->
val sourcePreferences = remember { Injekt.get<SourcePreferences>() } val sourcePreferences = remember { Injekt.get<SourcePreferences>() }
// KMK <--
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
stringResource(SYMR.strings.pref_category_fork), stringResource(SYMR.strings.pref_category_fork),
@ -201,12 +207,14 @@ object SettingsAppearanceScreen : SearchableSettings {
pref = uiPreferences.expandFilters(), pref = uiPreferences.expandFilters(),
title = stringResource(SYMR.strings.toggle_expand_search_filters), title = stringResource(SYMR.strings.toggle_expand_search_filters),
), ),
// KMK -->
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = uiPreferences.expandRelatedTitles(), pref = uiPreferences.expandRelatedTitles(),
title = stringResource(KMR.strings.pref_expand_related_titles), title = stringResource(KMR.strings.pref_expand_related_titles),
subtitle = stringResource(KMR.strings.pref_expand_related_titles_summary), subtitle = stringResource(KMR.strings.pref_expand_related_titles_summary),
enabled = sourcePreferences.relatedMangas().get(), enabled = sourcePreferences.relatedMangas().get(),
), ),
// KMK <--
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = uiPreferences.recommendsInOverflow(), pref = uiPreferences.recommendsInOverflow(),
title = stringResource(SYMR.strings.put_recommends_in_overflow), title = stringResource(SYMR.strings.put_recommends_in_overflow),

View file

@ -126,6 +126,7 @@ object SettingsTrackingScreen : SearchableSettings {
pref = trackPreferences.autoUpdateTrack(), pref = trackPreferences.autoUpdateTrack(),
title = stringResource(MR.strings.pref_auto_update_manga_sync), title = stringResource(MR.strings.pref_auto_update_manga_sync),
), ),
// KMK -->
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = trackPreferences.updateTrackMarkedRead(), pref = trackPreferences.updateTrackMarkedRead(),
title = stringResource(KMR.strings.pref_update_tracking_marked_read), title = stringResource(KMR.strings.pref_update_tracking_marked_read),
@ -134,6 +135,7 @@ object SettingsTrackingScreen : SearchableSettings {
pref = trackPreferences.autoSyncReadChapters(), pref = trackPreferences.autoSyncReadChapters(),
title = stringResource(KMR.strings.pref_auto_sync_read_chapters), title = stringResource(KMR.strings.pref_auto_sync_read_chapters),
), ),
// KMK <--
Preference.PreferenceGroup( Preference.PreferenceGroup(
title = stringResource(MR.strings.services), title = stringResource(MR.strings.services),
preferenceItems = persistentListOf( preferenceItems = persistentListOf(

View file

@ -329,6 +329,7 @@ object AboutScreen : Screen() {
} }
} }
// KMK -->
private suspend fun getReleaseNotes( private suspend fun getReleaseNotes(
context: Context, context: Context,
onAvailableUpdate: (GetApplicationRelease.Result.NewUpdate) -> Unit, onAvailableUpdate: (GetApplicationRelease.Result.NewUpdate) -> Unit,
@ -351,6 +352,7 @@ object AboutScreen : Screen() {
} }
} }
} }
// KMK <--
fun getVersionName(withBuildDate: Boolean): String { fun getVersionName(withBuildDate: Boolean): String {
return when { return when {

View file

@ -50,11 +50,13 @@ fun WhatsNewDialog(onDismissRequest: () -> Unit) {
} }
}, },
title = { Text(text = stringResource(MR.strings.updated_version, BuildConfig.VERSION_NAME)) }, title = { Text(text = stringResource(MR.strings.updated_version, BuildConfig.VERSION_NAME)) },
// KMK -->
dismissButton = { dismissButton = {
TextButton(onClick = { context.openInBrowser(RELEASE_URL) }) { TextButton(onClick = { context.openInBrowser(RELEASE_URL) }) {
Text(text = stringResource(KMR.strings.changelogs)) Text(text = stringResource(KMR.strings.changelogs))
} }
}, },
// KMK <--
text = { text = {
Column { Column {
val changelog by produceState<List<DisplayChangelog>?>(initialValue = null) { val changelog by produceState<List<DisplayChangelog>?>(initialValue = null) {

View file

@ -169,17 +169,21 @@ private fun UpdatesUiItem(
.padding(horizontal = MaterialTheme.padding.medium), .padding(horizontal = MaterialTheme.padding.medium),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
// KMK -->
val mangaCover = update.coverData val mangaCover = update.coverData
val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) } val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) }
val onBgColor = mangaCover.dominantCoverColors?.second val onBgColor = mangaCover.dominantCoverColors?.second
// KMK <--
MangaCover.Square( MangaCover.Square(
modifier = Modifier modifier = Modifier
.padding(vertical = 6.dp) .padding(vertical = 6.dp)
.fillMaxHeight(), .fillMaxHeight(),
data = mangaCover, data = mangaCover,
onClick = onClickCover, onClick = onClickCover,
// KMK -->
bgColor = bgColor, bgColor = bgColor,
tint = onBgColor, tint = onBgColor,
// KMK <--
) )
Column( Column(

View file

@ -20,12 +20,19 @@ import androidx.core.graphics.drawable.toBitmap
* @return the bitmap associated with the resource * @return the bitmap associated with the resource
*/ */
@Composable @Composable
fun rememberResourceBitmapPainter(@DrawableRes id: Int, @ColorInt tint: Int? = null): BitmapPainter { fun rememberResourceBitmapPainter(
@DrawableRes id: Int,
// KMK -->
@ColorInt tint: Int? = null,
// KMK <--
): BitmapPainter {
val context = LocalContext.current val context = LocalContext.current
return remember(id) { return remember(id) {
val drawable = ContextCompat.getDrawable(context, id) val drawable = ContextCompat.getDrawable(context, id)
?: throw Resources.NotFoundException() ?: throw Resources.NotFoundException()
// KMK -->
tint?.let { drawable.setTint(it) } tint?.let { drawable.setTint(it) }
// KMK <--
BitmapPainter(drawable.toBitmap().asImageBitmap()) BitmapPainter(drawable.toBitmap().asImageBitmap())
} }
} }

View file

@ -101,8 +101,10 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
@SuppressLint("LaunchActivityFromNotification") @SuppressLint("LaunchActivityFromNotification")
override fun onCreate() { override fun onCreate() {
super<Application>.onCreate() super<Application>.onCreate()
// KMK -->
Firebase.initialize(this) Firebase.initialize(this)
if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree()) if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
// KMK <--
// SY --> // SY -->
if (!isDevFlavor) { if (!isDevFlavor) {
@ -168,7 +170,9 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
setAppCompatDelegateThemeMode(Injekt.get<UiPreferences>().themeMode().get()) setAppCompatDelegateThemeMode(Injekt.get<UiPreferences>().themeMode().get())
// KMK -->
MangaCoverMetadata.load() MangaCoverMetadata.load()
// KMK <--
// Updates widget update // Updates widget update
with(WidgetManager(Injekt.get(), Injekt.get())) { with(WidgetManager(Injekt.get(), Injekt.get())) {

View file

@ -56,8 +56,11 @@ import java.io.IOException
*/ */
@Suppress("LongParameterList") @Suppress("LongParameterList")
class MangaCoverFetcher( class MangaCoverFetcher(
// KMK -->
private val mangaCover: MangaCover, private val mangaCover: MangaCover,
private val url: String? = mangaCover.url, private val url: String? = mangaCover.url,
// private val url: String?,
// KMK <--
private val isLibraryManga: Boolean, private val isLibraryManga: Boolean,
private val options: Options, private val options: Options,
private val coverFileLazy: Lazy<File?>, private val coverFileLazy: Lazy<File?>,
@ -68,8 +71,10 @@ class MangaCoverFetcher(
private val imageLoader: ImageLoader, private val imageLoader: ImageLoader,
) : Fetcher { ) : Fetcher {
// KMK -->
private val fileScope by lazy { CoroutineScope(Job() + Dispatchers.IO) } private val fileScope by lazy { CoroutineScope(Job() + Dispatchers.IO) }
private val uiPreferences = Injekt.get<UiPreferences>() private val uiPreferences = Injekt.get<UiPreferences>()
// KMK <--
private val diskCacheKey: String private val diskCacheKey: String
get() = diskCacheKeyLazy.value get() = diskCacheKeyLazy.value
@ -98,7 +103,9 @@ class MangaCoverFetcher(
} }
private fun fileLoader(file: File): FetchResult { private fun fileLoader(file: File): FetchResult {
// KMK -->
setRatioAndColorsInScope(mangaCover, ogFile = file) setRatioAndColorsInScope(mangaCover, ogFile = file)
// KMK <--
return SourceFetchResult( return SourceFetchResult(
source = ImageSource( source = ImageSource(
file = file.toOkioPath(), file = file.toOkioPath(),
@ -111,7 +118,9 @@ class MangaCoverFetcher(
} }
private fun fileUriLoader(uri: String): FetchResult { private fun fileUriLoader(uri: String): FetchResult {
// KMK -->
setRatioAndColorsInScope(mangaCover) setRatioAndColorsInScope(mangaCover)
// KMK <--
val source = UniFile.fromUri(options.context, uri.toUri())!! val source = UniFile.fromUri(options.context, uri.toUri())!!
.openInputStream() .openInputStream()
.source() .source()
@ -145,7 +154,9 @@ class MangaCoverFetcher(
} }
// Read from snapshot // Read from snapshot
// KMK -->
setRatioAndColorsInScope(mangaCover, bufferedSource = snapshot.toImageSource().source()) setRatioAndColorsInScope(mangaCover, bufferedSource = snapshot.toImageSource().source())
// KMK <--
return SourceFetchResult( return SourceFetchResult(
source = snapshot.toImageSource(), source = snapshot.toImageSource(),
mimeType = "image/*", mimeType = "image/*",
@ -166,7 +177,9 @@ class MangaCoverFetcher(
// Read from disk cache // Read from disk cache
snapshot = writeToDiskCache(response) snapshot = writeToDiskCache(response)
if (snapshot != null) { if (snapshot != null) {
// KMK -->
setRatioAndColorsInScope(mangaCover, bufferedSource = snapshot.toImageSource().source()) setRatioAndColorsInScope(mangaCover, bufferedSource = snapshot.toImageSource().source())
// KMK <--
return SourceFetchResult( return SourceFetchResult(
source = snapshot.toImageSource(), source = snapshot.toImageSource(),
mimeType = "image/*", mimeType = "image/*",
@ -174,6 +187,7 @@ class MangaCoverFetcher(
) )
} }
// KMK -->
setRatioAndColorsInScope( setRatioAndColorsInScope(
mangaCover, mangaCover,
bufferedSource = ImageSource( bufferedSource = ImageSource(
@ -181,6 +195,7 @@ class MangaCoverFetcher(
fileSystem = FileSystem.SYSTEM, fileSystem = FileSystem.SYSTEM,
).source(), ).source(),
) )
// KMK <--
// Read from response if cache is unused or unusable // Read from response if cache is unused or unusable
return SourceFetchResult( return SourceFetchResult(
source = ImageSource(source = responseBody.source(), fileSystem = FileSystem.SYSTEM), source = ImageSource(source = responseBody.source(), fileSystem = FileSystem.SYSTEM),
@ -319,6 +334,7 @@ class MangaCoverFetcher(
} }
} }
// KMK -->
/** /**
* [setRatioAndColorsInScope] is called whenever a cover is loaded with [MangaCoverFetcher.fetch] * [setRatioAndColorsInScope] is called whenever a cover is loaded with [MangaCoverFetcher.fetch]
* *
@ -338,6 +354,7 @@ class MangaCoverFetcher(
MangaCoverMetadata.setRatioAndColors(mangaCover, bufferedSource, ogFile, onlyFavorite, force) MangaCoverMetadata.setRatioAndColors(mangaCover, bufferedSource, ogFile, onlyFavorite, force)
} }
} }
// KMK <--
private enum class Type { private enum class Type {
File, File,
@ -354,7 +371,10 @@ class MangaCoverFetcher(
override fun create(data: Manga, options: Options, imageLoader: ImageLoader): Fetcher { override fun create(data: Manga, options: Options, imageLoader: ImageLoader): Fetcher {
return MangaCoverFetcher( return MangaCoverFetcher(
// KMK -->
// url = data.thumbnailUrl,
mangaCover = data.asMangaCover(), mangaCover = data.asMangaCover(),
// KMK <--
isLibraryManga = data.favorite, isLibraryManga = data.favorite,
options = options, options = options,
coverFileLazy = lazy { coverCache.getCoverFile(data.thumbnailUrl) }, coverFileLazy = lazy { coverCache.getCoverFile(data.thumbnailUrl) },
@ -376,7 +396,10 @@ class MangaCoverFetcher(
override fun create(data: MangaCover, options: Options, imageLoader: ImageLoader): Fetcher { override fun create(data: MangaCover, options: Options, imageLoader: ImageLoader): Fetcher {
return MangaCoverFetcher( return MangaCoverFetcher(
// KMK -->
// url = data.url,
mangaCover = data, mangaCover = data,
// KMK <--
isLibraryManga = data.isMangaFavorite, isLibraryManga = data.isMangaFavorite,
options = options, options = options,
coverFileLazy = lazy { coverCache.getCoverFile(data.url) }, coverFileLazy = lazy { coverCache.getCoverFile(data.url) },

View file

@ -70,6 +70,8 @@ object MangaCoverMetadata {
* *
* This is only for loading color first time it appears on Library/Browse. Any new colors caused by loading new * This is only for loading color first time it appears on Library/Browse. Any new colors caused by loading new
* cover when open a manga detail or change cover will be updated separately on [MangaScreenModel.setPaletteColor]. * cover when open a manga detail or change cover will be updated separately on [MangaScreenModel.setPaletteColor].
*
* @author Jays2Kings, cuong-tran
*/ */
fun setRatioAndColors( fun setRatioAndColors(
mangaCover: MangaCover, mangaCover: MangaCover,

View file

@ -44,6 +44,7 @@ val Options.customDecoder: Boolean
private val customDecoderKey = Extras.Key(default = false) private val customDecoderKey = Extras.Key(default = false)
// KMK -->
/** /**
* Calculate the best [Palette.Swatch] from [Palette] * Calculate the best [Palette.Swatch] from [Palette]
* @author Jays2Kings * @author Jays2Kings
@ -82,3 +83,4 @@ fun Palette.getBestColor(): Int? {
} }
}?.rgb }?.rgb
} }
// KMK <--

View file

@ -85,11 +85,11 @@ class DownloadCache(
* The interval after which this cache should be invalidated. 1 hour shouldn't cause major * The interval after which this cache should be invalidated. 1 hour shouldn't cause major
* issues, as the cache is only used for UI feedback. * issues, as the cache is only used for UI feedback.
*/ */
private val renewInterval //= 1.hours.inWholeMilliseconds private val renewInterval // = 1.hours.inWholeMilliseconds
// KMK --> // KMK -->
get() = downloadPreferences.downloadCacheRenewInterval().get() get() = downloadPreferences.downloadCacheRenewInterval().get()
.hours.inWholeMilliseconds .hours.inWholeMilliseconds
// KMK <-- // KMK <--
/** /**
* The last time the cache was refreshed. * The last time the cache was refreshed.
@ -330,7 +330,11 @@ class DownloadCache(
lastRenew = 0L lastRenew = 0L
renewalJob?.cancel() renewalJob?.cancel()
diskCacheFile.delete() diskCacheFile.delete()
renewCache(/* KMK --> */ 0L /* KMK <-- */) renewCache(
// KMK -->
renewInterval = 0L,
// KMK <--
)
} }
// KMK --> // KMK -->
@ -345,9 +349,18 @@ class DownloadCache(
/** /**
* Renews the downloads cache. * Renews the downloads cache.
*/ */
private fun renewCache(/* KMK --> */ renewInterval: Long = this.renewInterval /* KMK <-- */) { private fun renewCache(
// KMK -->
renewInterval: Long = this.renewInterval,
// KMK <--
) {
// Avoid renewing cache if in the process nor too often // Avoid renewing cache if in the process nor too often
if (/* KMK --> */ renewInterval < 0L || /* KMK <-- */ lastRenew + renewInterval >= System.currentTimeMillis() || renewalJob?.isActive == true) { if (lastRenew + renewInterval >= System.currentTimeMillis() ||
// KMK -->
renewInterval < 0L ||
// KMK <--
renewalJob?.isActive == true
) {
return return
} }

View file

@ -80,5 +80,7 @@ interface Tracker {
suspend fun setRemoteFinishDate(track: Track, epochMillis: Long) suspend fun setRemoteFinishDate(track: Track, epochMillis: Long)
// KMK -->
fun hasNotStartedReading(status: Long): Boolean fun hasNotStartedReading(status: Long): Boolean
// KMK <--
} }

View file

@ -241,5 +241,7 @@ class Anilist(id: Long) : BaseTracker(id, "AniList"), DeletableTracker {
} }
} }
// KMK -->
override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ
// KMK <--
} }

View file

@ -148,5 +148,7 @@ class Bangumi(id: Long) : BaseTracker(id, "Bangumi") {
.toImmutableList() .toImmutableList()
} }
// KMK -->
override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ
// KMK <--
} }

View file

@ -145,5 +145,7 @@ class Kavita(id: Long) : BaseTracker(id, "Kavita"), EnhancedTracker {
authentications = oauth authentications = oauth
} }
// KMK -->
override fun hasNotStartedReading(status: Long): Boolean = status == UNREAD override fun hasNotStartedReading(status: Long): Boolean = status == UNREAD
// KMK <--
} }

View file

@ -154,5 +154,7 @@ class Kitsu(id: Long) : BaseTracker(id, "Kitsu"), DeletableTracker {
} }
} }
// KMK -->
override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ
// KMK <--
} }

View file

@ -112,5 +112,7 @@ class Komga(id: Long) : BaseTracker(id, "Komga"), EnhancedTracker {
null null
} }
// KMK -->
override fun hasNotStartedReading(status: Long): Boolean = status == UNREAD override fun hasNotStartedReading(status: Long): Boolean = status == UNREAD
// KMK <--
} }

View file

@ -121,5 +121,7 @@ class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), DeletableTracker
return trackPreferences.trackPassword(this).get().ifBlank { null } return trackPreferences.trackPassword(this).get().ifBlank { null }
} }
// KMK -->
override fun hasNotStartedReading(status: Long): Boolean = status == WISH_LIST override fun hasNotStartedReading(status: Long): Boolean = status == WISH_LIST
// KMK <--
} }

View file

@ -173,5 +173,7 @@ class MdList(id: Long) : BaseTracker(id, "MDList") {
class MangaDexNotFoundException : Exception("Mangadex not enabled") class MangaDexNotFoundException : Exception("Mangadex not enabled")
// KMK -->
override fun hasNotStartedReading(status: Long): Boolean = status == FollowStatus.PLAN_TO_READ.long override fun hasNotStartedReading(status: Long): Boolean = status == FollowStatus.PLAN_TO_READ.long
// KMK <--
} }

View file

@ -175,5 +175,7 @@ class MyAnimeList(id: Long) : BaseTracker(id, "MyAnimeList"), DeletableTracker {
} }
} }
// KMK -->
override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ
// KMK <--
} }

View file

@ -152,5 +152,7 @@ class Shikimori(id: Long) : BaseTracker(id, "Shikimori"), DeletableTracker {
interceptor.newAuth(null) interceptor.newAuth(null)
} }
// KMK -->
override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ
// KMK <--
} }

View file

@ -104,5 +104,7 @@ class Suwayomi(id: Long) : BaseTracker(id, "Suwayomi"), EnhancedTracker {
null null
} }
// KMK -->
override fun hasNotStartedReading(status: Long): Boolean = status == UNREAD override fun hasNotStartedReading(status: Long): Boolean = status == UNREAD
// KMK <--
} }

View file

@ -82,7 +82,12 @@ data class BrowseTab(
) )
} else if (feedTabInFront) { } else if (feedTabInFront) {
persistentListOf( persistentListOf(
feedTab(/* KMK --> */feedScreenModel, bulkFavoriteScreenModel/* KMK <-- */), feedTab(
// KMK -->
feedScreenModel,
bulkFavoriteScreenModel,
// KMK <--
),
sourcesTab(), sourcesTab(),
extensionsTab(extensionsScreenModel), extensionsTab(extensionsScreenModel),
migrateSourceTab(), migrateSourceTab(),
@ -90,7 +95,12 @@ data class BrowseTab(
} else { } else {
persistentListOf( persistentListOf(
sourcesTab(), sourcesTab(),
feedTab(/* KMK --> */feedScreenModel, bulkFavoriteScreenModel/* KMK <-- */), feedTab(
// KMK -->
feedScreenModel,
bulkFavoriteScreenModel,
// KMK <--
),
extensionsTab(extensionsScreenModel), extensionsTab(extensionsScreenModel),
migrateSourceTab(), migrateSourceTab(),
) )

View file

@ -30,14 +30,18 @@ data class ExtensionDetailsScreen(
} }
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
// KMK -->
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
// KMK <--
ExtensionDetailsScreen( ExtensionDetailsScreen(
navigateUp = navigator::pop, navigateUp = navigator::pop,
state = state, state = state,
onClickSourcePreferences = { navigator.push(SourcePreferencesScreen(it)) }, onClickSourcePreferences = { navigator.push(SourcePreferencesScreen(it)) },
// KMK -->
onClickWhatsNew = { uriHandler.openUri(screenModel.getChangelogUrl()) }, onClickWhatsNew = { uriHandler.openUri(screenModel.getChangelogUrl()) },
onClickReadme = { uriHandler.openUri(screenModel.getReadmeUrl()) }, onClickReadme = { uriHandler.openUri(screenModel.getReadmeUrl()) },
// KMK <--
onClickEnableAll = { screenModel.toggleSources(true) }, onClickEnableAll = { screenModel.toggleSources(true) },
onClickDisableAll = { screenModel.toggleSources(false) }, onClickDisableAll = { screenModel.toggleSources(false) },
onClickClearCookies = screenModel::clearCookies, onClickClearCookies = screenModel::clearCookies,

View file

@ -131,8 +131,9 @@ open class FeedScreenModel(
source, source,
( (
// KMK --> // KMK -->
// (if (source.supportsLatest) persistentListOf(null) else persistentListOf()) +
persistentListOf(null) + persistentListOf(null) +
// KMK <--> // KMK <-->
getSourceSavedSearches(source.id) getSourceSavedSearches(source.id)
).toImmutableList(), ).toImmutableList(),
), ),
@ -152,7 +153,7 @@ open class FeedScreenModel(
} }
private suspend fun hasTooManyFeeds(): Boolean { private suspend fun hasTooManyFeeds(): Boolean {
return countFeedSavedSearchGlobal.await() > MAX_FEED_ITEMS return countFeedSavedSearchGlobal.await() > MaxFeedItems
} }
fun getEnabledSources(): ImmutableList<CatalogueSource> { fun getEnabledSources(): ImmutableList<CatalogueSource> {
@ -234,10 +235,13 @@ open class FeedScreenModel(
withContext(coroutineDispatcher) { withContext(coroutineDispatcher) {
if (itemUI.savedSearch == null) { if (itemUI.savedSearch == null) {
// KMK --> // KMK -->
if (itemUI.source.supportsLatest) if (itemUI.source.supportsLatest) {
// KMK <--
itemUI.source.getLatestUpdates(1) itemUI.source.getLatestUpdates(1)
else // KMK -->
} else {
itemUI.source.getPopularManga(1) itemUI.source.getPopularManga(1)
}
// KMK <-- // KMK <--
} else { } else {
itemUI.source.getSearchManga( itemUI.source.getSearchManga(
@ -331,4 +335,4 @@ data class FeedScreenState(
get() = items?.fastAny { it.results == null } != false get() = items?.fastAny { it.results == null } != false
} }
const val MAX_FEED_ITEMS = 20 const val MaxFeedItems = 20

View file

@ -112,9 +112,9 @@ fun feedTab(
listingQuery = if (!source.supportsLatest) { listingQuery = if (!source.supportsLatest) {
GetRemoteManga.QUERY_POPULAR GetRemoteManga.QUERY_POPULAR
} else { } else {
// KMK <--
GetRemoteManga.QUERY_LATEST GetRemoteManga.QUERY_LATEST
}, },
// KMK <--
), ),
) )
}, },

View file

@ -98,6 +98,7 @@ class SourcesScreenModel(
// KMK --> // KMK -->
filters: Pair<String?, Boolean>, filters: Pair<String?, Boolean>,
unfilteredSources: List<Source>, unfilteredSources: List<Source>,
// sources: List<Source>,
// KMK <-- // KMK <--
categories: List<String>, categories: List<String>,
showLatest: Boolean, showLatest: Boolean,

View file

@ -166,7 +166,10 @@ class SourceFeedScreen(val sourceId: Long) : Screen() {
openMangaDexRandom = if (screenModel.sourceIsMangaDex) { openMangaDexRandom = if (screenModel.sourceIsMangaDex) {
{ {
screenModel.onMangaDexRandom { screenModel.onMangaDexRandom {
// KMK -->
// navigator.replace(
navigator.push( navigator.push(
// KMK <--
BrowseSourceScreen( BrowseSourceScreen(
sourceId, sourceId,
"id:$it", "id:$it",
@ -179,7 +182,10 @@ class SourceFeedScreen(val sourceId: Long) : Screen() {
}, },
openMangaDexFollows = if (screenModel.sourceIsMangaDex) { openMangaDexFollows = if (screenModel.sourceIsMangaDex) {
{ {
// KMK -->
// navigator.replace(MangaDexFollowsScreen(sourceId))
navigator.push(MangaDexFollowsScreen(sourceId)) navigator.push(MangaDexFollowsScreen(sourceId))
// KMK <--
} }
} else { } else {
null null
@ -221,19 +227,31 @@ class SourceFeedScreen(val sourceId: Long) : Screen() {
} }
fun onBrowseClick(navigator: Navigator, sourceId: Long, search: String? = null, savedSearch: Long? = null, filters: String? = null) { fun onBrowseClick(navigator: Navigator, sourceId: Long, search: String? = null, savedSearch: Long? = null, filters: String? = null) {
// KMK -->
// navigator.replace(BrowseSourceScreen(sourceId, search, savedSearch = savedSearch, filtersJson = filters))
navigator.push(BrowseSourceScreen(sourceId, search, savedSearch = savedSearch, filtersJson = filters)) navigator.push(BrowseSourceScreen(sourceId, search, savedSearch = savedSearch, filtersJson = filters))
// KMK <--
} }
private fun onLatestClick(navigator: Navigator, source: Source) { private fun onLatestClick(navigator: Navigator, source: Source) {
// KMK -->
// navigator.replace(BrowseSourceScreen(source.id, GetRemoteManga.QUERY_LATEST))
navigator.push(BrowseSourceScreen(source.id, GetRemoteManga.QUERY_LATEST)) navigator.push(BrowseSourceScreen(source.id, GetRemoteManga.QUERY_LATEST))
// KMK <--
} }
fun onBrowseClick(navigator: Navigator, source: Source) { fun onBrowseClick(navigator: Navigator, source: Source) {
// KMK -->
// navigator.replace(BrowseSourceScreen(source.id, GetRemoteManga.QUERY_POPULAR))
navigator.push(BrowseSourceScreen(source.id, GetRemoteManga.QUERY_POPULAR)) navigator.push(BrowseSourceScreen(source.id, GetRemoteManga.QUERY_POPULAR))
// KMK <--
} }
private fun onSavedSearchClick(navigator: Navigator, source: Source, savedSearch: SavedSearch) { private fun onSavedSearchClick(navigator: Navigator, source: Source, savedSearch: SavedSearch) {
// KMK -->
// navigator.replace(BrowseSourceScreen(source.id, listingQuery = null, savedSearch = savedSearch.id))
navigator.push(BrowseSourceScreen(source.id, listingQuery = null, savedSearch = savedSearch.id)) navigator.push(BrowseSourceScreen(source.id, listingQuery = null, savedSearch = savedSearch.id))
// KMK <--
} }
private fun onSearchClick(navigator: Navigator, source: Source, query: String) { private fun onSearchClick(navigator: Navigator, source: Source, query: String) {

View file

@ -17,7 +17,7 @@ import eu.kanade.presentation.browse.SourceFeedUI
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.online.all.MangaDex import eu.kanade.tachiyomi.source.online.all.MangaDex
import eu.kanade.tachiyomi.ui.browse.feed.MAX_FEED_ITEMS import eu.kanade.tachiyomi.ui.browse.feed.MaxFeedItems
import exh.source.getMainSource import exh.source.getMainSource
import exh.source.mangaDexSourceIds import exh.source.mangaDexSourceIds
import exh.util.nullIfBlank import exh.util.nullIfBlank
@ -109,7 +109,7 @@ open class SourceFeedScreenModel(
} }
private suspend fun hasTooManyFeeds(): Boolean { private suspend fun hasTooManyFeeds(): Boolean {
return countFeedSavedSearchBySourceId.await(source.id) > MAX_FEED_ITEMS return countFeedSavedSearchBySourceId.await(source.id) > MaxFeedItems
} }
fun createFeed(savedSearchId: Long) { fun createFeed(savedSearchId: Long) {

View file

@ -290,6 +290,9 @@ object LibraryTab : Tab {
initialSelection = dialog.initialSelection, initialSelection = dialog.initialSelection,
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
onEditCategories = { onEditCategories = {
// KMK -->
// screenModel.clearSelection()
// KMK <--
navigator.push(CategoryScreen()) navigator.push(CategoryScreen())
}, },
onConfirm = { include, exclude -> onConfirm = { include, exclude ->

View file

@ -337,10 +337,12 @@ class MainActivity : BaseActivity() {
// SY --> // SY -->
} }
// KMK -->
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
MangaCoverMetadata.savePrefs() MangaCoverMetadata.savePrefs()
} }
// KMK <--
override fun onProvideAssistContent(outContent: AssistContent) { override fun onProvideAssistContent(outContent: AssistContent) {
super.onProvideAssistContent(outContent) super.onProvideAssistContent(outContent)

View file

@ -58,7 +58,6 @@ import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.source.local.isLocal import tachiyomi.source.local.isLocal
import timber.log.Timber
@Composable @Composable
fun EditMangaDialog( fun EditMangaDialog(
@ -78,6 +77,7 @@ fun EditMangaDialog(
var binding by remember { var binding by remember {
mutableStateOf<EditMangaDialogBinding?>(null) mutableStateOf<EditMangaDialogBinding?>(null)
} }
// KMK -->
val colors = EditMangaDialogColors( val colors = EditMangaDialogColors(
textColor = MaterialTheme.colorScheme.onSurfaceVariant.toArgb(), textColor = MaterialTheme.colorScheme.onSurfaceVariant.toArgb(),
textHighlightColor = MaterialTheme.colorScheme.outline.toArgb(), textHighlightColor = MaterialTheme.colorScheme.outline.toArgb(),
@ -89,6 +89,7 @@ fun EditMangaDialog(
dropdownBgColor = MaterialTheme.colorScheme.surfaceVariant.toArgb(), dropdownBgColor = MaterialTheme.colorScheme.surfaceVariant.toArgb(),
dialogBgColor = MaterialTheme.colorScheme.surfaceContainerHigh.toArgb(), dialogBgColor = MaterialTheme.colorScheme.surfaceContainerHigh.toArgb(),
) )
// KMK <--
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
confirmButton = { confirmButton = {
@ -142,7 +143,9 @@ fun EditMangaDialog(
factoryContext, factoryContext,
this, this,
scope, scope,
// KMK -->
colors, colors,
// KMK <--
) )
} }
.root .root
@ -154,6 +157,7 @@ fun EditMangaDialog(
) )
} }
// KMK -->
class EditMangaDialogColors( class EditMangaDialogColors(
@ColorInt val textColor: Int, @ColorInt val textColor: Int,
@ColorInt val textHighlightColor: Int, @ColorInt val textHighlightColor: Int,
@ -165,17 +169,23 @@ class EditMangaDialogColors(
@ColorInt val dropdownBgColor: Int, @ColorInt val dropdownBgColor: Int,
@ColorInt val dialogBgColor: Int, @ColorInt val dialogBgColor: Int,
) )
// KMK <--
private fun onViewCreated( private fun onViewCreated(
manga: Manga, manga: Manga,
context: Context, context: Context,
binding: EditMangaDialogBinding, binding: EditMangaDialogBinding,
scope: CoroutineScope, scope: CoroutineScope,
// KMK -->
colors: EditMangaDialogColors, colors: EditMangaDialogColors,
// KMK <--
) { ) {
loadCover(manga, binding) loadCover(manga, binding)
// KMK -->
// val statusAdapter: ArrayAdapter<String> = ArrayAdapter(
val statusAdapter = SpinnerAdapter( val statusAdapter = SpinnerAdapter(
// KMK <--
context, context,
android.R.layout.simple_spinner_dropdown_item, android.R.layout.simple_spinner_dropdown_item,
listOf( listOf(
@ -187,7 +197,9 @@ private fun onViewCreated(
MR.strings.cancelled, MR.strings.cancelled,
MR.strings.on_hiatus, MR.strings.on_hiatus,
).map { context.stringResource(it) }, ).map { context.stringResource(it) },
// KMK -->
colors, colors,
// KMK <--
) )
binding.status.adapter = statusAdapter binding.status.adapter = statusAdapter
@ -206,6 +218,7 @@ private fun onViewCreated(
) )
} }
// KMK -->
// Set Spinner's selected item's background color to transparent // Set Spinner's selected item's background color to transparent
binding.status.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { binding.status.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View?, pos: Int, id: Long) { override fun onItemSelected(parent: AdapterView<*>, view: View?, pos: Int, id: Long) {
@ -216,6 +229,7 @@ private fun onViewCreated(
// Set Spinner's dropdown caret color // Set Spinner's dropdown caret color
binding.status.backgroundTintList = ColorStateList.valueOf(colors.iconColor) binding.status.backgroundTintList = ColorStateList.valueOf(colors.iconColor)
// KMK
if (manga.isLocal()) { if (manga.isLocal()) {
if (manga.title != manga.url) { if (manga.title != manga.url) {
@ -265,6 +279,7 @@ private fun onViewCreated(
} }
binding.mangaGenresTags.clearFocus() binding.mangaGenresTags.clearFocus()
// KMK -->
listOf( listOf(
binding.title, binding.title,
binding.mangaAuthor, binding.mangaAuthor,
@ -308,6 +323,7 @@ private fun onViewCreated(
binding.resetTags.setBackgroundColor(colors.btnBgColor) binding.resetTags.setBackgroundColor(colors.btnBgColor)
binding.resetInfo.setTextColor(colors.btnTextColor) binding.resetInfo.setTextColor(colors.btnTextColor)
binding.resetInfo.setBackgroundColor(colors.btnBgColor) binding.resetInfo.setBackgroundColor(colors.btnBgColor)
// KMK <--
binding.resetTags.setOnClickListener { resetTags(manga, binding, scope, colors) } binding.resetTags.setOnClickListener { resetTags(manga, binding, scope, colors) }
binding.resetInfo.setOnClickListener { resetInfo(manga, binding, scope, colors) } binding.resetInfo.setOnClickListener { resetInfo(manga, binding, scope, colors) }
@ -317,7 +333,9 @@ private fun resetTags(
manga: Manga, manga: Manga,
binding: EditMangaDialogBinding, binding: EditMangaDialogBinding,
scope: CoroutineScope, scope: CoroutineScope,
// KMK -->
colors: EditMangaDialogColors, colors: EditMangaDialogColors,
// KMK <--
) { ) {
if (manga.genre.isNullOrEmpty() || manga.isLocal()) { if (manga.genre.isNullOrEmpty() || manga.isLocal()) {
binding.mangaGenresTags.setChips(emptyList(), scope, colors) binding.mangaGenresTags.setChips(emptyList(), scope, colors)
@ -336,7 +354,9 @@ private fun resetInfo(
manga: Manga, manga: Manga,
binding: EditMangaDialogBinding, binding: EditMangaDialogBinding,
scope: CoroutineScope, scope: CoroutineScope,
// KMK -->
colors: EditMangaDialogColors, colors: EditMangaDialogColors,
// KMK <--
) { ) {
binding.title.setText("") binding.title.setText("")
binding.mangaAuthor.setText("") binding.mangaAuthor.setText("")
@ -349,24 +369,35 @@ private fun resetInfo(
private fun ChipGroup.setChips( private fun ChipGroup.setChips(
items: List<String>, items: List<String>,
scope: CoroutineScope, scope: CoroutineScope,
// KMK -->
colors: EditMangaDialogColors, colors: EditMangaDialogColors,
// KMK <--
) { ) {
removeAllViews() removeAllViews()
// KMK -->
val colorStateList = ColorStateList.valueOf(colors.tagColor) val colorStateList = ColorStateList.valueOf(colors.tagColor)
// KMK <--
items.asSequence().map { item -> items.asSequence().map { item ->
Chip(context).apply { Chip(context).apply {
text = item text = item
// KMK -->
setTextColor(colors.tagTextColor) setTextColor(colors.tagTextColor)
// KMK <--
isCloseIconVisible = true isCloseIconVisible = true
// KMK -->
// closeIcon?.setTint(context.getResourceColor(R.attr.colorAccent))
closeIcon?.setTint(colors.iconColor) closeIcon?.setTint(colors.iconColor)
// KMK <--
setOnCloseIconClickListener { setOnCloseIconClickListener {
removeView(this) removeView(this)
} }
// KMK -->
chipBackgroundColor = colorStateList chipBackgroundColor = colorStateList
// KMK <--
} }
}.forEach { }.forEach {
addView(it) addView(it)
@ -374,16 +405,24 @@ private fun ChipGroup.setChips(
val addTagChip = Chip(context).apply { val addTagChip = Chip(context).apply {
text = SYMR.strings.add_tag.getString(context) text = SYMR.strings.add_tag.getString(context)
// KMK -->
setTextColor(colors.tagTextColor) setTextColor(colors.tagTextColor)
// KMK <--
chipIcon = ContextCompat.getDrawable(context, R.drawable.ic_add_24dp)?.apply { chipIcon = ContextCompat.getDrawable(context, R.drawable.ic_add_24dp)?.apply {
isChipIconVisible = true isChipIconVisible = true
// KMK -->
// setTint(context.getResourceColor(R.attr.colorAccent))
setTint(colors.iconColor) setTint(colors.iconColor)
// KMK <--
} }
// KMK -->
chipBackgroundColor = colorStateList chipBackgroundColor = colorStateList
// KMK <--
setOnClickListener { setOnClickListener {
// KMK -->
var dialog: AlertDialog? = null var dialog: AlertDialog? = null
val builder = MaterialAlertDialogBuilder(context) val builder = MaterialAlertDialogBuilder(context)
@ -391,8 +430,10 @@ private fun ChipGroup.setChips(
.setTitle(SYMR.strings.add_tag.getString(context)) .setTitle(SYMR.strings.add_tag.getString(context))
.setPositiveButton(MR.strings.action_ok.getString(context)) { .setPositiveButton(MR.strings.action_ok.getString(context)) {
dialog?.dismissDialog() dialog?.dismissDialog()
// KMK <--
val newTag = it.trimOrNull() val newTag = it.trimOrNull()
if (newTag != null) setChips(items + listOfNotNull(newTag), scope, colors) if (newTag != null) setChips(items + listOfNotNull(newTag), scope, colors)
// KMK -->
} }
.setNegativeButton(MR.strings.action_cancel.getString(context)) { .setNegativeButton(MR.strings.action_cancel.getString(context)) {
dialog?.dismissDialog() dialog?.dismissDialog()
@ -403,6 +444,7 @@ private fun ChipGroup.setChips(
dialog = builder.create() dialog = builder.create()
dialog.setView(binding.root) dialog.setView(binding.root)
dialog.show() dialog.show()
// KMK <--
} }
} }
addView(addTagChip) addView(addTagChip)
@ -416,6 +458,7 @@ private fun ChipGroup.getTextStrings(): List<String> = children.mapNotNull {
} }
}.toList() }.toList()
// KMK -->
private class SpinnerAdapter( private class SpinnerAdapter(
context: Context, context: Context,
@LayoutRes val resource: Int, @LayoutRes val resource: Int,
@ -447,7 +490,6 @@ private class SpinnerAdapter(
// If no custom field is assigned, assume the whole resource is a TextView // If no custom field is assigned, assume the whole resource is a TextView
text = view as TextView text = view as TextView
} catch (e: ClassCastException) { } catch (e: ClassCastException) {
Timber.e("You must supply a resource ID for a TextView")
throw IllegalStateException("ArrayAdapter requires the resource ID to be a TextView", e) throw IllegalStateException("ArrayAdapter requires the resource ID to be a TextView", e)
} }
@ -460,3 +502,4 @@ private class SpinnerAdapter(
return view return view
} }
} }
// KMK <--

View file

@ -136,6 +136,7 @@ class MangaScreen(
} }
val successState = state as MangaScreenModel.State.Success val successState = state as MangaScreenModel.State.Success
// KMK -->
val seedColorState = rememberUpdatedState(newValue = successState.seedColor) val seedColorState = rememberUpdatedState(newValue = successState.seedColor)
val uiPreferences = remember { Injekt.get<UiPreferences>() } val uiPreferences = remember { Injekt.get<UiPreferences>() }
@ -159,6 +160,7 @@ class MangaScreen(
screenModel: MangaScreenModel, screenModel: MangaScreenModel,
successState: MangaScreenModel.State.Success, successState: MangaScreenModel.State.Success,
) { ) {
// KMK <--
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
val haptic = LocalHapticFeedback.current val haptic = LocalHapticFeedback.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
@ -254,7 +256,15 @@ class MangaScreen(
previewsRowCount = successState.previewsRowCount, previewsRowCount = successState.previewsRowCount,
// SY --> // SY -->
onMigrateClicked = { migrateManga(navigator, screenModel.manga!!) }.takeIf { successState.manga.favorite }, onMigrateClicked = { migrateManga(navigator, screenModel.manga!!) }.takeIf { successState.manga.favorite },
onMetadataViewerClicked = { openMetadataViewer(navigator, successState.manga, successState.seedColor) }, onMetadataViewerClicked = {
openMetadataViewer(
navigator,
successState.manga,
// KMK -->
successState.seedColor,
// KMK <--
)
},
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,
@ -524,21 +534,33 @@ class MangaScreen(
return return
} }
// KMK -->
navigator.popUntil { screen -> navigator.popUntil { screen ->
navigator.size < 2 || screen is BrowseSourceScreen || navigator.size < 2 || screen is BrowseSourceScreen ||
screen is HomeScreen || screen is SourceFeedScreen screen is HomeScreen || screen is SourceFeedScreen
} }
// KMK <--
when (val previousController = navigator.lastItem) { when (val previousController = navigator.lastItem) {
is HomeScreen -> { is HomeScreen -> {
// KMK -->
// navigator.pop()
// KMK <--
previousController.search(query) previousController.search(query)
} }
is BrowseSourceScreen -> { is BrowseSourceScreen -> {
// KMK -->
// navigator.pop()
// KMK <--
previousController.search(query) previousController.search(query)
} }
// SY --> // SY -->
is SourceFeedScreen -> { is SourceFeedScreen -> {
// KMK -->
// navigator.pop()
// navigator.replace(BrowseSourceScreen(previousController.sourceId, query))
navigator.push(BrowseSourceScreen(previousController.sourceId, query)) navigator.push(BrowseSourceScreen(previousController.sourceId, query))
// KMK <--
} }
// SY <-- // SY <--
} }
@ -559,10 +581,14 @@ class MangaScreen(
while (idx >= 0) { while (idx >= 0) {
previousController = navigator.items[idx--] previousController = navigator.items[idx--]
if (previousController is BrowseSourceScreen && source is HttpSource) { if (previousController is BrowseSourceScreen && source is HttpSource) {
// KMK -->
// navigator.pop()
navigator.popUntil { navigator.size == idx + 2 } navigator.popUntil { navigator.size == idx + 2 }
// KMK <--
previousController.searchGenre(genreName) previousController.searchGenre(genreName)
return return
} }
// KMK -->
if (previousController is SourceFeedScreen && source is HttpSource) { if (previousController is SourceFeedScreen && source is HttpSource) {
navigator.popUntil { navigator.size == idx + 2 } navigator.popUntil { navigator.size == idx + 2 }
navigator.push(BrowseSourceScreen(previousController.sourceId, "")) navigator.push(BrowseSourceScreen(previousController.sourceId, ""))
@ -570,6 +596,7 @@ class MangaScreen(
previousController.searchGenre(genreName) previousController.searchGenre(genreName)
return return
} }
// KMK <--
} }
performSearch(navigator, genreName, global = false) performSearch(navigator, genreName, global = false)
} }
@ -599,7 +626,13 @@ class MangaScreen(
// SY <-- // SY <--
} }
private fun openMetadataViewer(navigator: Navigator, manga: Manga, seedColor: Color? = null) { private fun openMetadataViewer(
navigator: Navigator,
manga: Manga,
// KMK -->
seedColor: Color? = null,
// KMK <--
) {
navigator.push(MetadataViewScreen(manga.id, manga.source, seedColor)) navigator.push(MetadataViewScreen(manga.id, manga.source, seedColor))
} }

View file

@ -221,7 +221,9 @@ class MangaScreenModel(
val loggedInTrackers by lazy { trackerManager.trackers.filter { it.isLoggedIn } } val loggedInTrackers by lazy { trackerManager.trackers.filter { it.isLoggedIn } }
// KMK -->
val useNewSourceNavigation by uiPreferences.useNewSourceNavigation().asState(screenModelScope) val useNewSourceNavigation by uiPreferences.useNewSourceNavigation().asState(screenModelScope)
// KMK <--
val manga: Manga? val manga: Manga?
get() = successState?.manga get() = successState?.manga
@ -462,7 +464,9 @@ class MangaScreenModel(
// Fetch info-chapters when needed // Fetch info-chapters when needed
if (screenModelScope.isActive) { if (screenModelScope.isActive) {
val fetchFromSourceTasks = listOf( val fetchFromSourceTasks = listOf(
// KMK -->
async { syncTrackers() }, async { syncTrackers() },
// KMK <--
async { if (needRefreshInfo) fetchMangaFromSource() }, async { if (needRefreshInfo) fetchMangaFromSource() },
async { if (needRefreshChapter) fetchChaptersFromSource() }, async { if (needRefreshChapter) fetchChaptersFromSource() },
) )
@ -477,6 +481,7 @@ class MangaScreenModel(
} }
} }
// KMK -->
/** /**
* Get the color of the manga cover by loading cover with ImageRequest directly from network. * Get the color of the manga cover by loading cover with ImageRequest directly from network.
*/ */
@ -530,7 +535,6 @@ class MangaScreenModel(
) )
} }
// KMK -->
private suspend fun syncTrackers() { private suspend fun syncTrackers() {
if (!trackPreferences.autoSyncReadChapters().get()) return if (!trackPreferences.autoSyncReadChapters().get()) return
@ -558,7 +562,9 @@ class MangaScreenModel(
screenModelScope.launch { screenModelScope.launch {
updateSuccessState { it.copy(isRefreshingData = true) } updateSuccessState { it.copy(isRefreshingData = true) }
val fetchFromSourceTasks = listOf( val fetchFromSourceTasks = listOf(
// KMK -->
async { syncTrackers() }, async { syncTrackers() },
// KMK <--
async { fetchMangaFromSource(manualFetch) }, async { fetchMangaFromSource(manualFetch) },
async { fetchChaptersFromSource(manualFetch) }, async { fetchChaptersFromSource(manualFetch) },
) )
@ -1103,6 +1109,7 @@ class MangaScreenModel(
} else { } else {
downloadManager.getQueuedDownloadOrNull(chapter.id) downloadManager.getQueuedDownloadOrNull(chapter.id)
} }
// SY --> // SY -->
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
val manga = mergedData?.manga?.get(chapter.mangaId) ?: manga val manga = mergedData?.manga?.get(chapter.mangaId) ?: manga
@ -1769,6 +1776,7 @@ class MangaScreenModel(
) : Dialog ) : Dialog
data class DeleteChapters(val chapters: List<Chapter>) : Dialog data class DeleteChapters(val chapters: List<Chapter>) : Dialog
data class DuplicateManga(val manga: Manga, val duplicate: Manga) : Dialog data class DuplicateManga(val manga: Manga, val duplicate: Manga) : Dialog
/* SY --> /* SY -->
data class Migrate(val newManga: Manga, val oldManga: Manga) : Dialog data class Migrate(val newManga: Manga, val oldManga: Manga) : Dialog
SY <-- */ SY <-- */

View file

@ -18,6 +18,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.tachiyomi.databinding.DialogStubTextinputBinding import eu.kanade.tachiyomi.databinding.DialogStubTextinputBinding
import eu.kanade.tachiyomi.ui.manga.EditMangaDialogColors import eu.kanade.tachiyomi.ui.manga.EditMangaDialogColors
// KMK -->
@Suppress("UnusedReceiverParameter") @Suppress("UnusedReceiverParameter")
fun MaterialAlertDialogBuilder.binding(context: Context): DialogStubTextinputBinding { fun MaterialAlertDialogBuilder.binding(context: Context): DialogStubTextinputBinding {
return DialogStubTextinputBinding.inflate(LayoutInflater.from(context)) return DialogStubTextinputBinding.inflate(LayoutInflater.from(context))
@ -53,12 +54,14 @@ fun DialogStubTextinputBinding.setNegativeButton(text: String, onClick: () -> Un
return this return this
} }
@Suppress("unused")
fun DialogStubTextinputBinding.setHint(hint: String? = null): DialogStubTextinputBinding { fun DialogStubTextinputBinding.setHint(hint: String? = null): DialogStubTextinputBinding {
textField.hint = hint textField.hint = hint
return this return this
} }
fun DialogStubTextinputBinding.setTextEdit(prefill: String? = null): DialogStubTextinputBinding { fun DialogStubTextinputBinding.setTextEdit(prefill: String? = null): DialogStubTextinputBinding {
// KMK <--
textField.editText?.apply { textField.editText?.apply {
setText(prefill, TextView.BufferType.EDITABLE) setText(prefill, TextView.BufferType.EDITABLE)
post { post {
@ -66,6 +69,7 @@ fun DialogStubTextinputBinding.setTextEdit(prefill: String? = null): DialogStubT
context.getSystemService<InputMethodManager>()?.showSoftInput(this, 0) context.getSystemService<InputMethodManager>()?.showSoftInput(this, 0)
} }
} }
// KMK -->
return this return this
} }
@ -133,3 +137,4 @@ class RoundedCornerDrawable(val color: Int, private val cornerRadius: Float = 72
paint.colorFilter = colorFilter paint.colorFilter = colorFilter
} }
} }
// KMK <--

View file

@ -117,5 +117,7 @@ data class DummyTracker(
epochMillis: Long, epochMillis: Long,
) = Unit ) = Unit
// KMK -->
override fun hasNotStartedReading(status: Long): Boolean = status == 2L override fun hasNotStartedReading(status: Long): Boolean = status == 2L
// KMK <--
} }

View file

@ -42,7 +42,9 @@ import uy.kohesive.injekt.api.get
class MetadataViewScreen( class MetadataViewScreen(
private val mangaId: Long, private val mangaId: Long,
private val sourceId: Long, private val sourceId: Long,
// KMK -->
private val seedColor: Color? = null, private val seedColor: Color? = null,
// KMK <--
) : Screen() { ) : Screen() {
@Composable @Composable
@ -109,6 +111,7 @@ class MetadataViewScreen(
} }
} }
// KMK -->
val uiPreferences = remember { Injekt.get<UiPreferences>() } val uiPreferences = remember { Injekt.get<UiPreferences>() }
if (uiPreferences.themeCoverBased().get()) { if (uiPreferences.themeCoverBased().get()) {
@ -123,5 +126,6 @@ class MetadataViewScreen(
} else { } else {
content() content()
} }
// KMK <--
} }
} }

View file

@ -29,9 +29,11 @@ fun EHentaiDescription(
search: (String) -> Unit, search: (String) -> Unit,
) { ) {
val context = LocalContext.current val context = LocalContext.current
// KMK -->
val textColor = MaterialTheme.colorScheme.secondary.toArgb() val textColor = MaterialTheme.colorScheme.secondary.toArgb()
val iconColor = MaterialTheme.colorScheme.primary.toArgb() val iconColor = MaterialTheme.colorScheme.primary.toArgb()
val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb() val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb()
// KMK <--
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
factory = { factoryContext -> factory = { factoryContext ->
@ -50,26 +52,38 @@ fun EHentaiDescription(
} }
?: meta.genre ?: meta.genre
?: context.stringResource(MR.strings.unknown) ?: context.stringResource(MR.strings.unknown)
// KMK -->
binding.genre.setTextColor(textColor) binding.genre.setTextColor(textColor)
// KMK <--
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 -->
binding.visible.setTextColor(textColor) binding.visible.setTextColor(textColor)
// KMK <--
binding.favorites.text = (meta.favorites ?: 0).toString() binding.favorites.text = (meta.favorites ?: 0).toString()
// KMK -->
binding.favorites.bindDrawable(context, R.drawable.ic_book_24dp, iconColor) binding.favorites.bindDrawable(context, R.drawable.ic_book_24dp, iconColor)
binding.favorites.setTextColor(textColor) binding.favorites.setTextColor(textColor)
// KMK <--
binding.uploader.text = meta.uploader ?: context.stringResource(MR.strings.unknown) binding.uploader.text = meta.uploader ?: context.stringResource(MR.strings.unknown)
// KMK -->
binding.uploader.setTextColor(textColor) binding.uploader.setTextColor(textColor)
// KMK <--
binding.size.text = MetadataUtil.humanReadableByteCount(meta.size ?: 0, true) binding.size.text = MetadataUtil.humanReadableByteCount(meta.size ?: 0, true)
// KMK -->
binding.size.bindDrawable(context, R.drawable.ic_outline_sd_card_24, iconColor) binding.size.bindDrawable(context, R.drawable.ic_outline_sd_card_24, iconColor)
binding.size.setTextColor(textColor) binding.size.setTextColor(textColor)
// KMK <--
val length = meta.length ?: 0 val length = meta.length ?: 0
binding.pages.text = context.pluralStringResource(SYMR.plurals.num_pages, length, length) binding.pages.text = context.pluralStringResource(SYMR.plurals.num_pages, length, length)
// 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)
// KMK <--
val language = meta.language ?: context.stringResource(MR.strings.unknown) val language = meta.language ?: context.stringResource(MR.strings.unknown)
binding.language.text = if (meta.translated == true) { binding.language.text = if (meta.translated == true) {
@ -77,18 +91,22 @@ fun EHentaiDescription(
} else { } else {
language language
} }
// KMK -->
binding.language.setTextColor(textColor) binding.language.setTextColor(textColor)
// KMK <--
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 -->
binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor) binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor)
binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor) binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor)
binding.rating.setTextColor(textColor) binding.rating.setTextColor(textColor)
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor) binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
binding.moreInfo.setTextColor(textColor) binding.moreInfo.setTextColor(textColor)
// KMK <--
listOf( listOf(
binding.favorites, binding.favorites,

View file

@ -20,8 +20,10 @@ import tachiyomi.i18n.MR
@Composable @Composable
fun EightMusesDescription(state: State.Success, openMetadataViewer: () -> Unit) { fun EightMusesDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
// KMK -->
val textColor = MaterialTheme.colorScheme.secondary.toArgb() val textColor = MaterialTheme.colorScheme.secondary.toArgb()
val iconColor = MaterialTheme.colorScheme.primary.toArgb() val iconColor = MaterialTheme.colorScheme.primary.toArgb()
// KMK <--
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
factory = { factoryContext -> factory = { factoryContext ->
@ -33,10 +35,12 @@ fun EightMusesDescription(state: State.Success, openMetadataViewer: () -> Unit)
val binding = DescriptionAdapter8mBinding.bind(it) val binding = DescriptionAdapter8mBinding.bind(it)
binding.title.text = meta.title ?: context.stringResource(MR.strings.unknown) binding.title.text = meta.title ?: context.stringResource(MR.strings.unknown)
// KMK -->
binding.title.setTextColor(textColor) binding.title.setTextColor(textColor)
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor) binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
binding.moreInfo.setTextColor(textColor) binding.moreInfo.setTextColor(textColor)
// KMK <--
binding.title.setOnLongClickListener { binding.title.setOnLongClickListener {
context.copyToClipboard( context.copyToClipboard(
@ -45,7 +49,9 @@ fun EightMusesDescription(state: State.Success, openMetadataViewer: () -> Unit)
) )
true true
} }
// KMK -->
binding.title.setTextColor(textColor) binding.title.setTextColor(textColor)
// KMK <--
binding.moreInfo.setOnClickListener { binding.moreInfo.setOnClickListener {
openMetadataViewer() openMetadataViewer()

View file

@ -20,8 +20,10 @@ import tachiyomi.i18n.sy.SYMR
@Composable @Composable
fun HBrowseDescription(state: State.Success, openMetadataViewer: () -> Unit) { fun HBrowseDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
// KMK -->
val textColor = MaterialTheme.colorScheme.secondary.toArgb() val textColor = MaterialTheme.colorScheme.secondary.toArgb()
val iconColor = MaterialTheme.colorScheme.primary.toArgb() val iconColor = MaterialTheme.colorScheme.primary.toArgb()
// KMK <--
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
factory = { factoryContext -> factory = { factoryContext ->
@ -33,11 +35,13 @@ fun HBrowseDescription(state: State.Success, openMetadataViewer: () -> Unit) {
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 -->
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)
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor) binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
binding.moreInfo.setTextColor(textColor) binding.moreInfo.setTextColor(textColor)
// KMK <--
binding.pages.setOnLongClickListener { binding.pages.setOnLongClickListener {
context.copyToClipboard( context.copyToClipboard(

View file

@ -23,9 +23,11 @@ import kotlin.math.round
@Composable @Composable
fun MangaDexDescription(state: State.Success, openMetadataViewer: () -> Unit) { fun MangaDexDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
// KMK -->
val textColor = MaterialTheme.colorScheme.secondary.toArgb() val textColor = MaterialTheme.colorScheme.secondary.toArgb()
val iconColor = MaterialTheme.colorScheme.primary.toArgb() val iconColor = MaterialTheme.colorScheme.primary.toArgb()
val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb() val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb()
// KMK <--
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
factory = { factoryContext -> factory = { factoryContext ->
@ -43,12 +45,14 @@ fun MangaDexDescription(state: State.Success, openMetadataViewer: () -> Unit) {
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 -->
binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor) binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor)
binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor) binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor)
binding.rating.setTextColor(textColor) binding.rating.setTextColor(textColor)
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor) binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
binding.moreInfo.setTextColor(textColor) binding.moreInfo.setTextColor(textColor)
// KMK <--
binding.rating.setOnLongClickListener { binding.rating.setOnLongClickListener {
context.copyToClipboard( context.copyToClipboard(

View file

@ -64,10 +64,14 @@ object MetadataUIUtil {
fun TextView.bindDrawable( fun TextView.bindDrawable(
context: Context, context: Context,
@DrawableRes drawable: Int, @DrawableRes drawable: Int,
// KMK -->
@ColorInt color: Int = context.getResourceColor(R.attr.colorAccent), @ColorInt color: Int = context.getResourceColor(R.attr.colorAccent),
// KMK <--
) { ) {
ContextCompat.getDrawable(context, drawable)?.apply { ContextCompat.getDrawable(context, drawable)?.apply {
// KMK -->
setTint(color) setTint(color)
// KMK <--
setBounds(0, 0, 20.dpToPx, 20.dpToPx) setBounds(0, 0, 20.dpToPx, 20.dpToPx)
setCompoundDrawables(this, null, null, null) setCompoundDrawables(this, null, null, null)
} }

View file

@ -27,8 +27,10 @@ import java.time.ZonedDateTime
@Composable @Composable
fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) { fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
// KMK -->
val textColor = MaterialTheme.colorScheme.secondary.toArgb() val textColor = MaterialTheme.colorScheme.secondary.toArgb()
val iconColor = MaterialTheme.colorScheme.primary.toArgb() val iconColor = MaterialTheme.colorScheme.primary.toArgb()
// KMK <--
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
factory = { factoryContext -> factory = { factoryContext ->
@ -49,13 +51,17 @@ fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
it.second it.second
} ?: categoriesString ?: context.stringResource(MR.strings.unknown) } ?: categoriesString ?: context.stringResource(MR.strings.unknown)
} }
// KMK -->
binding.genre.setTextColor(textColor) binding.genre.setTextColor(textColor)
// KMK <--
meta.favoritesCount?.let { meta.favoritesCount?.let {
if (it == 0L) return@let if (it == 0L) return@let
binding.favorites.text = it.toString() binding.favorites.text = it.toString()
// KMK -->
binding.favorites.bindDrawable(context, R.drawable.ic_book_24dp, iconColor) binding.favorites.bindDrawable(context, R.drawable.ic_book_24dp, iconColor)
binding.favorites.setTextColor(textColor) binding.favorites.setTextColor(textColor)
// KMK <--
} }
binding.whenPosted.text = MetadataUtil.EX_DATE_FORMAT binding.whenPosted.text = MetadataUtil.EX_DATE_FORMAT
@ -63,22 +69,28 @@ fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
ZonedDateTime ZonedDateTime
.ofInstant(Instant.ofEpochSecond(meta.uploadDate ?: 0), ZoneId.systemDefault()) .ofInstant(Instant.ofEpochSecond(meta.uploadDate ?: 0), ZoneId.systemDefault())
) )
// KMK -->
binding.whenPosted.setTextColor(textColor) binding.whenPosted.setTextColor(textColor)
// KMK <--
binding.pages.text = context.pluralStringResource( binding.pages.text = context.pluralStringResource(
SYMR.plurals.num_pages, SYMR.plurals.num_pages,
meta.pageImageTypes.size, meta.pageImageTypes.size,
meta.pageImageTypes.size, meta.pageImageTypes.size,
) )
// 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)
// KMK <--
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
binding.id.text = "#" + (meta.nhId ?: 0) binding.id.text = "#" + (meta.nhId ?: 0)
// KMK -->
binding.id.setTextColor(textColor) binding.id.setTextColor(textColor)
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor) binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
binding.moreInfo.setTextColor(textColor) binding.moreInfo.setTextColor(textColor)
// KMK <--
listOf( listOf(
binding.favorites, binding.favorites,

View file

@ -25,9 +25,11 @@ import kotlin.math.round
@Composable @Composable
fun PururinDescription(state: State.Success, openMetadataViewer: () -> Unit) { fun PururinDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
// KMK -->
val textColor = MaterialTheme.colorScheme.secondary.toArgb() val textColor = MaterialTheme.colorScheme.secondary.toArgb()
val iconColor = MaterialTheme.colorScheme.primary.toArgb() val iconColor = MaterialTheme.colorScheme.primary.toArgb()
val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb() val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb()
// KMK <--
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
factory = { factoryContext -> factory = { factoryContext ->
@ -44,29 +46,39 @@ fun PururinDescription(state: State.Success, openMetadataViewer: () -> Unit) {
it.second it.second
} ?: genre?.name ?: context.stringResource(MR.strings.unknown) } ?: genre?.name ?: context.stringResource(MR.strings.unknown)
} }
// KMK -->
binding.genre.setTextColor(textColor) binding.genre.setTextColor(textColor)
// KMK <--
binding.uploader.text = meta.uploaderDisp ?: meta.uploader.orEmpty() binding.uploader.text = meta.uploaderDisp ?: meta.uploader.orEmpty()
// KMK -->
binding.uploader.setTextColor(textColor) binding.uploader.setTextColor(textColor)
// KMK <--
binding.size.text = meta.fileSize ?: context.stringResource(MR.strings.unknown) binding.size.text = meta.fileSize ?: context.stringResource(MR.strings.unknown)
// KMK -->
binding.size.bindDrawable(context, R.drawable.ic_outline_sd_card_24, iconColor) binding.size.bindDrawable(context, R.drawable.ic_outline_sd_card_24, iconColor)
binding.size.setTextColor(textColor) binding.size.setTextColor(textColor)
// KMK <--
binding.pages.text = context.pluralStringResource(SYMR.plurals.num_pages, meta.pages ?: 0, meta.pages ?: 0) binding.pages.text = context.pluralStringResource(SYMR.plurals.num_pages, meta.pages ?: 0, meta.pages ?: 0)
// 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)
// KMK <--
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 -->
binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor) binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor)
binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor) binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor)
binding.rating.setTextColor(textColor) binding.rating.setTextColor(textColor)
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor) binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
binding.moreInfo.setTextColor(textColor) binding.moreInfo.setTextColor(textColor)
// KMK <--
listOf( listOf(
binding.genre, binding.genre,

View file

@ -26,9 +26,11 @@ import kotlin.math.round
@Composable @Composable
fun TsuminoDescription(state: State.Success, openMetadataViewer: () -> Unit) { fun TsuminoDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
// KMK -->
val textColor = MaterialTheme.colorScheme.secondary.toArgb() val textColor = MaterialTheme.colorScheme.secondary.toArgb()
val iconColor = MaterialTheme.colorScheme.primary.toArgb() val iconColor = MaterialTheme.colorScheme.primary.toArgb()
val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb() val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb()
// KMK <--
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
factory = { factoryContext -> factory = { factoryContext ->
@ -43,31 +45,43 @@ fun TsuminoDescription(state: State.Success, openMetadataViewer: () -> Unit) {
binding.genre.setBackgroundColor(it.first) binding.genre.setBackgroundColor(it.first)
it.second it.second
} ?: meta.category ?: context.stringResource(MR.strings.unknown) } ?: meta.category ?: context.stringResource(MR.strings.unknown)
// KMK -->
binding.genre.setTextColor(textColor) binding.genre.setTextColor(textColor)
// KMK <--
binding.favorites.text = (meta.favorites ?: 0).toString() binding.favorites.text = (meta.favorites ?: 0).toString()
// KMK -->
binding.favorites.bindDrawable(context, R.drawable.ic_book_24dp, iconColor) binding.favorites.bindDrawable(context, R.drawable.ic_book_24dp, iconColor)
binding.favorites.setTextColor(textColor) binding.favorites.setTextColor(textColor)
// KMK <--
binding.whenPosted.text = TsuminoSearchMetadata.TSUMINO_DATE_FORMAT.format(Date(meta.uploadDate ?: 0)) binding.whenPosted.text = TsuminoSearchMetadata.TSUMINO_DATE_FORMAT.format(Date(meta.uploadDate ?: 0))
// KMK -->
binding.whenPosted.setTextColor(textColor) binding.whenPosted.setTextColor(textColor)
// KMK <--
binding.uploader.text = meta.uploader ?: context.stringResource(MR.strings.unknown) binding.uploader.text = meta.uploader ?: context.stringResource(MR.strings.unknown)
// KMK -->
binding.uploader.setTextColor(textColor) binding.uploader.setTextColor(textColor)
// 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 -->
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)
// KMK <--
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 -->
binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor) binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor)
binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor) binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor)
binding.rating.setTextColor(textColor) binding.rating.setTextColor(textColor)
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor) binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
binding.moreInfo.setTextColor(textColor) binding.moreInfo.setTextColor(textColor)
// KMK <--
listOf( listOf(
binding.favorites, binding.favorites,

View file

@ -39,9 +39,11 @@ fun UpcomingItem(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.large), horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.large),
) { ) {
// KMK -->
val mangaCover = upcoming.asMangaCover() val mangaCover = upcoming.asMangaCover()
val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) } val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) }
val onBgColor = mangaCover.dominantCoverColors?.second val onBgColor = mangaCover.dominantCoverColors?.second
// KMK <--
MangaCover.Book( MangaCover.Book(
modifier = Modifier.fillMaxHeight(), modifier = Modifier.fillMaxHeight(),
data = mangaCover, data = mangaCover,

View file

@ -35,6 +35,7 @@ class LibraryPreferences(
fun lastUpdatedTimestamp() = preferenceStore.getLong(Preference.appStateKey("library_update_last_timestamp"), 0L) fun lastUpdatedTimestamp() = preferenceStore.getLong(Preference.appStateKey("library_update_last_timestamp"), 0L)
fun autoUpdateInterval() = preferenceStore.getInt("pref_library_update_interval_key", 0) fun autoUpdateInterval() = preferenceStore.getInt("pref_library_update_interval_key", 0)
// KMK -->
fun coverRatios() = preferenceStore.getStringSet( fun coverRatios() = preferenceStore.getStringSet(
Preference.appStateKey("pref_library_cover_ratios_key"), Preference.appStateKey("pref_library_cover_ratios_key"),
emptySet(), emptySet(),
@ -44,6 +45,7 @@ class LibraryPreferences(
Preference.appStateKey("pref_library_cover_colors_key"), Preference.appStateKey("pref_library_cover_colors_key"),
emptySet(), emptySet(),
) )
// KMK <--
fun autoUpdateDeviceRestrictions() = preferenceStore.getStringSet( fun autoUpdateDeviceRestrictions() = preferenceStore.getStringSet(
"library_update_restriction", "library_update_restriction",

View file

@ -25,6 +25,7 @@ data class MangaCover(
val url: String? = customThumbnailUrl ?: ogUrl val url: String? = customThumbnailUrl ?: ogUrl
// SY <-- // SY <--
// KMK -->
/** /**
* [vibrantCoverColor] is used to set the color theme in manga detail page. * [vibrantCoverColor] is used to set the color theme in manga detail page.
* It contains color for all mangas, both in library or browsing. * It contains color for all mangas, both in library or browsing.
@ -66,8 +67,6 @@ data class MangaCover(
coverRatioMap[mangaId] = value coverRatioMap[mangaId] = value
} }
companion object { companion object {
private val getCustomMangaInfo: GetCustomMangaInfo by injectLazy()
/** /**
* [vibrantCoverColorMap] store color generated while browsing library. * [vibrantCoverColorMap] store color generated while browsing library.
* It always empty at beginning each time app starts, then add more color while browsing. * It always empty at beginning each time app starts, then add more color while browsing.
@ -84,6 +83,11 @@ data class MangaCover(
var coverColorMap = ConcurrentHashMap<Long, Pair<Int, Int>>() var coverColorMap = ConcurrentHashMap<Long, Pair<Int, Int>>()
var coverRatioMap = ConcurrentHashMap<Long, Float>() var coverRatioMap = ConcurrentHashMap<Long, Float>()
// KMK <--
// SY -->
private val getCustomMangaInfo: GetCustomMangaInfo by injectLazy()
// SY <--
} }
} }

View file

@ -29,9 +29,7 @@ data class Release(
else -> "" else -> ""
} }
// SY -->
return assets.find { it.contains("Komikku$apkVariant-") } ?: assets[0] return assets.find { it.contains("Komikku$apkVariant-") } ?: assets[0]
// SY <--
} }
/** /**

View file

@ -79,6 +79,7 @@ class GetApplicationReleaseTest {
), ),
) )
// KMK: Don't cast, will throw exception if the result is different from expected
result shouldBe GetApplicationRelease.Result.NewUpdate(release) result shouldBe GetApplicationRelease.Result.NewUpdate(release)
} }
@ -106,6 +107,7 @@ class GetApplicationReleaseTest {
), ),
) )
// KMK: Don't cast, will throw exception if the result is different from expected
result shouldBe GetApplicationRelease.Result.NewUpdate(release) result shouldBe GetApplicationRelease.Result.NewUpdate(release)
} }

View file

@ -17,7 +17,7 @@ import androidx.compose.ui.unit.dp
import tachiyomi.presentation.core.util.drawVerticalScrollbar import tachiyomi.presentation.core.util.drawVerticalScrollbar
/** /**
* LazyColumn with scrollbar. * LazyColumn with scrollbar (non-controllable).
*/ */
@Composable @Composable
fun ScrollbarLazyColumn( fun ScrollbarLazyColumn(

View file

@ -22,12 +22,16 @@ val CoverHeight = 87.dp
fun UpdatesMangaCover( fun UpdatesMangaCover(
cover: Bitmap?, cover: Bitmap?,
modifier: GlanceModifier = GlanceModifier, modifier: GlanceModifier = GlanceModifier,
// KMK -->
color: Color? = null, color: Color? = null,
// KMK <--
) { ) {
Box( Box(
modifier = modifier modifier = modifier
.size(width = CoverWidth, height = CoverHeight) .size(width = CoverWidth, height = CoverHeight)
// KMK -->
.background(color ?: Color.Unspecified) .background(color ?: Color.Unspecified)
// KMK <--
.appWidgetInnerRadius(), .appWidgetInnerRadius(),
) { ) {
if (cover != null) { if (cover != null) {

View file

@ -88,7 +88,9 @@ fun UpdatesWidget(
UpdatesMangaCover( UpdatesMangaCover(
cover = cover, cover = cover,
modifier = GlanceModifier.clickable(actionStartActivity(intent)), modifier = GlanceModifier.clickable(actionStartActivity(intent)),
// KMK -->
color = MangaCover.coverColorMap[mangaId]?.first?.let { Color(it) }, color = MangaCover.coverColorMap[mangaId]?.first?.let { Color(it) },
// KMK <--
) )
} }
} }