Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
96c5813
Use materilalKolor for monet compat color scheme
Secozzi Feb 10, 2026
6fa041e
Switch to MaterialExpressiveTheme
AntsyLich Dec 26, 2025
fa27fb8
Switch to M3E ExtendedFloatingActionButton
Secozzi Feb 10, 2026
40f3656
Cleanup extension screen search query predicate
Secozzi Feb 10, 2026
1d4e1c6
Remember descriptionAnnotator across composition
AntsyLich Dec 26, 2025
dd8375b
Update dependency org.jsoup:jsoup to v1.22.1 (#2826)
renovate-bot Jan 6, 2026
5a0f011
Update dependency org.junit.jupiter:junit-jupiter to v6.0.2 (#2830)
renovate-bot Jan 6, 2026
398c8e3
Optimise MAL search queries by ~11x
Secozzi Feb 10, 2026
f813e43
Translations update from Hosted Weblate (#2806)
weblate Jan 7, 2026
dd6a1b7
Add studios to MAL search results
Secozzi Feb 10, 2026
ba268eb
Fix crash when trying to install/update extensions while shizuku isn'…
NGB-Was-Taken Jan 7, 2026
3af6f1f
Enable logcat logging on stable and debug builds without enabling ve…
NGB-Was-Taken Jan 7, 2026
b7eb577
Update markdown to v0.39.1 (#2850)
renovate-bot Jan 14, 2026
c7bd79a
Update dependency com.materialkolor:material-kolor to v5.0.0-alpha05 …
renovate-bot Jan 14, 2026
6883b54
Update dependency androidx.compose:compose-bom to v2026 (#2853)
renovate-bot Jan 15, 2026
5ecf136
Update dependency com.google.firebase:firebase-bom to v34.8.0 (#2856)
renovate-bot Jan 16, 2026
c999e9f
Add Filters to Updates screen
Secozzi Feb 10, 2026
d8a403b
Update dependency io.kotest:kotest-assertions-core to v6.1.0 (#2870)
renovate-bot Jan 20, 2026
dc8a6c2
Reword download index message (#2874)
MajorTanya Jan 20, 2026
9800d32
Update GitHub Actions (#2884)
renovate-bot Jan 24, 2026
81c5204
Update Gradle to v8.14.4 (#2894)
renovate-bot Jan 24, 2026
f830248
Update dependency io.kotest:kotest-assertions-core to v6.1.1 (#2893)
renovate-bot Jan 24, 2026
47cd910
Update dependency com.diffplug.spotless:spotless-plugin-gradle to v8.…
renovate-bot Jan 24, 2026
f789b92
Update serialization.version to v1.10.0 (#2879)
renovate-bot Jan 24, 2026
805a2fb
Fix memoization in manga bottom action menus
cuong-tran Jan 24, 2026
debb0f9
Fix Add Repo input not taking up the full dialog width (#2816)
cuong-tran Jan 24, 2026
4cedcbf
Update dependency io.mockk:mockk to v1.14.9 (#2904)
renovate-bot Jan 26, 2026
6018481
Update dependency com.diffplug.spotless:spotless-plugin-gradle to v8.…
renovate-bot Jan 28, 2026
921c75f
Update dependency io.kotest:kotest-assertions-core to v6.1.2 (#2908)
renovate-bot Jan 28, 2026
8389f87
Update markdown to v0.39.2 (#2923)
renovate-bot Feb 2, 2026
394510b
Update dependency androidx.activity:activity-compose to v1.12.3 (#2917)
renovate-bot Feb 2, 2026
7f1bd21
Update paging.version to v3.4.0 (#2916)
renovate-bot Feb 2, 2026
899a021
Update dependency androidx.work:work-runtime to v2.11.1 (#2914)
renovate-bot Feb 2, 2026
878884c
Update gradle/actions action to v5.0.1 (#2912)
renovate-bot Feb 2, 2026
4c18834
Update dependency androidx.compose:compose-bom to v2026.01.01 (#2913)
renovate-bot Feb 2, 2026
96f9250
Add "src:" prefix to search by source ID
Secozzi Feb 10, 2026
3bce489
Clean up some build warnings
Secozzi Feb 10, 2026
53319fb
Add src:local search alias for Local Source
Secozzi Feb 10, 2026
656cccb
Update dependency com.materialkolor:material-kolor to v5.0.0-alpha06 …
renovate-bot Feb 9, 2026
4456e28
Update dependency io.kotest:kotest-assertions-core to v6.1.3 (#2939)
renovate-bot Feb 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,20 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Dependency Review
if: github.event_name == 'pull_request'
uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2

- name: Set up JDK
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
java-version: 17
distribution: temurin

- name: Set up Gradle
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5.0.1

- name: Check code format
run: ./gradlew spotlessCheck
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up JDK
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
java-version: 17
distribution: temurin
Expand All @@ -53,7 +53,7 @@ jobs:
# <-- AM (SYNC_DRIVE)

- name: Set up Gradle
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5.0.1

- name: Build
run: ./gradlew assembleRelease -Penable-updater
Expand Down
3 changes: 3 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,14 @@ kotlin {
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
"-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi",
"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
"-opt-in=androidx.compose.material3.ExperimentalMaterial3ExpressiveApi",
"-opt-in=androidx.compose.ui.ExperimentalComposeUiApi",
"-opt-in=coil3.annotation.ExperimentalCoilApi",
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.coroutines.FlowPreview",
"-opt-in=kotlinx.coroutines.InternalCoroutinesApi",
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
"-Xannotation-default-target=param-property",
)
}
}
Expand Down Expand Up @@ -286,6 +288,7 @@ dependencies {
implementation(libs.compose.grid)
implementation(libs.reorderable)
implementation(libs.bundles.markdown)
implementation(libs.materialKolor)

// Logging
implementation(libs.logcat)
Expand Down
27 changes: 27 additions & 0 deletions app/src/main/java/eu/kanade/core/util/FlowUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// AM -->
package eu.kanade.core.util

import kotlinx.coroutines.flow.Flow

inline fun <T1, T2, T3, T4, T5, T6, R> combine(
flow: Flow<T1>,
flow2: Flow<T2>,
flow3: Flow<T3>,
flow4: Flow<T4>,
flow5: Flow<T5>,
flow6: Flow<T6>,
crossinline transform: suspend (T1, T2, T3, T4, T5, T6) -> R,
): Flow<R> {
return kotlinx.coroutines.flow.combine(flow, flow2, flow3, flow4, flow5, flow6) { args: Array<*> ->
@Suppress("UNCHECKED_CAST")
transform(
args[0] as T1,
args[1] as T2,
args[2] as T3,
args[3] as T4,
args[4] as T5,
args[5] as T6,
)
}
}
// <-- AM
86 changes: 40 additions & 46 deletions app/src/main/java/eu/kanade/presentation/anime/AnimeScreen.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package eu.kanade.presentation.anime

import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
Expand All @@ -29,9 +26,11 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.Icon
import androidx.compose.material3.SmallExtendedFloatingActionButton
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.animateFloatingActionButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
Expand Down Expand Up @@ -92,7 +91,6 @@ import tachiyomi.i18n.aniyomi.AYMR
import tachiyomi.presentation.core.components.FastScrollIrregularLazyVerticalGrid
import tachiyomi.presentation.core.components.Scroller.EXACT_HEIGHT_KEY_PREFIX
import tachiyomi.presentation.core.components.TwoPanelBox
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
import tachiyomi.presentation.core.components.material.PullRefresh
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
Expand Down Expand Up @@ -479,27 +477,25 @@ private fun AnimeScreenSmallImpl(
val isFABVisible = remember(episodes) {
episodes.fastAny { !it.episode.seen } && !isAnySelected
}
AnimatedVisibility(
visible = isFABVisible,
enter = fadeIn(),
exit = fadeOut(),
) {
ExtendedFloatingActionButton(
text = {
val isWatching = remember(state.episodes) {
state.episodes.fastAny { it.episode.seen }
}
Text(
text = stringResource(
if (isWatching) MR.strings.action_resume else MR.strings.action_start,
),
)
},
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueWatching,
expanded = itemListState.shouldExpandFAB(),
)
}
SmallExtendedFloatingActionButton(
text = {
val isWatching = remember(state.episodes) {
state.episodes.fastAny { it.episode.seen }
}
Text(
text = stringResource(
if (isWatching) MR.strings.action_resume else MR.strings.action_start,
),
)
},
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueWatching,
expanded = itemListState.shouldExpandFAB(),
modifier = Modifier.animateFloatingActionButton(
visible = isFABVisible,
alignment = Alignment.BottomEnd,
),
)
},
) { contentPadding ->
val topPadding = contentPadding.calculateTopPadding()
Expand Down Expand Up @@ -864,27 +860,25 @@ fun AnimeScreenLargeImpl(
val isFABVisible = remember(episodes) {
episodes.fastAny { !it.episode.seen } && !isAnySelected
}
AnimatedVisibility(
visible = isFABVisible,
enter = fadeIn(),
exit = fadeOut(),
) {
ExtendedFloatingActionButton(
text = {
val isWatching = remember(state.episodes) {
state.episodes.fastAny { it.episode.seen }
}
Text(
text = stringResource(
if (isWatching) MR.strings.action_resume else MR.strings.action_start,
),
)
},
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueWatching,
expanded = itemListState.shouldExpandFAB(),
)
}
SmallExtendedFloatingActionButton(
text = {
val isWatching = remember(state.episodes) {
state.episodes.fastAny { it.episode.seen }
}
Text(
text = stringResource(
if (isWatching) MR.strings.action_resume else MR.strings.action_start,
),
)
},
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueWatching,
expanded = itemListState.shouldExpandFAB(),
modifier = Modifier.animateFloatingActionButton(
visible = isFABVisible,
alignment = Alignment.BottomEnd,
),
)
},
) { contentPadding ->
PullRefresh(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,11 @@ fun AnimeBottomActionMenu(
val confirm = remember {
mutableStateListOf(false, false, false, false, false, false, false, false, false, false, false)
}
val confirmRange = 0..<11
// <-- AY
var resetJob: Job? = remember { null }
var resetJob by remember { mutableStateOf<Job?>(null) }
val onLongClickItem: (Int) -> Unit = { toConfirmIndex ->
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
(confirmRange).forEach { i -> confirm[i] = i == toConfirmIndex }
confirm.indices.forEach { i -> confirm[i] = i == toConfirmIndex }
resetJob?.cancel()
resetJob = scope.launch {
delay(1.seconds)
Expand Down Expand Up @@ -319,10 +318,10 @@ fun LibraryBottomActionMenu(
) {
val haptic = LocalHapticFeedback.current
val confirm = remember { mutableStateListOf(false, false, false, false, false, false) }
var resetJob: Job? = remember { null }
var resetJob by remember { mutableStateOf<Job?>(null) }
val onLongClickItem: (Int) -> Unit = { toConfirmIndex ->
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
(0..5).forEach { i -> confirm[i] = i == toConfirmIndex }
confirm.indices.forEach { i -> confirm[i] = i == toConfirmIndex }
resetJob?.cancel()
resetJob = scope.launch {
delay(1.seconds)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -577,44 +577,47 @@ private fun ColumnScope.AnimeContentInfo(
}
}

private fun descriptionAnnotator(loadImages: Boolean, linkStyle: SpanStyle) = markdownAnnotator(
annotate = { content, child ->
if (!loadImages && child.type == MarkdownElementTypes.IMAGE) {
val inlineLink = child.findChildOfType(MarkdownElementTypes.INLINE_LINK)
@Composable
private fun descriptionAnnotator(loadImages: Boolean, linkStyle: SpanStyle) = remember(loadImages, linkStyle) {
markdownAnnotator(
annotate = { content, child ->
if (!loadImages && child.type == MarkdownElementTypes.IMAGE) {
val inlineLink = child.findChildOfType(MarkdownElementTypes.INLINE_LINK)

val url = inlineLink?.findChildOfType(MarkdownElementTypes.LINK_DESTINATION)
?.getUnescapedTextInNode(content)
?: inlineLink?.findChildOfType(MarkdownElementTypes.AUTOLINK)
?.findChildOfType(MarkdownTokenTypes.AUTOLINK)
val url = inlineLink?.findChildOfType(MarkdownElementTypes.LINK_DESTINATION)
?.getUnescapedTextInNode(content)
?: return@markdownAnnotator false
?: inlineLink?.findChildOfType(MarkdownElementTypes.AUTOLINK)
?.findChildOfType(MarkdownTokenTypes.AUTOLINK)
?.getUnescapedTextInNode(content)
?: return@markdownAnnotator false

val textNode = inlineLink?.findChildOfType(MarkdownElementTypes.LINK_TITLE)
?: inlineLink?.findChildOfType(MarkdownElementTypes.LINK_TEXT)
val altText = textNode?.findChildOfType(MarkdownTokenTypes.TEXT)
?.getUnescapedTextInNode(content).orEmpty()
val textNode = inlineLink?.findChildOfType(MarkdownElementTypes.LINK_TITLE)
?: inlineLink?.findChildOfType(MarkdownElementTypes.LINK_TEXT)
val altText = textNode?.findChildOfType(MarkdownTokenTypes.TEXT)
?.getUnescapedTextInNode(content).orEmpty()

withLink(LinkAnnotation.Url(url = url)) {
pushStyle(linkStyle)
appendInlineContent(MARKDOWN_INLINE_IMAGE_TAG)
append(altText)
pop()
}
withLink(LinkAnnotation.Url(url = url)) {
pushStyle(linkStyle)
appendInlineContent(MARKDOWN_INLINE_IMAGE_TAG)
append(altText)
pop()
}

return@markdownAnnotator true
}
return@markdownAnnotator true
}

if (child.type in DISALLOWED_MARKDOWN_TYPES) {
append(content.substring(child.startOffset, child.endOffset))
return@markdownAnnotator true
}
if (child.type in DISALLOWED_MARKDOWN_TYPES) {
append(content.substring(child.startOffset, child.endOffset))
return@markdownAnnotator true
}

false
},
config = markdownAnnotatorConfig(
eolAsNewLine = true,
),
)
false
},
config = markdownAnnotatorConfig(
eolAsNewLine = true,
),
)
}

@Composable
private fun AnimeSummary(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.SwapCalls
import androidx.compose.material.icons.outlined.TravelExplore
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SmallExtendedFloatingActionButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -115,7 +115,7 @@ fun SourcesScreen(
floatingActionButton = {
val buttonText = if (updateCount != 0) MR.strings.ext_update else MR.strings.ext_install
val buttonIcon = if (updateCount != 0) Icons.Filled.Upload else Icons.Filled.Download
ExtendedFloatingActionButton(
SmallExtendedFloatingActionButton(
text = { Text(text = stringResource(buttonText)) },
icon = { Icon(imageVector = buttonIcon, contentDescription = null) },
onClick = { toExtensionsScreen() },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material3.Icon
import androidx.compose.material3.SmallExtendedFloatingActionButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.shouldExpandFAB

Expand All @@ -18,7 +18,7 @@ fun CategoryFloatingActionButton(
onCreate: () -> Unit,
modifier: Modifier = Modifier,
) {
ExtendedFloatingActionButton(
SmallExtendedFloatingActionButton(
text = { Text(text = stringResource(MR.strings.action_add)) },
icon = { Icon(imageVector = Icons.Outlined.Add, contentDescription = null) },
onClick = onCreate,
Expand Down
Loading