add KMK comment
This commit is contained in:
parent
854ea8c7f0
commit
7a99a9a9b5
79 changed files with 517 additions and 70 deletions
|
|
@ -13,7 +13,9 @@ class TrustExtension(
|
|||
) {
|
||||
|
||||
suspend fun isTrusted(pkgInfo: PackageInfo, fingerprints: List<String>): Boolean {
|
||||
// KMK -->
|
||||
if (fingerprints.contains(CreateExtensionRepo.OFFICIAL_REPO_SIGNATURE)) return true
|
||||
// KMK <--
|
||||
val trustedFingerprints = extensionRepoRepository.getAll().map { it.signingKeyFingerprint }.toHashSet()
|
||||
val key = "${pkgInfo.packageName}:${PackageInfoCompat.getLongVersionCode(pkgInfo)}:${fingerprints.last()}"
|
||||
return trustedFingerprints.any { fingerprints.contains(it) } || key in preferences.trustedExtensions().get()
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ class SyncChapterProgressWithTrack(
|
|||
private val getChaptersByMangaId: GetChaptersByMangaId,
|
||||
) {
|
||||
val trackPreferences: TrackPreferences = Injekt.get()
|
||||
|
||||
suspend fun await(
|
||||
mangaId: Long,
|
||||
remoteTrack: Track,
|
||||
|
|
@ -32,12 +33,15 @@ class SyncChapterProgressWithTrack(
|
|||
|
||||
// Current chapters in database
|
||||
val dbChapters = getChaptersByMangaId.await(mangaId)
|
||||
// KMK -->
|
||||
.reversed()
|
||||
// KMK <--
|
||||
.filter { it.isRecognizedNumber }
|
||||
|
||||
val sortedChapters = dbChapters
|
||||
.sortedBy { it.chapterNumber }
|
||||
|
||||
// KMK -->
|
||||
// Chapters to update to follow tracker: only continuous incremental chapters
|
||||
// any abnormal chapter number will stop it from updating read status further
|
||||
var lastCheckChapter: Double
|
||||
|
|
@ -49,6 +53,7 @@ class SyncChapterProgressWithTrack(
|
|||
chapter.chapterNumber >= lastCheckChapter && chapter.chapterNumber <= remoteTrack.lastChapterRead
|
||||
}
|
||||
.filter { chapter -> !chapter.read }
|
||||
// KMK <--
|
||||
.map { it.copy(read = true).toChapterUpdate() }
|
||||
|
||||
// only take into account continuous reading
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ class TrackPreferences(
|
|||
fun anilistScoreType() = preferenceStore.getString("anilist_score_type", Anilist.POINT_10)
|
||||
|
||||
fun autoUpdateTrack() = preferenceStore.getBoolean("pref_auto_update_manga_sync_key", true)
|
||||
|
||||
// KMK -->
|
||||
fun updateTrackMarkedRead() = preferenceStore.getBoolean("pref_update_tracking_marked_read_key", false)
|
||||
|
||||
fun autoSyncReadChapters() = preferenceStore.getBoolean("pref_auto_sync_read_chapters_key", false)
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,11 @@ class UiPreferences(
|
|||
|
||||
fun themeDarkAmoled() = preferenceStore.getBoolean("pref_theme_dark_amoled_key", false)
|
||||
|
||||
// KMK -->
|
||||
fun themeCoverBased() = preferenceStore.getBoolean("pref_theme_cover_based_key", true)
|
||||
|
||||
fun themeCoverBasedStyle() = preferenceStore.getEnum("pref_theme_cover_based_style_key", PaletteStyle.Vibrant)
|
||||
// KMK <--
|
||||
|
||||
fun relativeTime() = preferenceStore.getBoolean("relative_time_v2", true)
|
||||
|
||||
|
|
@ -43,7 +45,9 @@ class UiPreferences(
|
|||
|
||||
fun feedTabInFront() = preferenceStore.getBoolean("latest_tab_position", false)
|
||||
|
||||
// KMK -->
|
||||
fun expandRelatedTitles() = preferenceStore.getBoolean("expand_related_titles", true)
|
||||
// KMK <--
|
||||
|
||||
fun recommendsInOverflow() = preferenceStore.getBoolean("recommends_in_overflow", true)
|
||||
|
||||
|
|
|
|||
|
|
@ -70,8 +70,10 @@ fun ExtensionDetailsScreen(
|
|||
navigateUp: () -> Unit,
|
||||
state: ExtensionDetailsScreenModel.State,
|
||||
onClickSourcePreferences: (sourceId: Long) -> Unit,
|
||||
// KMK -->
|
||||
onClickWhatsNew: () -> Unit,
|
||||
onClickReadme: () -> Unit,
|
||||
// KMK <--
|
||||
onClickEnableAll: () -> Unit,
|
||||
onClickDisableAll: () -> Unit,
|
||||
onClickClearCookies: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ private fun ExtensionFilterContent(
|
|||
items(state.languages) { language ->
|
||||
SwitchPreferenceWidget(
|
||||
modifier = Modifier.animateItemPlacement(),
|
||||
title = LocaleHelper.getSourceDisplayName(language, context)
|
||||
// KMK -->
|
||||
+ " (${LocaleHelper.getDisplayName(language)})",
|
||||
title = LocaleHelper.getSourceDisplayName(language, context) +
|
||||
// KMK -->
|
||||
" (${LocaleHelper.getDisplayName(language)})",
|
||||
// KMK <--
|
||||
checked = language in state.enabledLanguages,
|
||||
onCheckedChanged = { onClickLang(language) },
|
||||
|
|
|
|||
|
|
@ -210,12 +210,15 @@ fun FeedAddSearchDialog(
|
|||
val context = LocalContext.current
|
||||
val savedSearchStrings = remember {
|
||||
savedSearches.map {
|
||||
// KMK -->
|
||||
it?.name ?: if (source.supportsLatest) {
|
||||
context.stringResource(MR.strings.latest)
|
||||
} else {
|
||||
context.stringResource(MR.strings.popular)
|
||||
}
|
||||
it?.name
|
||||
// KMK -->
|
||||
?: if (source.supportsLatest) {
|
||||
// KMK <--
|
||||
context.stringResource(MR.strings.latest)
|
||||
// KMK -->
|
||||
} else {
|
||||
context.stringResource(MR.strings.popular)
|
||||
}
|
||||
// KMK <--
|
||||
}.toImmutableList()
|
||||
}
|
||||
|
|
@ -244,8 +247,8 @@ fun FeedAddSearchDialog(
|
|||
@Composable
|
||||
fun <T> RadioSelector(
|
||||
options: ImmutableList<T>,
|
||||
selected: Int?,
|
||||
optionStrings: ImmutableList<String> = remember { options.map { it.toString() }.toImmutableList() },
|
||||
selected: Int?,
|
||||
onSelectOption: (Int) -> Unit = {},
|
||||
) {
|
||||
Column(Modifier.verticalScroll(rememberScrollState())) {
|
||||
|
|
|
|||
|
|
@ -98,7 +98,10 @@ fun SourcesScreen(
|
|||
|
||||
when {
|
||||
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,
|
||||
modifier = Modifier.padding(contentPadding),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -57,9 +57,11 @@ private val defaultContent: @Composable RowScope.(Source, String?) -> Unit = { s
|
|||
Text(
|
||||
text = source.name +
|
||||
// KMK -->
|
||||
(source.installedExtension?.let { extension ->
|
||||
" (${extension.name})".takeIf {extension.name != source.name }
|
||||
} ?: ""),
|
||||
(
|
||||
source.installedExtension?.let { extension ->
|
||||
" (${extension.name})".takeIf { extension.name != source.name }
|
||||
} ?: ""
|
||||
),
|
||||
// KMK <--
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
|
|||
|
|
@ -99,11 +99,10 @@ internal fun BrowseSourceComfortableGridItem(
|
|||
ogUrl = manga.thumbnailUrl,
|
||||
lastModified = manga.coverLastModified,
|
||||
),
|
||||
// KMK -->
|
||||
isSelected = isSelected,
|
||||
coverAlpha = when {
|
||||
manga.favorite -> CommonMangaItemDefaults.BrowseFavoriteCoverAlpha
|
||||
else -> 1f
|
||||
},
|
||||
// KMK <--
|
||||
coverAlpha = if (manga.favorite) CommonMangaItemDefaults.BrowseFavoriteCoverAlpha else 1f,
|
||||
coverBadgeStart = {
|
||||
InLibraryBadge(enabled = manga.favorite)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -99,11 +99,10 @@ internal fun BrowseSourceCompactGridItem(
|
|||
ogUrl = manga.thumbnailUrl,
|
||||
lastModified = manga.coverLastModified,
|
||||
),
|
||||
// KMK -->
|
||||
isSelected = isSelected,
|
||||
coverAlpha = when {
|
||||
manga.favorite -> CommonMangaItemDefaults.BrowseFavoriteCoverAlpha
|
||||
else -> 1f
|
||||
},
|
||||
// KMK <--
|
||||
coverAlpha = if (manga.favorite) CommonMangaItemDefaults.BrowseFavoriteCoverAlpha else 1f,
|
||||
coverBadgeStart = {
|
||||
InLibraryBadge(enabled = manga.favorite)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -92,11 +92,10 @@ internal fun BrowseSourceListItem(
|
|||
ogUrl = manga.thumbnailUrl,
|
||||
lastModified = manga.coverLastModified,
|
||||
),
|
||||
// KMK -->
|
||||
isSelected = isSelected,
|
||||
coverAlpha = when {
|
||||
manga.favorite -> CommonMangaItemDefaults.BrowseFavoriteCoverAlpha
|
||||
else -> 1f
|
||||
},
|
||||
// KMK <--
|
||||
coverAlpha = if (manga.favorite) CommonMangaItemDefaults.BrowseFavoriteCoverAlpha else 1f,
|
||||
badge = {
|
||||
InLibraryBadge(enabled = manga.favorite)
|
||||
// SY -->
|
||||
|
|
|
|||
|
|
@ -78,11 +78,10 @@ internal fun MangaItem(
|
|||
coverBadgeStart = {
|
||||
InLibraryBadge(enabled = isFavorite)
|
||||
},
|
||||
// KMK -->
|
||||
isSelected = isSelected,
|
||||
coverAlpha = when {
|
||||
isFavorite -> CommonMangaItemDefaults.BrowseFavoriteCoverAlpha
|
||||
else -> 1f
|
||||
},
|
||||
// KMK <--
|
||||
coverAlpha = if (isFavorite) CommonMangaItemDefaults.BrowseFavoriteCoverAlpha else 1f,
|
||||
onClick = onClick,
|
||||
onLongClick = onLongClick,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -49,15 +49,19 @@ fun HistoryItem(
|
|||
.padding(horizontal = MaterialTheme.padding.medium, vertical = MaterialTheme.padding.small),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
// KMK -->
|
||||
val mangaCover = history.coverData
|
||||
val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) }
|
||||
val onBgColor = mangaCover.dominantCoverColors?.second
|
||||
// KMK <--
|
||||
MangaCover.Book(
|
||||
modifier = Modifier.fillMaxHeight(),
|
||||
data = mangaCover,
|
||||
onClick = onClickCover,
|
||||
// KMK -->
|
||||
bgColor = bgColor,
|
||||
tint = onBgColor,
|
||||
// KMK <--
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
|
|
|||
|
|
@ -71,10 +71,14 @@ fun MangaCompactGridItem(
|
|||
coverAlpha: Float = 1f,
|
||||
coverBadgeStart: @Composable (RowScope.() -> Unit)? = null,
|
||||
coverBadgeEnd: @Composable (RowScope.() -> Unit)? = null,
|
||||
// KMK -->
|
||||
libraryColored: Boolean? = null,
|
||||
// KMK <--
|
||||
) {
|
||||
// KMK -->
|
||||
val bgColor = libraryColored?.let { coverData.dominantCoverColors?.first?.let { Color(it) } }
|
||||
val onBgColor = libraryColored?.let { coverData.dominantCoverColors?.second }
|
||||
// KMK <--
|
||||
GridItemSelectable(
|
||||
isSelected = isSelected,
|
||||
onClick = onClick,
|
||||
|
|
@ -84,11 +88,16 @@ fun MangaCompactGridItem(
|
|||
cover = {
|
||||
MangaCover.Book(
|
||||
modifier = Modifier
|
||||
// KMK -->
|
||||
// .alpha(if (isSelected) GridSelectedCoverAlpha else coverAlpha)
|
||||
// KMK <--
|
||||
.fillMaxWidth(),
|
||||
alpha = if (isSelected) GridSelectedCoverAlpha else coverAlpha,
|
||||
data = coverData,
|
||||
// KMK -->
|
||||
alpha = if (isSelected) GridSelectedCoverAlpha else coverAlpha,
|
||||
bgColor = bgColor,
|
||||
tint = onBgColor,
|
||||
// KMK <--
|
||||
)
|
||||
},
|
||||
badgesStart = coverBadgeStart,
|
||||
|
|
@ -178,10 +187,14 @@ fun MangaComfortableGridItem(
|
|||
coverBadgeStart: (@Composable RowScope.() -> Unit)? = null,
|
||||
coverBadgeEnd: (@Composable RowScope.() -> Unit)? = null,
|
||||
onClickContinueReading: (() -> Unit)? = null,
|
||||
// KMK -->
|
||||
libraryColored: Boolean? = null,
|
||||
// KMK <--
|
||||
) {
|
||||
// KMK -->
|
||||
val bgColor = libraryColored?.let { coverData.dominantCoverColors?.first?.let { Color(it) } }
|
||||
val onBgColor = libraryColored?.let { coverData.dominantCoverColors?.second }
|
||||
// KMK <--
|
||||
GridItemSelectable(
|
||||
isSelected = isSelected,
|
||||
onClick = onClick,
|
||||
|
|
@ -192,11 +205,16 @@ fun MangaComfortableGridItem(
|
|||
cover = {
|
||||
MangaCover.Book(
|
||||
modifier = Modifier
|
||||
// KMK -->
|
||||
// .alpha(if (isSelected) GridSelectedCoverAlpha else coverAlpha)
|
||||
// KMK <--
|
||||
.fillMaxWidth(),
|
||||
alpha = if (isSelected) GridSelectedCoverAlpha else coverAlpha,
|
||||
data = coverData,
|
||||
// KMK -->
|
||||
alpha = if (isSelected) GridSelectedCoverAlpha else coverAlpha,
|
||||
bgColor = bgColor,
|
||||
tint = onBgColor,
|
||||
// KMK <--
|
||||
)
|
||||
},
|
||||
badgesStart = coverBadgeStart,
|
||||
|
|
@ -334,10 +352,14 @@ fun MangaListItem(
|
|||
isSelected: Boolean = false,
|
||||
coverAlpha: Float = 1f,
|
||||
onClickContinueReading: (() -> Unit)? = null,
|
||||
// KMK -->
|
||||
libraryColored: Boolean? = null,
|
||||
// KMK <--
|
||||
) {
|
||||
// KMK -->
|
||||
val bgColor = libraryColored?.let { coverData.dominantCoverColors?.first?.let { Color(it) } }
|
||||
val onBgColor = libraryColored?.let { coverData.dominantCoverColors?.second }
|
||||
// KMK <--
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.selectedBackground(isSelected)
|
||||
|
|
@ -351,11 +373,16 @@ fun MangaListItem(
|
|||
) {
|
||||
MangaCover.Square(
|
||||
modifier = Modifier
|
||||
// KMK -->
|
||||
// .alpha(coverAlpha)
|
||||
// KMK <--
|
||||
.fillMaxHeight(),
|
||||
alpha = coverAlpha,
|
||||
data = coverData,
|
||||
// KMK -->
|
||||
alpha = coverAlpha,
|
||||
bgColor = bgColor,
|
||||
tint = onBgColor,
|
||||
// KMK <--
|
||||
)
|
||||
Text(
|
||||
text = title,
|
||||
|
|
|
|||
|
|
@ -61,7 +61,9 @@ internal fun LibraryComfortableGrid(
|
|||
} else {
|
||||
null
|
||||
},
|
||||
// KMK -->
|
||||
libraryColored = true,
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ internal fun LibraryCompactGrid(
|
|||
} else {
|
||||
null
|
||||
},
|
||||
// KMK -->
|
||||
libraryColored = true,
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,9 @@ internal fun LibraryList(
|
|||
} else {
|
||||
null
|
||||
},
|
||||
// KMK -->
|
||||
libraryColored = true,
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -445,7 +445,9 @@ private fun MangaScreenSmallImpl(
|
|||
actionModeCounter = selectedChapterCount,
|
||||
onSelectAll = { onAllChapterSelected(true) },
|
||||
onInvertSelection = { onInvertSelection() },
|
||||
// KMK -->
|
||||
onPaletteScreenClick = onPaletteScreenClick,
|
||||
// KMK <--
|
||||
)
|
||||
},
|
||||
bottomBar = {
|
||||
|
|
@ -669,7 +671,9 @@ private fun MangaScreenSmallImpl(
|
|||
chapterCount = chapters.size,
|
||||
missingChapterCount = missingChapterCount,
|
||||
onClick = onFilterClicked,
|
||||
// KMK -->
|
||||
hasFilters = state.filterActive,
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -820,7 +824,9 @@ private fun MangaScreenLargeImpl(
|
|||
actionModeCounter = selectedChapterCount,
|
||||
onSelectAll = { onAllChapterSelected(true) },
|
||||
onInvertSelection = { onInvertSelection() },
|
||||
// KMK -->
|
||||
onPaletteScreenClick = onPaletteScreenClick,
|
||||
// KMK <--
|
||||
)
|
||||
},
|
||||
bottomBar = {
|
||||
|
|
@ -1029,7 +1035,9 @@ private fun MangaScreenLargeImpl(
|
|||
chapterCount = chapters.size,
|
||||
missingChapterCount = missingChapterCount,
|
||||
onClick = onFilterButtonClicked,
|
||||
// KMK -->
|
||||
hasFilters = state.filterActive,
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ private fun NotDownloadedIndicator(
|
|||
painter = painterResource(R.drawable.ic_download_chapter_24dp),
|
||||
contentDescription = stringResource(MR.strings.manga_download),
|
||||
modifier = Modifier.size(IndicatorSize),
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
tint = MaterialTheme.colorScheme.primary, // KMK: onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -128,7 +128,7 @@ private fun DownloadingIndicator(
|
|||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
val arrowColor: Color
|
||||
val strokeColor = MaterialTheme.colorScheme.primary
|
||||
val strokeColor = MaterialTheme.colorScheme.primary // KMK: onSurfaceVariant
|
||||
val downloadProgress = downloadProgressProvider()
|
||||
val indeterminate = downloadState == Download.State.QUEUE ||
|
||||
(downloadState == Download.State.DOWNLOADING && downloadProgress == 0)
|
||||
|
|
@ -208,7 +208,7 @@ private fun DownloadedIndicator(
|
|||
imageVector = Icons.Filled.CheckCircle,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(IndicatorSize),
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
tint = MaterialTheme.colorScheme.primary, // KMK: onSurfaceVariant
|
||||
)
|
||||
DropdownMenu(expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false }) {
|
||||
DropdownMenuItem(
|
||||
|
|
|
|||
|
|
@ -29,11 +29,15 @@ fun ChapterHeader(
|
|||
chapterCount: Int?,
|
||||
missingChapterCount: Int,
|
||||
onClick: () -> Unit,
|
||||
// KMK -->
|
||||
hasFilters: Boolean,
|
||||
// KMK <--
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
// KMK -->
|
||||
val filterTint = if (hasFilters) MaterialTheme.colorScheme.active else MaterialTheme.colorScheme.primary
|
||||
Row(
|
||||
// KMK <--
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(
|
||||
|
|
@ -41,9 +45,11 @@ fun ChapterHeader(
|
|||
onClick = onClick,
|
||||
)
|
||||
.padding(horizontal = 16.dp, vertical = 4.dp),
|
||||
// KMK -->
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
// KMK <--
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall),
|
||||
) {
|
||||
|
|
@ -60,11 +66,13 @@ fun ChapterHeader(
|
|||
MissingChaptersWarning(missingChapterCount)
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.FilterList,
|
||||
contentDescription = null,
|
||||
tint = filterTint,
|
||||
)
|
||||
// KMK <--
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,11 +41,14 @@ enum class MangaCover(val ratio: Float) {
|
|||
contentDescription: String = "",
|
||||
shape: Shape = MaterialTheme.shapes.extraSmall,
|
||||
onClick: (() -> Unit)? = null,
|
||||
// KMK -->
|
||||
alpha: Float = 1f,
|
||||
bgColor: Color? = null,
|
||||
@ColorInt tint: Int? = null,
|
||||
onCoverLoaded: ((DomainMangaCover) -> Unit)? = null,
|
||||
// KMK <--
|
||||
) {
|
||||
// KMK -->
|
||||
val animatedImageVector = AnimatedImageVector.animatedVectorResource(R.drawable.anim_waiting)
|
||||
var atEnd by remember { mutableStateOf(false) }
|
||||
|
||||
|
|
@ -61,9 +64,12 @@ enum class MangaCover(val ratio: Float) {
|
|||
}
|
||||
|
||||
var succeed by remember { mutableStateOf(false) }
|
||||
// KMK <--
|
||||
|
||||
AsyncImage(
|
||||
model = data,
|
||||
// KMK -->
|
||||
// placeholder = ColorPainter(CoverPlaceholderColor),
|
||||
placeholder = rememberAnimatedVectorPainter(animatedImageVector = animatedImageVector, atEnd = atEnd),
|
||||
error = 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,
|
||||
modifier = modifier
|
||||
.aspectRatio(ratio)
|
||||
.clip(shape)
|
||||
// KMK -->
|
||||
.alpha(if (succeed) alpha else 1f)
|
||||
.background(bgColor ?: Color.Transparent)
|
||||
// KMK <--
|
||||
.then(
|
||||
if (onClick != null) {
|
||||
Modifier.clickable(
|
||||
|
|
|
|||
|
|
@ -132,12 +132,17 @@ fun MangaInfoBox(
|
|||
drawRect(
|
||||
brush = Brush.verticalGradient(
|
||||
colors = backdropGradientColors,
|
||||
// KMK -->
|
||||
startY = size.height / 2,
|
||||
// KMKM <--
|
||||
),
|
||||
)
|
||||
}
|
||||
// KMK -->
|
||||
.background(MaterialTheme.colorScheme.surfaceTint.copy(alpha = 0.4f))
|
||||
.blur(7.dp)
|
||||
// .blur(4.dp)
|
||||
// KMK <--
|
||||
.alpha(0.2f),
|
||||
)
|
||||
|
||||
|
|
@ -234,7 +239,11 @@ fun MangaActionRow(
|
|||
)
|
||||
},
|
||||
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
|
||||
} else {
|
||||
defaultActionButtonColor
|
||||
|
|
@ -255,7 +264,7 @@ fun MangaActionRow(
|
|||
MangaActionButton(
|
||||
title = stringResource(MR.strings.action_web_view),
|
||||
icon = Icons.Outlined.Public,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
color = MaterialTheme.colorScheme.primary, // KMK: defaultActionButtonColor
|
||||
onClick = onWebViewClicked,
|
||||
onLongClick = onWebViewLongClicked,
|
||||
)
|
||||
|
|
@ -265,7 +274,7 @@ fun MangaActionRow(
|
|||
MangaActionButton(
|
||||
title = stringResource(SYMR.strings.merge),
|
||||
icon = Icons.AutoMirrored.Outlined.CallMerge,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
color = MaterialTheme.colorScheme.primary, // KMK: defaultActionButtonColor
|
||||
onClick = onMergeClicked,
|
||||
)
|
||||
}
|
||||
|
|
@ -286,8 +295,10 @@ fun ExpandableMangaDescription(
|
|||
// SY <--
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
// KMK -->
|
||||
val uiPreferences = Injekt.get<UiPreferences>()
|
||||
val pureDarkMode = uiPreferences.themeDarkAmoled().get()
|
||||
// KMK <--
|
||||
Column(modifier = modifier) {
|
||||
val (expanded, onExpanded) = rememberSaveable {
|
||||
mutableStateOf(defaultExpandState)
|
||||
|
|
@ -355,7 +366,9 @@ fun ExpandableMangaDescription(
|
|||
tagSelected = it
|
||||
showMenu = true
|
||||
},
|
||||
// KMK -->
|
||||
pureDarkMode = pureDarkMode,
|
||||
// KMK <--
|
||||
)
|
||||
} else {
|
||||
// SY <--
|
||||
|
|
@ -371,7 +384,9 @@ fun ExpandableMangaDescription(
|
|||
tagSelected = it
|
||||
showMenu = true
|
||||
},
|
||||
// KMK -->
|
||||
pureDarkMode = pureDarkMode,
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -389,7 +404,9 @@ fun ExpandableMangaDescription(
|
|||
tagSelected = it
|
||||
showMenu = true
|
||||
},
|
||||
// KMK -->
|
||||
pureDarkMode = pureDarkMode,
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -427,7 +444,9 @@ private fun MangaAndSourceTitlesLarge(
|
|||
data = coverDataProvider(),
|
||||
contentDescription = stringResource(MR.strings.manga_cover),
|
||||
onClick = onCoverClick,
|
||||
// KMK -->
|
||||
onCoverLoaded = { mangaCover -> onCoverLoaded(mangaCover) },
|
||||
// KMK <--
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
MangaContentInfo(
|
||||
|
|
@ -477,7 +496,9 @@ private fun MangaAndSourceTitlesSmall(
|
|||
data = coverDataProvider(),
|
||||
contentDescription = stringResource(MR.strings.manga_cover),
|
||||
onClick = onCoverClick,
|
||||
// KMK -->
|
||||
onCoverLoaded = { mangaCover -> onCoverLoaded(mangaCover) },
|
||||
// KMK <--
|
||||
)
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
|
|
@ -636,6 +657,7 @@ private fun ColumnScope.MangaContentInfo(
|
|||
text = sourceName,
|
||||
modifier = Modifier.clickableNoIndication {
|
||||
// KMK -->
|
||||
// doSearch(sourceName, false)
|
||||
onSourceClick()
|
||||
// KMK <--
|
||||
},
|
||||
|
|
@ -695,7 +717,9 @@ private fun MangaSummary(
|
|||
contentDescription = stringResource(
|
||||
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())),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,9 @@ fun MangaToolbar(
|
|||
|
||||
modifier: Modifier = Modifier,
|
||||
backgroundAlphaProvider: () -> Float = titleAlphaProvider,
|
||||
// KMK -->
|
||||
onPaletteScreenClick: () -> Unit,
|
||||
// KMK <--
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
|
|
|
|||
|
|
@ -99,7 +99,9 @@ value class SearchMetadataChips(
|
|||
fun NamespaceTags(
|
||||
tags: SearchMetadataChips,
|
||||
onClick: (item: String) -> Unit,
|
||||
// KMK -->
|
||||
pureDarkMode: Boolean = false,
|
||||
// KMK <--
|
||||
) {
|
||||
Column(Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
tags.tags.forEach { (namespace, tags) ->
|
||||
|
|
@ -109,7 +111,9 @@ fun NamespaceTags(
|
|||
modifier = Modifier.padding(top = 4.dp),
|
||||
text = namespace,
|
||||
onClick = null,
|
||||
// KMK -->
|
||||
pureDarkMode = pureDarkMode,
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
FlowRow(
|
||||
|
|
@ -125,20 +129,28 @@ fun NamespaceTags(
|
|||
border = borderDp?.let {
|
||||
SuggestionChipDefaults.suggestionChipBorder(
|
||||
borderWidth = it,
|
||||
// KMK -->
|
||||
borderColor = MaterialTheme.colorScheme.primary,
|
||||
// KMK <--
|
||||
)
|
||||
} ?: SuggestionChipDefaults.suggestionChipBorder(
|
||||
// KMK -->
|
||||
borderColor = MaterialTheme.colorScheme.primary,
|
||||
// KMK <--
|
||||
),
|
||||
borderM3 = borderDp?.let {
|
||||
SuggestionChipDefaultsM3.suggestionChipBorder(
|
||||
enabled = true,
|
||||
borderWidth = it,
|
||||
// KMK -->
|
||||
borderColor = MaterialTheme.colorScheme.primary,
|
||||
// KMK <--
|
||||
)
|
||||
} ?: SuggestionChipDefaultsM3.suggestionChipBorder(
|
||||
enabled = true,
|
||||
// KMK -->
|
||||
borderColor = MaterialTheme.colorScheme.primary,
|
||||
// KMK <--
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -154,12 +166,17 @@ fun TagsChip(
|
|||
onClick: (() -> Unit)?,
|
||||
modifier: Modifier = Modifier,
|
||||
border: ChipBorder? = SuggestionChipDefaults.suggestionChipBorder(),
|
||||
// KMK -->
|
||||
// borderM3: BorderStroke? = SuggestionChipDefaultsM3.suggestionChipBorder(enabled = true),
|
||||
borderM3: BorderStroke? = null,
|
||||
pureDarkMode: Boolean = false,
|
||||
// KMK <--
|
||||
) {
|
||||
CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
|
||||
if (onClick != null) {
|
||||
// KMK -->
|
||||
if (borderM3 != null || pureDarkMode) {
|
||||
// KMK <--
|
||||
SuggestionChip(
|
||||
modifier = modifier,
|
||||
onClick = onClick,
|
||||
|
|
@ -171,10 +188,12 @@ fun TagsChip(
|
|||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
},
|
||||
border = borderM3 ?: SuggestionChipDefaultsM3.suggestionChipBorder(
|
||||
enabled = true,
|
||||
borderColor = MaterialTheme.colorScheme.primary,
|
||||
),
|
||||
border = borderM3
|
||||
// KMK -->
|
||||
?: SuggestionChipDefaultsM3.suggestionChipBorder(
|
||||
enabled = true,
|
||||
borderColor = MaterialTheme.colorScheme.primary,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
ElevatedSuggestionChip(
|
||||
|
|
@ -193,6 +212,7 @@ fun TagsChip(
|
|||
),
|
||||
)
|
||||
}
|
||||
// KMK <--
|
||||
} else {
|
||||
SuggestionChip(
|
||||
modifier = modifier,
|
||||
|
|
|
|||
|
|
@ -451,7 +451,9 @@ object SettingsAdvancedScreen : SearchableSettings {
|
|||
}
|
||||
},
|
||||
),
|
||||
// KMK -->
|
||||
Preference.PreferenceItem.InfoPreference(stringResource(KMR.strings.pref_private_installer_warning)),
|
||||
// KMK <--
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.ext_revoke_trust),
|
||||
onClick = {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,9 @@ object SettingsAppearanceScreen : SearchableSettings {
|
|||
|
||||
return listOf(
|
||||
getThemeGroup(uiPreferences = uiPreferences),
|
||||
// KMK -->
|
||||
getDetailsPageThemeGroup(uiPreferences = uiPreferences),
|
||||
// KMK <--
|
||||
getDisplayGroup(uiPreferences = uiPreferences),
|
||||
// SY -->
|
||||
getNavbarGroup(uiPreferences = uiPreferences),
|
||||
|
|
@ -106,6 +108,7 @@ object SettingsAppearanceScreen : SearchableSettings {
|
|||
)
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
@Composable
|
||||
private fun getDetailsPageThemeGroup(
|
||||
uiPreferences: UiPreferences,
|
||||
|
|
@ -132,6 +135,7 @@ object SettingsAppearanceScreen : SearchableSettings {
|
|||
),
|
||||
)
|
||||
}
|
||||
// KMK <--
|
||||
|
||||
@Composable
|
||||
private fun getDisplayGroup(
|
||||
|
|
@ -192,7 +196,9 @@ object SettingsAppearanceScreen : SearchableSettings {
|
|||
@Composable
|
||||
fun getForkGroup(uiPreferences: UiPreferences): Preference.PreferenceGroup {
|
||||
val previewsRowCount by uiPreferences.previewsRowCount().collectAsState()
|
||||
// KMK -->
|
||||
val sourcePreferences = remember { Injekt.get<SourcePreferences>() }
|
||||
// KMK <--
|
||||
|
||||
return Preference.PreferenceGroup(
|
||||
stringResource(SYMR.strings.pref_category_fork),
|
||||
|
|
@ -201,12 +207,14 @@ object SettingsAppearanceScreen : SearchableSettings {
|
|||
pref = uiPreferences.expandFilters(),
|
||||
title = stringResource(SYMR.strings.toggle_expand_search_filters),
|
||||
),
|
||||
// KMK -->
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
pref = uiPreferences.expandRelatedTitles(),
|
||||
title = stringResource(KMR.strings.pref_expand_related_titles),
|
||||
subtitle = stringResource(KMR.strings.pref_expand_related_titles_summary),
|
||||
enabled = sourcePreferences.relatedMangas().get(),
|
||||
),
|
||||
// KMK <--
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
pref = uiPreferences.recommendsInOverflow(),
|
||||
title = stringResource(SYMR.strings.put_recommends_in_overflow),
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ object SettingsTrackingScreen : SearchableSettings {
|
|||
pref = trackPreferences.autoUpdateTrack(),
|
||||
title = stringResource(MR.strings.pref_auto_update_manga_sync),
|
||||
),
|
||||
// KMK -->
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
pref = trackPreferences.updateTrackMarkedRead(),
|
||||
title = stringResource(KMR.strings.pref_update_tracking_marked_read),
|
||||
|
|
@ -134,6 +135,7 @@ object SettingsTrackingScreen : SearchableSettings {
|
|||
pref = trackPreferences.autoSyncReadChapters(),
|
||||
title = stringResource(KMR.strings.pref_auto_sync_read_chapters),
|
||||
),
|
||||
// KMK <--
|
||||
Preference.PreferenceGroup(
|
||||
title = stringResource(MR.strings.services),
|
||||
preferenceItems = persistentListOf(
|
||||
|
|
|
|||
|
|
@ -329,6 +329,7 @@ object AboutScreen : Screen() {
|
|||
}
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
private suspend fun getReleaseNotes(
|
||||
context: Context,
|
||||
onAvailableUpdate: (GetApplicationRelease.Result.NewUpdate) -> Unit,
|
||||
|
|
@ -351,6 +352,7 @@ object AboutScreen : Screen() {
|
|||
}
|
||||
}
|
||||
}
|
||||
// KMK <--
|
||||
|
||||
fun getVersionName(withBuildDate: Boolean): String {
|
||||
return when {
|
||||
|
|
|
|||
|
|
@ -50,11 +50,13 @@ fun WhatsNewDialog(onDismissRequest: () -> Unit) {
|
|||
}
|
||||
},
|
||||
title = { Text(text = stringResource(MR.strings.updated_version, BuildConfig.VERSION_NAME)) },
|
||||
// KMK -->
|
||||
dismissButton = {
|
||||
TextButton(onClick = { context.openInBrowser(RELEASE_URL) }) {
|
||||
Text(text = stringResource(KMR.strings.changelogs))
|
||||
}
|
||||
},
|
||||
// KMK <--
|
||||
text = {
|
||||
Column {
|
||||
val changelog by produceState<List<DisplayChangelog>?>(initialValue = null) {
|
||||
|
|
|
|||
|
|
@ -169,17 +169,21 @@ private fun UpdatesUiItem(
|
|||
.padding(horizontal = MaterialTheme.padding.medium),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
// KMK -->
|
||||
val mangaCover = update.coverData
|
||||
val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) }
|
||||
val onBgColor = mangaCover.dominantCoverColors?.second
|
||||
// KMK <--
|
||||
MangaCover.Square(
|
||||
modifier = Modifier
|
||||
.padding(vertical = 6.dp)
|
||||
.fillMaxHeight(),
|
||||
data = mangaCover,
|
||||
onClick = onClickCover,
|
||||
// KMK -->
|
||||
bgColor = bgColor,
|
||||
tint = onBgColor,
|
||||
// KMK <--
|
||||
)
|
||||
|
||||
Column(
|
||||
|
|
|
|||
|
|
@ -20,12 +20,19 @@ import androidx.core.graphics.drawable.toBitmap
|
|||
* @return the bitmap associated with the resource
|
||||
*/
|
||||
@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
|
||||
return remember(id) {
|
||||
val drawable = ContextCompat.getDrawable(context, id)
|
||||
?: throw Resources.NotFoundException()
|
||||
// KMK -->
|
||||
tint?.let { drawable.setTint(it) }
|
||||
// KMK <--
|
||||
BitmapPainter(drawable.toBitmap().asImageBitmap())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,8 +101,10 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
|
|||
@SuppressLint("LaunchActivityFromNotification")
|
||||
override fun onCreate() {
|
||||
super<Application>.onCreate()
|
||||
// KMK -->
|
||||
Firebase.initialize(this)
|
||||
if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
|
||||
// KMK <--
|
||||
|
||||
// SY -->
|
||||
if (!isDevFlavor) {
|
||||
|
|
@ -168,7 +170,9 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
|
|||
|
||||
setAppCompatDelegateThemeMode(Injekt.get<UiPreferences>().themeMode().get())
|
||||
|
||||
// KMK -->
|
||||
MangaCoverMetadata.load()
|
||||
// KMK <--
|
||||
|
||||
// Updates widget update
|
||||
with(WidgetManager(Injekt.get(), Injekt.get())) {
|
||||
|
|
|
|||
|
|
@ -56,8 +56,11 @@ import java.io.IOException
|
|||
*/
|
||||
@Suppress("LongParameterList")
|
||||
class MangaCoverFetcher(
|
||||
// KMK -->
|
||||
private val mangaCover: MangaCover,
|
||||
private val url: String? = mangaCover.url,
|
||||
// private val url: String?,
|
||||
// KMK <--
|
||||
private val isLibraryManga: Boolean,
|
||||
private val options: Options,
|
||||
private val coverFileLazy: Lazy<File?>,
|
||||
|
|
@ -68,8 +71,10 @@ class MangaCoverFetcher(
|
|||
private val imageLoader: ImageLoader,
|
||||
) : Fetcher {
|
||||
|
||||
// KMK -->
|
||||
private val fileScope by lazy { CoroutineScope(Job() + Dispatchers.IO) }
|
||||
private val uiPreferences = Injekt.get<UiPreferences>()
|
||||
// KMK <--
|
||||
|
||||
private val diskCacheKey: String
|
||||
get() = diskCacheKeyLazy.value
|
||||
|
|
@ -98,7 +103,9 @@ class MangaCoverFetcher(
|
|||
}
|
||||
|
||||
private fun fileLoader(file: File): FetchResult {
|
||||
// KMK -->
|
||||
setRatioAndColorsInScope(mangaCover, ogFile = file)
|
||||
// KMK <--
|
||||
return SourceFetchResult(
|
||||
source = ImageSource(
|
||||
file = file.toOkioPath(),
|
||||
|
|
@ -111,7 +118,9 @@ class MangaCoverFetcher(
|
|||
}
|
||||
|
||||
private fun fileUriLoader(uri: String): FetchResult {
|
||||
// KMK -->
|
||||
setRatioAndColorsInScope(mangaCover)
|
||||
// KMK <--
|
||||
val source = UniFile.fromUri(options.context, uri.toUri())!!
|
||||
.openInputStream()
|
||||
.source()
|
||||
|
|
@ -145,7 +154,9 @@ class MangaCoverFetcher(
|
|||
}
|
||||
|
||||
// Read from snapshot
|
||||
// KMK -->
|
||||
setRatioAndColorsInScope(mangaCover, bufferedSource = snapshot.toImageSource().source())
|
||||
// KMK <--
|
||||
return SourceFetchResult(
|
||||
source = snapshot.toImageSource(),
|
||||
mimeType = "image/*",
|
||||
|
|
@ -166,7 +177,9 @@ class MangaCoverFetcher(
|
|||
// Read from disk cache
|
||||
snapshot = writeToDiskCache(response)
|
||||
if (snapshot != null) {
|
||||
// KMK -->
|
||||
setRatioAndColorsInScope(mangaCover, bufferedSource = snapshot.toImageSource().source())
|
||||
// KMK <--
|
||||
return SourceFetchResult(
|
||||
source = snapshot.toImageSource(),
|
||||
mimeType = "image/*",
|
||||
|
|
@ -174,6 +187,7 @@ class MangaCoverFetcher(
|
|||
)
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
setRatioAndColorsInScope(
|
||||
mangaCover,
|
||||
bufferedSource = ImageSource(
|
||||
|
|
@ -181,6 +195,7 @@ class MangaCoverFetcher(
|
|||
fileSystem = FileSystem.SYSTEM,
|
||||
).source(),
|
||||
)
|
||||
// KMK <--
|
||||
// Read from response if cache is unused or unusable
|
||||
return SourceFetchResult(
|
||||
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]
|
||||
*
|
||||
|
|
@ -338,6 +354,7 @@ class MangaCoverFetcher(
|
|||
MangaCoverMetadata.setRatioAndColors(mangaCover, bufferedSource, ogFile, onlyFavorite, force)
|
||||
}
|
||||
}
|
||||
// KMK <--
|
||||
|
||||
private enum class Type {
|
||||
File,
|
||||
|
|
@ -354,7 +371,10 @@ class MangaCoverFetcher(
|
|||
|
||||
override fun create(data: Manga, options: Options, imageLoader: ImageLoader): Fetcher {
|
||||
return MangaCoverFetcher(
|
||||
// KMK -->
|
||||
// url = data.thumbnailUrl,
|
||||
mangaCover = data.asMangaCover(),
|
||||
// KMK <--
|
||||
isLibraryManga = data.favorite,
|
||||
options = options,
|
||||
coverFileLazy = lazy { coverCache.getCoverFile(data.thumbnailUrl) },
|
||||
|
|
@ -376,7 +396,10 @@ class MangaCoverFetcher(
|
|||
|
||||
override fun create(data: MangaCover, options: Options, imageLoader: ImageLoader): Fetcher {
|
||||
return MangaCoverFetcher(
|
||||
// KMK -->
|
||||
// url = data.url,
|
||||
mangaCover = data,
|
||||
// KMK <--
|
||||
isLibraryManga = data.isMangaFavorite,
|
||||
options = options,
|
||||
coverFileLazy = lazy { coverCache.getCoverFile(data.url) },
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* cover when open a manga detail or change cover will be updated separately on [MangaScreenModel.setPaletteColor].
|
||||
*
|
||||
* @author Jays2Kings, cuong-tran
|
||||
*/
|
||||
fun setRatioAndColors(
|
||||
mangaCover: MangaCover,
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ val Options.customDecoder: Boolean
|
|||
|
||||
private val customDecoderKey = Extras.Key(default = false)
|
||||
|
||||
// KMK -->
|
||||
/**
|
||||
* Calculate the best [Palette.Swatch] from [Palette]
|
||||
* @author Jays2Kings
|
||||
|
|
@ -82,3 +83,4 @@ fun Palette.getBestColor(): Int? {
|
|||
}
|
||||
}?.rgb
|
||||
}
|
||||
// KMK <--
|
||||
|
|
|
|||
|
|
@ -85,11 +85,11 @@ class DownloadCache(
|
|||
* 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.
|
||||
*/
|
||||
private val renewInterval //= 1.hours.inWholeMilliseconds
|
||||
private val renewInterval // = 1.hours.inWholeMilliseconds
|
||||
// KMK -->
|
||||
get() = downloadPreferences.downloadCacheRenewInterval().get()
|
||||
.hours.inWholeMilliseconds
|
||||
// KMK <--
|
||||
// KMK <--
|
||||
|
||||
/**
|
||||
* The last time the cache was refreshed.
|
||||
|
|
@ -330,7 +330,11 @@ class DownloadCache(
|
|||
lastRenew = 0L
|
||||
renewalJob?.cancel()
|
||||
diskCacheFile.delete()
|
||||
renewCache(/* KMK --> */ 0L /* KMK <-- */)
|
||||
renewCache(
|
||||
// KMK -->
|
||||
renewInterval = 0L,
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
|
|
@ -345,9 +349,18 @@ class DownloadCache(
|
|||
/**
|
||||
* 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
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,5 +80,7 @@ interface Tracker {
|
|||
|
||||
suspend fun setRemoteFinishDate(track: Track, epochMillis: Long)
|
||||
|
||||
// KMK -->
|
||||
fun hasNotStartedReading(status: Long): Boolean
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -241,5 +241,7 @@ class Anilist(id: Long) : BaseTracker(id, "AniList"), DeletableTracker {
|
|||
}
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,5 +148,7 @@ class Bangumi(id: Long) : BaseTracker(id, "Bangumi") {
|
|||
.toImmutableList()
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,5 +145,7 @@ class Kavita(id: Long) : BaseTracker(id, "Kavita"), EnhancedTracker {
|
|||
authentications = oauth
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
override fun hasNotStartedReading(status: Long): Boolean = status == UNREAD
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,5 +154,7 @@ class Kitsu(id: Long) : BaseTracker(id, "Kitsu"), DeletableTracker {
|
|||
}
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,5 +112,7 @@ class Komga(id: Long) : BaseTracker(id, "Komga"), EnhancedTracker {
|
|||
null
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
override fun hasNotStartedReading(status: Long): Boolean = status == UNREAD
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,5 +121,7 @@ class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), DeletableTracker
|
|||
return trackPreferences.trackPassword(this).get().ifBlank { null }
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
override fun hasNotStartedReading(status: Long): Boolean = status == WISH_LIST
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,5 +173,7 @@ class MdList(id: Long) : BaseTracker(id, "MDList") {
|
|||
|
||||
class MangaDexNotFoundException : Exception("Mangadex not enabled")
|
||||
|
||||
// KMK -->
|
||||
override fun hasNotStartedReading(status: Long): Boolean = status == FollowStatus.PLAN_TO_READ.long
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,5 +175,7 @@ class MyAnimeList(id: Long) : BaseTracker(id, "MyAnimeList"), DeletableTracker {
|
|||
}
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,5 +152,7 @@ class Shikimori(id: Long) : BaseTracker(id, "Shikimori"), DeletableTracker {
|
|||
interceptor.newAuth(null)
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
override fun hasNotStartedReading(status: Long): Boolean = status == PLAN_TO_READ
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,5 +104,7 @@ class Suwayomi(id: Long) : BaseTracker(id, "Suwayomi"), EnhancedTracker {
|
|||
null
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
override fun hasNotStartedReading(status: Long): Boolean = status == UNREAD
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,12 @@ data class BrowseTab(
|
|||
)
|
||||
} else if (feedTabInFront) {
|
||||
persistentListOf(
|
||||
feedTab(/* KMK --> */feedScreenModel, bulkFavoriteScreenModel/* KMK <-- */),
|
||||
feedTab(
|
||||
// KMK -->
|
||||
feedScreenModel,
|
||||
bulkFavoriteScreenModel,
|
||||
// KMK <--
|
||||
),
|
||||
sourcesTab(),
|
||||
extensionsTab(extensionsScreenModel),
|
||||
migrateSourceTab(),
|
||||
|
|
@ -90,7 +95,12 @@ data class BrowseTab(
|
|||
} else {
|
||||
persistentListOf(
|
||||
sourcesTab(),
|
||||
feedTab(/* KMK --> */feedScreenModel, bulkFavoriteScreenModel/* KMK <-- */),
|
||||
feedTab(
|
||||
// KMK -->
|
||||
feedScreenModel,
|
||||
bulkFavoriteScreenModel,
|
||||
// KMK <--
|
||||
),
|
||||
extensionsTab(extensionsScreenModel),
|
||||
migrateSourceTab(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -30,14 +30,18 @@ data class ExtensionDetailsScreen(
|
|||
}
|
||||
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
// KMK -->
|
||||
val uriHandler = LocalUriHandler.current
|
||||
// KMK <--
|
||||
|
||||
ExtensionDetailsScreen(
|
||||
navigateUp = navigator::pop,
|
||||
state = state,
|
||||
onClickSourcePreferences = { navigator.push(SourcePreferencesScreen(it)) },
|
||||
// KMK -->
|
||||
onClickWhatsNew = { uriHandler.openUri(screenModel.getChangelogUrl()) },
|
||||
onClickReadme = { uriHandler.openUri(screenModel.getReadmeUrl()) },
|
||||
// KMK <--
|
||||
onClickEnableAll = { screenModel.toggleSources(true) },
|
||||
onClickDisableAll = { screenModel.toggleSources(false) },
|
||||
onClickClearCookies = screenModel::clearCookies,
|
||||
|
|
|
|||
|
|
@ -131,8 +131,9 @@ open class FeedScreenModel(
|
|||
source,
|
||||
(
|
||||
// KMK -->
|
||||
// (if (source.supportsLatest) persistentListOf(null) else persistentListOf()) +
|
||||
persistentListOf(null) +
|
||||
// KMK <-->
|
||||
// KMK <-->
|
||||
getSourceSavedSearches(source.id)
|
||||
).toImmutableList(),
|
||||
),
|
||||
|
|
@ -152,7 +153,7 @@ open class FeedScreenModel(
|
|||
}
|
||||
|
||||
private suspend fun hasTooManyFeeds(): Boolean {
|
||||
return countFeedSavedSearchGlobal.await() > MAX_FEED_ITEMS
|
||||
return countFeedSavedSearchGlobal.await() > MaxFeedItems
|
||||
}
|
||||
|
||||
fun getEnabledSources(): ImmutableList<CatalogueSource> {
|
||||
|
|
@ -234,10 +235,13 @@ open class FeedScreenModel(
|
|||
withContext(coroutineDispatcher) {
|
||||
if (itemUI.savedSearch == null) {
|
||||
// KMK -->
|
||||
if (itemUI.source.supportsLatest)
|
||||
if (itemUI.source.supportsLatest) {
|
||||
// KMK <--
|
||||
itemUI.source.getLatestUpdates(1)
|
||||
else
|
||||
// KMK -->
|
||||
} else {
|
||||
itemUI.source.getPopularManga(1)
|
||||
}
|
||||
// KMK <--
|
||||
} else {
|
||||
itemUI.source.getSearchManga(
|
||||
|
|
@ -331,4 +335,4 @@ data class FeedScreenState(
|
|||
get() = items?.fastAny { it.results == null } != false
|
||||
}
|
||||
|
||||
const val MAX_FEED_ITEMS = 20
|
||||
const val MaxFeedItems = 20
|
||||
|
|
|
|||
|
|
@ -112,9 +112,9 @@ fun feedTab(
|
|||
listingQuery = if (!source.supportsLatest) {
|
||||
GetRemoteManga.QUERY_POPULAR
|
||||
} else {
|
||||
// KMK <--
|
||||
GetRemoteManga.QUERY_LATEST
|
||||
},
|
||||
// KMK <--
|
||||
),
|
||||
)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ class SourcesScreenModel(
|
|||
// KMK -->
|
||||
filters: Pair<String?, Boolean>,
|
||||
unfilteredSources: List<Source>,
|
||||
// sources: List<Source>,
|
||||
// KMK <--
|
||||
categories: List<String>,
|
||||
showLatest: Boolean,
|
||||
|
|
|
|||
|
|
@ -166,7 +166,10 @@ class SourceFeedScreen(val sourceId: Long) : Screen() {
|
|||
openMangaDexRandom = if (screenModel.sourceIsMangaDex) {
|
||||
{
|
||||
screenModel.onMangaDexRandom {
|
||||
// KMK -->
|
||||
// navigator.replace(
|
||||
navigator.push(
|
||||
// KMK <--
|
||||
BrowseSourceScreen(
|
||||
sourceId,
|
||||
"id:$it",
|
||||
|
|
@ -179,7 +182,10 @@ class SourceFeedScreen(val sourceId: Long) : Screen() {
|
|||
},
|
||||
openMangaDexFollows = if (screenModel.sourceIsMangaDex) {
|
||||
{
|
||||
// KMK -->
|
||||
// navigator.replace(MangaDexFollowsScreen(sourceId))
|
||||
navigator.push(MangaDexFollowsScreen(sourceId))
|
||||
// KMK <--
|
||||
}
|
||||
} else {
|
||||
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) {
|
||||
// KMK -->
|
||||
// navigator.replace(BrowseSourceScreen(sourceId, search, savedSearch = savedSearch, filtersJson = filters))
|
||||
navigator.push(BrowseSourceScreen(sourceId, search, savedSearch = savedSearch, filtersJson = filters))
|
||||
// KMK <--
|
||||
}
|
||||
|
||||
private fun onLatestClick(navigator: Navigator, source: Source) {
|
||||
// KMK -->
|
||||
// navigator.replace(BrowseSourceScreen(source.id, GetRemoteManga.QUERY_LATEST))
|
||||
navigator.push(BrowseSourceScreen(source.id, GetRemoteManga.QUERY_LATEST))
|
||||
// KMK <--
|
||||
}
|
||||
|
||||
fun onBrowseClick(navigator: Navigator, source: Source) {
|
||||
// KMK -->
|
||||
// navigator.replace(BrowseSourceScreen(source.id, GetRemoteManga.QUERY_POPULAR))
|
||||
navigator.push(BrowseSourceScreen(source.id, GetRemoteManga.QUERY_POPULAR))
|
||||
// KMK <--
|
||||
}
|
||||
|
||||
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))
|
||||
// KMK <--
|
||||
}
|
||||
|
||||
private fun onSearchClick(navigator: Navigator, source: Source, query: String) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import eu.kanade.presentation.browse.SourceFeedUI
|
|||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
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.mangaDexSourceIds
|
||||
import exh.util.nullIfBlank
|
||||
|
|
@ -109,7 +109,7 @@ open class SourceFeedScreenModel(
|
|||
}
|
||||
|
||||
private suspend fun hasTooManyFeeds(): Boolean {
|
||||
return countFeedSavedSearchBySourceId.await(source.id) > MAX_FEED_ITEMS
|
||||
return countFeedSavedSearchBySourceId.await(source.id) > MaxFeedItems
|
||||
}
|
||||
|
||||
fun createFeed(savedSearchId: Long) {
|
||||
|
|
|
|||
|
|
@ -290,6 +290,9 @@ object LibraryTab : Tab {
|
|||
initialSelection = dialog.initialSelection,
|
||||
onDismissRequest = onDismissRequest,
|
||||
onEditCategories = {
|
||||
// KMK -->
|
||||
// screenModel.clearSelection()
|
||||
// KMK <--
|
||||
navigator.push(CategoryScreen())
|
||||
},
|
||||
onConfirm = { include, exclude ->
|
||||
|
|
|
|||
|
|
@ -337,10 +337,12 @@ class MainActivity : BaseActivity() {
|
|||
// SY -->
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
MangaCoverMetadata.savePrefs()
|
||||
}
|
||||
// KMK <--
|
||||
|
||||
override fun onProvideAssistContent(outContent: AssistContent) {
|
||||
super.onProvideAssistContent(outContent)
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ import tachiyomi.i18n.MR
|
|||
import tachiyomi.i18n.sy.SYMR
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import tachiyomi.source.local.isLocal
|
||||
import timber.log.Timber
|
||||
|
||||
@Composable
|
||||
fun EditMangaDialog(
|
||||
|
|
@ -78,6 +77,7 @@ fun EditMangaDialog(
|
|||
var binding by remember {
|
||||
mutableStateOf<EditMangaDialogBinding?>(null)
|
||||
}
|
||||
// KMK -->
|
||||
val colors = EditMangaDialogColors(
|
||||
textColor = MaterialTheme.colorScheme.onSurfaceVariant.toArgb(),
|
||||
textHighlightColor = MaterialTheme.colorScheme.outline.toArgb(),
|
||||
|
|
@ -89,6 +89,7 @@ fun EditMangaDialog(
|
|||
dropdownBgColor = MaterialTheme.colorScheme.surfaceVariant.toArgb(),
|
||||
dialogBgColor = MaterialTheme.colorScheme.surfaceContainerHigh.toArgb(),
|
||||
)
|
||||
// KMK <--
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
confirmButton = {
|
||||
|
|
@ -142,7 +143,9 @@ fun EditMangaDialog(
|
|||
factoryContext,
|
||||
this,
|
||||
scope,
|
||||
// KMK -->
|
||||
colors,
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
.root
|
||||
|
|
@ -154,6 +157,7 @@ fun EditMangaDialog(
|
|||
)
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
class EditMangaDialogColors(
|
||||
@ColorInt val textColor: Int,
|
||||
@ColorInt val textHighlightColor: Int,
|
||||
|
|
@ -165,17 +169,23 @@ class EditMangaDialogColors(
|
|||
@ColorInt val dropdownBgColor: Int,
|
||||
@ColorInt val dialogBgColor: Int,
|
||||
)
|
||||
// KMK <--
|
||||
|
||||
private fun onViewCreated(
|
||||
manga: Manga,
|
||||
context: Context,
|
||||
binding: EditMangaDialogBinding,
|
||||
scope: CoroutineScope,
|
||||
// KMK -->
|
||||
colors: EditMangaDialogColors,
|
||||
// KMK <--
|
||||
) {
|
||||
loadCover(manga, binding)
|
||||
|
||||
// KMK -->
|
||||
// val statusAdapter: ArrayAdapter<String> = ArrayAdapter(
|
||||
val statusAdapter = SpinnerAdapter(
|
||||
// KMK <--
|
||||
context,
|
||||
android.R.layout.simple_spinner_dropdown_item,
|
||||
listOf(
|
||||
|
|
@ -187,7 +197,9 @@ private fun onViewCreated(
|
|||
MR.strings.cancelled,
|
||||
MR.strings.on_hiatus,
|
||||
).map { context.stringResource(it) },
|
||||
// KMK -->
|
||||
colors,
|
||||
// KMK <--
|
||||
)
|
||||
|
||||
binding.status.adapter = statusAdapter
|
||||
|
|
@ -206,6 +218,7 @@ private fun onViewCreated(
|
|||
)
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
// Set Spinner's selected item's background color to transparent
|
||||
binding.status.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>, view: View?, pos: Int, id: Long) {
|
||||
|
|
@ -216,6 +229,7 @@ private fun onViewCreated(
|
|||
|
||||
// Set Spinner's dropdown caret color
|
||||
binding.status.backgroundTintList = ColorStateList.valueOf(colors.iconColor)
|
||||
// KMK
|
||||
|
||||
if (manga.isLocal()) {
|
||||
if (manga.title != manga.url) {
|
||||
|
|
@ -265,6 +279,7 @@ private fun onViewCreated(
|
|||
}
|
||||
binding.mangaGenresTags.clearFocus()
|
||||
|
||||
// KMK -->
|
||||
listOf(
|
||||
binding.title,
|
||||
binding.mangaAuthor,
|
||||
|
|
@ -308,6 +323,7 @@ private fun onViewCreated(
|
|||
binding.resetTags.setBackgroundColor(colors.btnBgColor)
|
||||
binding.resetInfo.setTextColor(colors.btnTextColor)
|
||||
binding.resetInfo.setBackgroundColor(colors.btnBgColor)
|
||||
// KMK <--
|
||||
|
||||
binding.resetTags.setOnClickListener { resetTags(manga, binding, scope, colors) }
|
||||
binding.resetInfo.setOnClickListener { resetInfo(manga, binding, scope, colors) }
|
||||
|
|
@ -317,7 +333,9 @@ private fun resetTags(
|
|||
manga: Manga,
|
||||
binding: EditMangaDialogBinding,
|
||||
scope: CoroutineScope,
|
||||
// KMK -->
|
||||
colors: EditMangaDialogColors,
|
||||
// KMK <--
|
||||
) {
|
||||
if (manga.genre.isNullOrEmpty() || manga.isLocal()) {
|
||||
binding.mangaGenresTags.setChips(emptyList(), scope, colors)
|
||||
|
|
@ -336,7 +354,9 @@ private fun resetInfo(
|
|||
manga: Manga,
|
||||
binding: EditMangaDialogBinding,
|
||||
scope: CoroutineScope,
|
||||
// KMK -->
|
||||
colors: EditMangaDialogColors,
|
||||
// KMK <--
|
||||
) {
|
||||
binding.title.setText("")
|
||||
binding.mangaAuthor.setText("")
|
||||
|
|
@ -349,24 +369,35 @@ private fun resetInfo(
|
|||
private fun ChipGroup.setChips(
|
||||
items: List<String>,
|
||||
scope: CoroutineScope,
|
||||
// KMK -->
|
||||
colors: EditMangaDialogColors,
|
||||
// KMK <--
|
||||
) {
|
||||
removeAllViews()
|
||||
|
||||
// KMK -->
|
||||
val colorStateList = ColorStateList.valueOf(colors.tagColor)
|
||||
// KMK <--
|
||||
|
||||
items.asSequence().map { item ->
|
||||
Chip(context).apply {
|
||||
text = item
|
||||
// KMK -->
|
||||
setTextColor(colors.tagTextColor)
|
||||
// KMK <--
|
||||
|
||||
isCloseIconVisible = true
|
||||
// KMK -->
|
||||
// closeIcon?.setTint(context.getResourceColor(R.attr.colorAccent))
|
||||
closeIcon?.setTint(colors.iconColor)
|
||||
// KMK <--
|
||||
setOnCloseIconClickListener {
|
||||
removeView(this)
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
chipBackgroundColor = colorStateList
|
||||
// KMK <--
|
||||
}
|
||||
}.forEach {
|
||||
addView(it)
|
||||
|
|
@ -374,16 +405,24 @@ private fun ChipGroup.setChips(
|
|||
|
||||
val addTagChip = Chip(context).apply {
|
||||
text = SYMR.strings.add_tag.getString(context)
|
||||
// KMK -->
|
||||
setTextColor(colors.tagTextColor)
|
||||
// KMK <--
|
||||
|
||||
chipIcon = ContextCompat.getDrawable(context, R.drawable.ic_add_24dp)?.apply {
|
||||
isChipIconVisible = true
|
||||
// KMK -->
|
||||
// setTint(context.getResourceColor(R.attr.colorAccent))
|
||||
setTint(colors.iconColor)
|
||||
// KMK <--
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
chipBackgroundColor = colorStateList
|
||||
// KMK <--
|
||||
|
||||
setOnClickListener {
|
||||
// KMK -->
|
||||
var dialog: AlertDialog? = null
|
||||
|
||||
val builder = MaterialAlertDialogBuilder(context)
|
||||
|
|
@ -391,8 +430,10 @@ private fun ChipGroup.setChips(
|
|||
.setTitle(SYMR.strings.add_tag.getString(context))
|
||||
.setPositiveButton(MR.strings.action_ok.getString(context)) {
|
||||
dialog?.dismissDialog()
|
||||
// KMK <--
|
||||
val newTag = it.trimOrNull()
|
||||
if (newTag != null) setChips(items + listOfNotNull(newTag), scope, colors)
|
||||
// KMK -->
|
||||
}
|
||||
.setNegativeButton(MR.strings.action_cancel.getString(context)) {
|
||||
dialog?.dismissDialog()
|
||||
|
|
@ -403,6 +444,7 @@ private fun ChipGroup.setChips(
|
|||
dialog = builder.create()
|
||||
dialog.setView(binding.root)
|
||||
dialog.show()
|
||||
// KMK <--
|
||||
}
|
||||
}
|
||||
addView(addTagChip)
|
||||
|
|
@ -416,6 +458,7 @@ private fun ChipGroup.getTextStrings(): List<String> = children.mapNotNull {
|
|||
}
|
||||
}.toList()
|
||||
|
||||
// KMK -->
|
||||
private class SpinnerAdapter(
|
||||
context: Context,
|
||||
@LayoutRes val resource: Int,
|
||||
|
|
@ -447,7 +490,6 @@ private class SpinnerAdapter(
|
|||
// If no custom field is assigned, assume the whole resource is a TextView
|
||||
text = view as TextView
|
||||
} 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)
|
||||
}
|
||||
|
||||
|
|
@ -460,3 +502,4 @@ private class SpinnerAdapter(
|
|||
return view
|
||||
}
|
||||
}
|
||||
// KMK <--
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ class MangaScreen(
|
|||
}
|
||||
|
||||
val successState = state as MangaScreenModel.State.Success
|
||||
// KMK -->
|
||||
val seedColorState = rememberUpdatedState(newValue = successState.seedColor)
|
||||
val uiPreferences = remember { Injekt.get<UiPreferences>() }
|
||||
|
||||
|
|
@ -159,6 +160,7 @@ class MangaScreen(
|
|||
screenModel: MangaScreenModel,
|
||||
successState: MangaScreenModel.State.Success,
|
||||
) {
|
||||
// KMK <--
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
val haptic = LocalHapticFeedback.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
|
@ -254,7 +256,15 @@ class MangaScreen(
|
|||
previewsRowCount = successState.previewsRowCount,
|
||||
// SY -->
|
||||
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,
|
||||
onRecommendClicked = { openRecommends(context, navigator, screenModel.source?.getMainSource(), successState.manga) },
|
||||
onMergedSettingsClicked = screenModel::showEditMergedSettingsDialog,
|
||||
|
|
@ -524,21 +534,33 @@ class MangaScreen(
|
|||
return
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
navigator.popUntil { screen ->
|
||||
navigator.size < 2 || screen is BrowseSourceScreen ||
|
||||
screen is HomeScreen || screen is SourceFeedScreen
|
||||
}
|
||||
// KMK <--
|
||||
|
||||
when (val previousController = navigator.lastItem) {
|
||||
is HomeScreen -> {
|
||||
// KMK -->
|
||||
// navigator.pop()
|
||||
// KMK <--
|
||||
previousController.search(query)
|
||||
}
|
||||
is BrowseSourceScreen -> {
|
||||
// KMK -->
|
||||
// navigator.pop()
|
||||
// KMK <--
|
||||
previousController.search(query)
|
||||
}
|
||||
// SY -->
|
||||
is SourceFeedScreen -> {
|
||||
// KMK -->
|
||||
// navigator.pop()
|
||||
// navigator.replace(BrowseSourceScreen(previousController.sourceId, query))
|
||||
navigator.push(BrowseSourceScreen(previousController.sourceId, query))
|
||||
// KMK <--
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
|
|
@ -559,10 +581,14 @@ class MangaScreen(
|
|||
while (idx >= 0) {
|
||||
previousController = navigator.items[idx--]
|
||||
if (previousController is BrowseSourceScreen && source is HttpSource) {
|
||||
// KMK -->
|
||||
// navigator.pop()
|
||||
navigator.popUntil { navigator.size == idx + 2 }
|
||||
// KMK <--
|
||||
previousController.searchGenre(genreName)
|
||||
return
|
||||
}
|
||||
// KMK -->
|
||||
if (previousController is SourceFeedScreen && source is HttpSource) {
|
||||
navigator.popUntil { navigator.size == idx + 2 }
|
||||
navigator.push(BrowseSourceScreen(previousController.sourceId, ""))
|
||||
|
|
@ -570,6 +596,7 @@ class MangaScreen(
|
|||
previousController.searchGenre(genreName)
|
||||
return
|
||||
}
|
||||
// KMK <--
|
||||
}
|
||||
performSearch(navigator, genreName, global = false)
|
||||
}
|
||||
|
|
@ -599,7 +626,13 @@ class MangaScreen(
|
|||
// 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))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -221,7 +221,9 @@ class MangaScreenModel(
|
|||
|
||||
val loggedInTrackers by lazy { trackerManager.trackers.filter { it.isLoggedIn } }
|
||||
|
||||
// KMK -->
|
||||
val useNewSourceNavigation by uiPreferences.useNewSourceNavigation().asState(screenModelScope)
|
||||
// KMK <--
|
||||
|
||||
val manga: Manga?
|
||||
get() = successState?.manga
|
||||
|
|
@ -462,7 +464,9 @@ class MangaScreenModel(
|
|||
// Fetch info-chapters when needed
|
||||
if (screenModelScope.isActive) {
|
||||
val fetchFromSourceTasks = listOf(
|
||||
// KMK -->
|
||||
async { syncTrackers() },
|
||||
// KMK <--
|
||||
async { if (needRefreshInfo) fetchMangaFromSource() },
|
||||
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.
|
||||
*/
|
||||
|
|
@ -530,7 +535,6 @@ class MangaScreenModel(
|
|||
)
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
private suspend fun syncTrackers() {
|
||||
if (!trackPreferences.autoSyncReadChapters().get()) return
|
||||
|
||||
|
|
@ -558,7 +562,9 @@ class MangaScreenModel(
|
|||
screenModelScope.launch {
|
||||
updateSuccessState { it.copy(isRefreshingData = true) }
|
||||
val fetchFromSourceTasks = listOf(
|
||||
// KMK -->
|
||||
async { syncTrackers() },
|
||||
// KMK <--
|
||||
async { fetchMangaFromSource(manualFetch) },
|
||||
async { fetchChaptersFromSource(manualFetch) },
|
||||
)
|
||||
|
|
@ -1103,6 +1109,7 @@ class MangaScreenModel(
|
|||
} else {
|
||||
downloadManager.getQueuedDownloadOrNull(chapter.id)
|
||||
}
|
||||
|
||||
// SY -->
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val manga = mergedData?.manga?.get(chapter.mangaId) ?: manga
|
||||
|
|
@ -1769,6 +1776,7 @@ class MangaScreenModel(
|
|||
) : Dialog
|
||||
data class DeleteChapters(val chapters: List<Chapter>) : Dialog
|
||||
data class DuplicateManga(val manga: Manga, val duplicate: Manga) : Dialog
|
||||
|
||||
/* SY -->
|
||||
data class Migrate(val newManga: Manga, val oldManga: Manga) : Dialog
|
||||
SY <-- */
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|||
import eu.kanade.tachiyomi.databinding.DialogStubTextinputBinding
|
||||
import eu.kanade.tachiyomi.ui.manga.EditMangaDialogColors
|
||||
|
||||
// KMK -->
|
||||
@Suppress("UnusedReceiverParameter")
|
||||
fun MaterialAlertDialogBuilder.binding(context: Context): DialogStubTextinputBinding {
|
||||
return DialogStubTextinputBinding.inflate(LayoutInflater.from(context))
|
||||
|
|
@ -53,12 +54,14 @@ fun DialogStubTextinputBinding.setNegativeButton(text: String, onClick: () -> Un
|
|||
return this
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun DialogStubTextinputBinding.setHint(hint: String? = null): DialogStubTextinputBinding {
|
||||
textField.hint = hint
|
||||
return this
|
||||
}
|
||||
|
||||
fun DialogStubTextinputBinding.setTextEdit(prefill: String? = null): DialogStubTextinputBinding {
|
||||
// KMK <--
|
||||
textField.editText?.apply {
|
||||
setText(prefill, TextView.BufferType.EDITABLE)
|
||||
post {
|
||||
|
|
@ -66,6 +69,7 @@ fun DialogStubTextinputBinding.setTextEdit(prefill: String? = null): DialogStubT
|
|||
context.getSystemService<InputMethodManager>()?.showSoftInput(this, 0)
|
||||
}
|
||||
}
|
||||
// KMK -->
|
||||
return this
|
||||
}
|
||||
|
||||
|
|
@ -133,3 +137,4 @@ class RoundedCornerDrawable(val color: Int, private val cornerRadius: Float = 72
|
|||
paint.colorFilter = colorFilter
|
||||
}
|
||||
}
|
||||
// KMK <--
|
||||
|
|
|
|||
|
|
@ -117,5 +117,7 @@ data class DummyTracker(
|
|||
epochMillis: Long,
|
||||
) = Unit
|
||||
|
||||
// KMK -->
|
||||
override fun hasNotStartedReading(status: Long): Boolean = status == 2L
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@ import uy.kohesive.injekt.api.get
|
|||
class MetadataViewScreen(
|
||||
private val mangaId: Long,
|
||||
private val sourceId: Long,
|
||||
// KMK -->
|
||||
private val seedColor: Color? = null,
|
||||
// KMK <--
|
||||
) : Screen() {
|
||||
|
||||
@Composable
|
||||
|
|
@ -109,6 +111,7 @@ class MetadataViewScreen(
|
|||
}
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
val uiPreferences = remember { Injekt.get<UiPreferences>() }
|
||||
|
||||
if (uiPreferences.themeCoverBased().get()) {
|
||||
|
|
@ -123,5 +126,6 @@ class MetadataViewScreen(
|
|||
} else {
|
||||
content()
|
||||
}
|
||||
// KMK <--
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,11 @@ fun EHentaiDescription(
|
|||
search: (String) -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
// KMK -->
|
||||
val textColor = MaterialTheme.colorScheme.secondary.toArgb()
|
||||
val iconColor = MaterialTheme.colorScheme.primary.toArgb()
|
||||
val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb()
|
||||
// KMK <--
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
factory = { factoryContext ->
|
||||
|
|
@ -50,26 +52,38 @@ fun EHentaiDescription(
|
|||
}
|
||||
?: meta.genre
|
||||
?: context.stringResource(MR.strings.unknown)
|
||||
// KMK -->
|
||||
binding.genre.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.visible.text = context.stringResource(SYMR.strings.is_visible, meta.visible ?: context.stringResource(MR.strings.unknown))
|
||||
// KMK -->
|
||||
binding.visible.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.favorites.text = (meta.favorites ?: 0).toString()
|
||||
// KMK -->
|
||||
binding.favorites.bindDrawable(context, R.drawable.ic_book_24dp, iconColor)
|
||||
binding.favorites.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.uploader.text = meta.uploader ?: context.stringResource(MR.strings.unknown)
|
||||
// KMK -->
|
||||
binding.uploader.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.size.text = MetadataUtil.humanReadableByteCount(meta.size ?: 0, true)
|
||||
// KMK -->
|
||||
binding.size.bindDrawable(context, R.drawable.ic_outline_sd_card_24, iconColor)
|
||||
binding.size.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
val length = meta.length ?: 0
|
||||
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.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
val language = meta.language ?: context.stringResource(MR.strings.unknown)
|
||||
binding.language.text = if (meta.translated == true) {
|
||||
|
|
@ -77,18 +91,22 @@ fun EHentaiDescription(
|
|||
} else {
|
||||
language
|
||||
}
|
||||
// KMK -->
|
||||
binding.language.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
val ratingFloat = meta.averageRating?.toFloat()
|
||||
binding.ratingBar.rating = ratingFloat ?: 0F
|
||||
@SuppressLint("SetTextI18n")
|
||||
binding.rating.text = (ratingFloat ?: 0F).toString() + " - " + MetadataUIUtil.getRatingString(context, ratingFloat?.times(2))
|
||||
// KMK -->
|
||||
binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor)
|
||||
binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor)
|
||||
binding.rating.setTextColor(textColor)
|
||||
|
||||
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
|
||||
binding.moreInfo.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
listOf(
|
||||
binding.favorites,
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@ import tachiyomi.i18n.MR
|
|||
@Composable
|
||||
fun EightMusesDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
// KMK -->
|
||||
val textColor = MaterialTheme.colorScheme.secondary.toArgb()
|
||||
val iconColor = MaterialTheme.colorScheme.primary.toArgb()
|
||||
// KMK <--
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
factory = { factoryContext ->
|
||||
|
|
@ -33,10 +35,12 @@ fun EightMusesDescription(state: State.Success, openMetadataViewer: () -> Unit)
|
|||
val binding = DescriptionAdapter8mBinding.bind(it)
|
||||
|
||||
binding.title.text = meta.title ?: context.stringResource(MR.strings.unknown)
|
||||
// KMK -->
|
||||
binding.title.setTextColor(textColor)
|
||||
|
||||
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
|
||||
binding.moreInfo.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.title.setOnLongClickListener {
|
||||
context.copyToClipboard(
|
||||
|
|
@ -45,7 +49,9 @@ fun EightMusesDescription(state: State.Success, openMetadataViewer: () -> Unit)
|
|||
)
|
||||
true
|
||||
}
|
||||
// KMK -->
|
||||
binding.title.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.moreInfo.setOnClickListener {
|
||||
openMetadataViewer()
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@ import tachiyomi.i18n.sy.SYMR
|
|||
@Composable
|
||||
fun HBrowseDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
// KMK -->
|
||||
val textColor = MaterialTheme.colorScheme.secondary.toArgb()
|
||||
val iconColor = MaterialTheme.colorScheme.primary.toArgb()
|
||||
// KMK <--
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
factory = { factoryContext ->
|
||||
|
|
@ -33,11 +35,13 @@ fun HBrowseDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
|||
val binding = DescriptionAdapterHbBinding.bind(it)
|
||||
|
||||
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.setTextColor(textColor)
|
||||
|
||||
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
|
||||
binding.moreInfo.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.pages.setOnLongClickListener {
|
||||
context.copyToClipboard(
|
||||
|
|
|
|||
|
|
@ -23,9 +23,11 @@ import kotlin.math.round
|
|||
@Composable
|
||||
fun MangaDexDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
// KMK -->
|
||||
val textColor = MaterialTheme.colorScheme.secondary.toArgb()
|
||||
val iconColor = MaterialTheme.colorScheme.primary.toArgb()
|
||||
val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb()
|
||||
// KMK <--
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
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.isVisible = ratingFloat != null
|
||||
binding.ratingBar.isVisible = ratingFloat != null
|
||||
// KMK -->
|
||||
binding.ratingBar.supportProgressTintList = ColorStateList.valueOf(iconColor)
|
||||
binding.ratingBar.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor)
|
||||
binding.rating.setTextColor(textColor)
|
||||
|
||||
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
|
||||
binding.moreInfo.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.rating.setOnLongClickListener {
|
||||
context.copyToClipboard(
|
||||
|
|
|
|||
|
|
@ -64,10 +64,14 @@ object MetadataUIUtil {
|
|||
fun TextView.bindDrawable(
|
||||
context: Context,
|
||||
@DrawableRes drawable: Int,
|
||||
// KMK -->
|
||||
@ColorInt color: Int = context.getResourceColor(R.attr.colorAccent),
|
||||
// KMK <--
|
||||
) {
|
||||
ContextCompat.getDrawable(context, drawable)?.apply {
|
||||
// KMK -->
|
||||
setTint(color)
|
||||
// KMK <--
|
||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
||||
setCompoundDrawables(this, null, null, null)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,10 @@ import java.time.ZonedDateTime
|
|||
@Composable
|
||||
fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
// KMK -->
|
||||
val textColor = MaterialTheme.colorScheme.secondary.toArgb()
|
||||
val iconColor = MaterialTheme.colorScheme.primary.toArgb()
|
||||
// KMK <--
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
factory = { factoryContext ->
|
||||
|
|
@ -49,13 +51,17 @@ fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
|||
it.second
|
||||
} ?: categoriesString ?: context.stringResource(MR.strings.unknown)
|
||||
}
|
||||
// KMK -->
|
||||
binding.genre.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
meta.favoritesCount?.let {
|
||||
if (it == 0L) return@let
|
||||
binding.favorites.text = it.toString()
|
||||
// KMK -->
|
||||
binding.favorites.bindDrawable(context, R.drawable.ic_book_24dp, iconColor)
|
||||
binding.favorites.setTextColor(textColor)
|
||||
// KMK <--
|
||||
}
|
||||
|
||||
binding.whenPosted.text = MetadataUtil.EX_DATE_FORMAT
|
||||
|
|
@ -63,22 +69,28 @@ fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
|||
ZonedDateTime
|
||||
.ofInstant(Instant.ofEpochSecond(meta.uploadDate ?: 0), ZoneId.systemDefault())
|
||||
)
|
||||
// KMK -->
|
||||
binding.whenPosted.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.pages.text = context.pluralStringResource(
|
||||
SYMR.plurals.num_pages,
|
||||
meta.pageImageTypes.size,
|
||||
meta.pageImageTypes.size,
|
||||
)
|
||||
// KMK -->
|
||||
binding.pages.bindDrawable(context, R.drawable.ic_baseline_menu_book_24, iconColor)
|
||||
binding.pages.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
binding.id.text = "#" + (meta.nhId ?: 0)
|
||||
// KMK -->
|
||||
binding.id.setTextColor(textColor)
|
||||
|
||||
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
|
||||
binding.moreInfo.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
listOf(
|
||||
binding.favorites,
|
||||
|
|
|
|||
|
|
@ -25,9 +25,11 @@ import kotlin.math.round
|
|||
@Composable
|
||||
fun PururinDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
// KMK -->
|
||||
val textColor = MaterialTheme.colorScheme.secondary.toArgb()
|
||||
val iconColor = MaterialTheme.colorScheme.primary.toArgb()
|
||||
val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb()
|
||||
// KMK <--
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
factory = { factoryContext ->
|
||||
|
|
@ -44,29 +46,39 @@ fun PururinDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
|||
it.second
|
||||
} ?: genre?.name ?: context.stringResource(MR.strings.unknown)
|
||||
}
|
||||
// KMK -->
|
||||
binding.genre.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.uploader.text = meta.uploaderDisp ?: meta.uploader.orEmpty()
|
||||
// KMK -->
|
||||
binding.uploader.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
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.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
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.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
val ratingFloat = meta.averageRating?.toFloat()
|
||||
binding.ratingBar.rating = ratingFloat ?: 0F
|
||||
@SuppressLint("SetTextI18n")
|
||||
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.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor)
|
||||
binding.rating.setTextColor(textColor)
|
||||
|
||||
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
|
||||
binding.moreInfo.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
listOf(
|
||||
binding.genre,
|
||||
|
|
|
|||
|
|
@ -26,9 +26,11 @@ import kotlin.math.round
|
|||
@Composable
|
||||
fun TsuminoDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
// KMK -->
|
||||
val textColor = MaterialTheme.colorScheme.secondary.toArgb()
|
||||
val iconColor = MaterialTheme.colorScheme.primary.toArgb()
|
||||
val ratingBarSecondaryColor = MaterialTheme.colorScheme.outlineVariant.toArgb()
|
||||
// KMK <--
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
factory = { factoryContext ->
|
||||
|
|
@ -43,31 +45,43 @@ fun TsuminoDescription(state: State.Success, openMetadataViewer: () -> Unit) {
|
|||
binding.genre.setBackgroundColor(it.first)
|
||||
it.second
|
||||
} ?: meta.category ?: context.stringResource(MR.strings.unknown)
|
||||
// KMK -->
|
||||
binding.genre.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.favorites.text = (meta.favorites ?: 0).toString()
|
||||
// KMK -->
|
||||
binding.favorites.bindDrawable(context, R.drawable.ic_book_24dp, iconColor)
|
||||
binding.favorites.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.whenPosted.text = TsuminoSearchMetadata.TSUMINO_DATE_FORMAT.format(Date(meta.uploadDate ?: 0))
|
||||
// KMK -->
|
||||
binding.whenPosted.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.uploader.text = meta.uploader ?: context.stringResource(MR.strings.unknown)
|
||||
// KMK -->
|
||||
binding.uploader.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
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.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
binding.ratingBar.rating = meta.averageRating ?: 0F
|
||||
@SuppressLint("SetTextI18n")
|
||||
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.supportSecondaryProgressTintList = ColorStateList.valueOf(ratingBarSecondaryColor)
|
||||
binding.rating.setTextColor(textColor)
|
||||
|
||||
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp, iconColor)
|
||||
binding.moreInfo.setTextColor(textColor)
|
||||
// KMK <--
|
||||
|
||||
listOf(
|
||||
binding.favorites,
|
||||
|
|
|
|||
|
|
@ -39,9 +39,11 @@ fun UpcomingItem(
|
|||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.large),
|
||||
) {
|
||||
// KMK -->
|
||||
val mangaCover = upcoming.asMangaCover()
|
||||
val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) }
|
||||
val onBgColor = mangaCover.dominantCoverColors?.second
|
||||
// KMK <--
|
||||
MangaCover.Book(
|
||||
modifier = Modifier.fillMaxHeight(),
|
||||
data = mangaCover,
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class LibraryPreferences(
|
|||
fun lastUpdatedTimestamp() = preferenceStore.getLong(Preference.appStateKey("library_update_last_timestamp"), 0L)
|
||||
fun autoUpdateInterval() = preferenceStore.getInt("pref_library_update_interval_key", 0)
|
||||
|
||||
// KMK -->
|
||||
fun coverRatios() = preferenceStore.getStringSet(
|
||||
Preference.appStateKey("pref_library_cover_ratios_key"),
|
||||
emptySet(),
|
||||
|
|
@ -44,6 +45,7 @@ class LibraryPreferences(
|
|||
Preference.appStateKey("pref_library_cover_colors_key"),
|
||||
emptySet(),
|
||||
)
|
||||
// KMK <--
|
||||
|
||||
fun autoUpdateDeviceRestrictions() = preferenceStore.getStringSet(
|
||||
"library_update_restriction",
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ data class MangaCover(
|
|||
val url: String? = customThumbnailUrl ?: ogUrl
|
||||
// SY <--
|
||||
|
||||
// KMK -->
|
||||
/**
|
||||
* [vibrantCoverColor] is used to set the color theme in manga detail page.
|
||||
* It contains color for all mangas, both in library or browsing.
|
||||
|
|
@ -66,8 +67,6 @@ data class MangaCover(
|
|||
coverRatioMap[mangaId] = value
|
||||
}
|
||||
companion object {
|
||||
private val getCustomMangaInfo: GetCustomMangaInfo by injectLazy()
|
||||
|
||||
/**
|
||||
* [vibrantCoverColorMap] store color generated while browsing library.
|
||||
* 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 coverRatioMap = ConcurrentHashMap<Long, Float>()
|
||||
// KMK <--
|
||||
|
||||
// SY -->
|
||||
private val getCustomMangaInfo: GetCustomMangaInfo by injectLazy()
|
||||
// SY <--
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,9 +29,7 @@ data class Release(
|
|||
else -> ""
|
||||
}
|
||||
|
||||
// SY -->
|
||||
return assets.find { it.contains("Komikku$apkVariant-") } ?: assets[0]
|
||||
// SY <--
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import androidx.compose.ui.unit.dp
|
|||
import tachiyomi.presentation.core.util.drawVerticalScrollbar
|
||||
|
||||
/**
|
||||
* LazyColumn with scrollbar.
|
||||
* LazyColumn with scrollbar (non-controllable).
|
||||
*/
|
||||
@Composable
|
||||
fun ScrollbarLazyColumn(
|
||||
|
|
|
|||
|
|
@ -22,12 +22,16 @@ val CoverHeight = 87.dp
|
|||
fun UpdatesMangaCover(
|
||||
cover: Bitmap?,
|
||||
modifier: GlanceModifier = GlanceModifier,
|
||||
// KMK -->
|
||||
color: Color? = null,
|
||||
// KMK <--
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(width = CoverWidth, height = CoverHeight)
|
||||
// KMK -->
|
||||
.background(color ?: Color.Unspecified)
|
||||
// KMK <--
|
||||
.appWidgetInnerRadius(),
|
||||
) {
|
||||
if (cover != null) {
|
||||
|
|
|
|||
|
|
@ -88,7 +88,9 @@ fun UpdatesWidget(
|
|||
UpdatesMangaCover(
|
||||
cover = cover,
|
||||
modifier = GlanceModifier.clickable(actionStartActivity(intent)),
|
||||
// KMK -->
|
||||
color = MangaCover.coverColorMap[mangaId]?.first?.let { Color(it) },
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue