Last commit merged: 69aa13bc56
This commit is contained in:
LuftVerbot 2023-11-26 01:44:41 +01:00
parent 375a252a69
commit 91de0ed82e
189 changed files with 1500 additions and 1349 deletions

View file

@ -12,7 +12,7 @@ jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v4
- uses: dessant/lock-threads@v5
with:
github-token: ${{ github.token }}
issue-inactive-days: '2'

View file

@ -174,6 +174,7 @@ dependencies {
implementation(compose.accompanist.permissions)
implementation(compose.accompanist.themeadapter)
implementation(compose.accompanist.systemuicontroller)
lintChecks(compose.lintchecks)
implementation(androidx.paging.runtime)
implementation(androidx.paging.compose)
@ -181,6 +182,7 @@ dependencies {
implementation(libs.bundles.sqlite)
implementation(kotlinx.reflect)
implementation(kotlinx.immutables)
implementation(platform(kotlinx.coroutines.bom))
implementation(kotlinx.bundles.coroutines)

View file

@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowForward
import androidx.compose.material.icons.outlined.ArrowForward
import androidx.compose.material.icons.outlined.Error
import androidx.compose.material3.CircularProgressIndicator
@ -54,7 +55,7 @@ fun GlobalSearchResultItem(
Text(text = subtitle)
}
IconButton(onClick = onClick) {
Icon(imageVector = Icons.Outlined.ArrowForward, contentDescription = null)
Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null)
}
}
content()

View file

@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material.icons.outlined.History
import androidx.compose.material.icons.outlined.Settings
@ -54,6 +55,7 @@ import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
import eu.kanade.tachiyomi.ui.browse.anime.extension.details.AnimeExtensionDetailsScreenModel
import eu.kanade.tachiyomi.util.system.LocaleHelper
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding
@ -79,40 +81,42 @@ fun AnimeExtensionDetailsScreen(
navigateUp = navigateUp,
actions = {
AppBarActions(
actions = buildList {
if (state.extension?.isUnofficial == false) {
add(
AppBar.Action(
title = stringResource(R.string.whats_new),
icon = Icons.Outlined.History,
onClick = onClickWhatsNew,
),
)
add(
AppBar.Action(
title = stringResource(R.string.action_faq_and_guides),
icon = Icons.Outlined.HelpOutline,
onClick = onClickReadme,
actions = persistentListOf<AppBar.AppBarAction>().builder()
.apply {
if (state.extension?.isUnofficial == false) {
add(
AppBar.Action(
title = stringResource(R.string.whats_new),
icon = Icons.Outlined.History,
onClick = onClickWhatsNew,
),
)
add(
AppBar.Action(
title = stringResource(R.string.action_faq_and_guides),
icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = onClickReadme,
),
)
}
addAll(
listOf(
AppBar.OverflowAction(
title = stringResource(R.string.action_enable_all),
onClick = onClickEnableAll,
),
AppBar.OverflowAction(
title = stringResource(R.string.action_disable_all),
onClick = onClickDisableAll,
),
AppBar.OverflowAction(
title = stringResource(R.string.pref_clear_cookies),
onClick = onClickClearCookies,
),
),
)
}
addAll(
listOf(
AppBar.OverflowAction(
title = stringResource(R.string.action_enable_all),
onClick = onClickEnableAll,
),
AppBar.OverflowAction(
title = stringResource(R.string.action_disable_all),
onClick = onClickDisableAll,
),
AppBar.OverflowAction(
title = stringResource(R.string.pref_clear_cookies),
onClick = onClickClearCookies,
),
),
)
},
.build(),
)
},
scrollBehavior = scrollBehavior,
@ -186,7 +190,6 @@ private fun AnimeExtensionDetails(
key = { it.source.id },
) { source ->
SourceSwitchPreference(
modifier = Modifier.animateItemPlacement(),
source = source,
onClickSourcePreferences = onClickSourcePreferences,
onClickSource = onClickSource,
@ -321,10 +324,10 @@ private fun DetailsHeader(
@Composable
private fun InfoText(
modifier: Modifier,
primaryText: String,
primaryTextStyle: TextStyle = MaterialTheme.typography.bodyLarge,
secondaryText: String,
modifier: Modifier = Modifier,
primaryTextStyle: TextStyle = MaterialTheme.typography.bodyLarge,
onClick: (() -> Unit)? = null,
) {
val interactionSource = remember { MutableInteractionSource() }
@ -364,10 +367,10 @@ private fun InfoDivider() {
@Composable
private fun SourceSwitchPreference(
modifier: Modifier = Modifier,
source: AnimeExtensionSourceItem,
onClickSourcePreferences: (sourceId: Long) -> Unit,
onClickSource: (sourceId: Long) -> Unit,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current

View file

@ -58,7 +58,6 @@ private fun AnimeExtensionFilterContent(
) {
items(state.languages) { language ->
SwitchPreferenceWidget(
modifier = Modifier.animateItemPlacement(),
title = LocaleHelper.getSourceDisplayName(language, context),
checked = language in state.enabledLanguages,
onCheckedChanged = { onClickLang(language) },

View file

@ -147,14 +147,13 @@ private fun AnimeExtensionContent(
}
ExtensionHeader(
textRes = header.textRes,
modifier = Modifier.animateItemPlacement(),
action = action,
)
}
is AnimeExtensionUiModel.Header.Text -> {
ExtensionHeader(
text = header.text,
modifier = Modifier.animateItemPlacement(),
)
}
}
@ -166,7 +165,7 @@ private fun AnimeExtensionContent(
key = { "extension-${it.hashCode()}" },
) { item ->
AnimeExtensionItem(
modifier = Modifier.animateItemPlacement(),
item = item,
onClickItem = {
when (it) {
@ -216,12 +215,12 @@ private fun AnimeExtensionContent(
@Composable
private fun AnimeExtensionItem(
modifier: Modifier = Modifier,
item: AnimeExtensionUiModel.Item,
onClickItem: (AnimeExtension) -> Unit,
onLongClickItem: (AnimeExtension) -> Unit,
onClickItemCancel: (AnimeExtension) -> Unit,
onClickItemAction: (AnimeExtension) -> Unit,
modifier: Modifier = Modifier,
) {
val (extension, installStep) = item
BaseBrowseItem(

View file

@ -68,7 +68,7 @@ private fun AnimeSourcesFilterContent(
contentType = "source-filter-header",
) {
AnimeSourcesFilterHeader(
modifier = Modifier.animateItemPlacement(),
language = language,
enabled = enabled,
onClickItem = onClickLanguage,
@ -81,7 +81,7 @@ private fun AnimeSourcesFilterContent(
contentType = { "source-filter-item" },
) { source ->
AnimeSourcesFilterItem(
modifier = Modifier.animateItemPlacement(),
source = source,
isEnabled = "${source.id}" !in state.disabledSources,
onClickItem = onClickSource,
@ -94,10 +94,10 @@ private fun AnimeSourcesFilterContent(
@Composable
fun AnimeSourcesFilterHeader(
modifier: Modifier,
language: String,
enabled: Boolean,
onClickItem: (String) -> Unit,
modifier: Modifier = Modifier,
) {
SwitchPreferenceWidget(
modifier = modifier,
@ -109,10 +109,10 @@ fun AnimeSourcesFilterHeader(
@Composable
private fun AnimeSourcesFilterItem(
modifier: Modifier,
source: AnimeSource,
isEnabled: Boolean,
onClickItem: (AnimeSource) -> Unit,
modifier: Modifier = Modifier,
) {
BaseAnimeSourceItem(
modifier = modifier,

View file

@ -74,12 +74,12 @@ fun AnimeSourcesScreen(
when (model) {
is AnimeSourceUiModel.Header -> {
AnimeSourceHeader(
modifier = Modifier.animateItemPlacement(),
language = model.language,
)
}
is AnimeSourceUiModel.Item -> AnimeSourceItem(
modifier = Modifier.animateItemPlacement(),
source = model.source,
onClickItem = onClickItem,
onLongClickItem = onLongClickItem,
@ -94,8 +94,8 @@ fun AnimeSourcesScreen(
@Composable
private fun AnimeSourceHeader(
modifier: Modifier = Modifier,
language: String,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
Text(
@ -111,11 +111,11 @@ private fun AnimeSourceHeader(
@Composable
private fun AnimeSourceItem(
modifier: Modifier = Modifier,
source: AnimeSource,
onClickItem: (AnimeSource, Listing) -> Unit,
onLongClickItem: (AnimeSource) -> Unit,
onClickPin: (AnimeSource) -> Unit,
modifier: Modifier = Modifier,
) {
BaseAnimeSourceItem(
modifier = modifier,

View file

@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material.icons.outlined.Public
import androidx.compose.material.icons.outlined.Refresh
@ -24,6 +25,7 @@ import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.util.formattedMessage
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.AnimeSource
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.StateFlow
import tachiyomi.domain.entries.anime.model.Anime
import tachiyomi.domain.library.model.LibraryDisplayMode
@ -76,15 +78,15 @@ fun BrowseAnimeSourceContent(
modifier = Modifier.padding(contentPadding),
message = getErrorMessage(errorState),
actions = if (source is LocalAnimeSource) {
listOf(
persistentListOf(
EmptyScreenAction(
stringResId = R.string.local_source_help_guide,
icon = Icons.Outlined.HelpOutline,
icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = onLocalAnimeSourceHelpClick,
),
)
} else {
listOf(
persistentListOf(
EmptyScreenAction(
stringResId = R.string.action_retry,
icon = Icons.Outlined.Refresh,
@ -97,7 +99,7 @@ fun BrowseAnimeSourceContent(
),
EmptyScreenAction(
stringResId = R.string.label_help,
icon = Icons.Outlined.HelpOutline,
icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = onHelpClick,
),
)
@ -145,7 +147,7 @@ fun BrowseAnimeSourceContent(
}
@Composable
fun MissingSourceScreen(
internal fun MissingSourceScreen(
source: StubAnimeSource,
navigateUp: () -> Unit,
) {

View file

@ -60,13 +60,13 @@ fun GlobalAnimeSearchScreen(
@Composable
internal fun GlobalSearchContent(
fromSourceId: Long? = null,
items: Map<AnimeCatalogueSource, AnimeSearchItemResult>,
contentPadding: PaddingValues,
getAnime: @Composable (Anime) -> State<Anime>,
onClickSource: (AnimeCatalogueSource) -> Unit,
onClickItem: (Anime) -> Unit,
onLongClickItem: (Anime) -> Unit,
fromSourceId: Long? = null,
) {
LazyColumn(
contentPadding = contentPadding,

View file

@ -70,10 +70,10 @@ private fun MigrateAnimeContent(
@Composable
private fun MigrateAnimeItem(
modifier: Modifier = Modifier,
anime: Anime,
onClickItem: (Anime) -> Unit,
onClickCover: (Anime) -> Unit,
modifier: Modifier = Modifier,
) {
BaseAnimeListItem(
modifier = modifier,

View file

@ -132,7 +132,7 @@ private fun MigrateAnimeSourceList(
key = { (source, _) -> "migrate-${source.id}" },
) { (source, count) ->
MigrateAnimeSourceItem(
modifier = Modifier.animateItemPlacement(),
source = source,
count = count,
onClickItem = { onClickItem(source) },
@ -144,11 +144,11 @@ private fun MigrateAnimeSourceList(
@Composable
private fun MigrateAnimeSourceItem(
modifier: Modifier = Modifier,
source: AnimeSource,
count: Long,
onClickItem: () -> Unit,
onLongClickItem: () -> Unit,
modifier: Modifier = Modifier,
) {
BaseAnimeSourceItem(
modifier = modifier,

View file

@ -17,8 +17,8 @@ import tachiyomi.presentation.core.util.secondaryItemAlpha
@Composable
fun BaseAnimeSourceItem(
modifier: Modifier = Modifier,
source: AnimeSource,
modifier: Modifier = Modifier,
showLanguageInContent: Boolean = true,
onClickItem: () -> Unit = {},
onLongClickItem: () -> Unit = {},

View file

@ -1,6 +1,7 @@
package eu.kanade.presentation.browse.anime.components
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ViewList
import androidx.compose.material.icons.filled.ViewList
import androidx.compose.material.icons.filled.ViewModule
import androidx.compose.material3.Text
@ -20,6 +21,7 @@ import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.AnimeSource
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.source.local.entries.anime.LocalAnimeSource
@ -53,32 +55,44 @@ fun BrowseAnimeSourceToolbar(
onClickCloseSearch = navigateUp,
actions = {
AppBarActions(
actions = listOfNotNull(
AppBar.Action(
title = stringResource(R.string.action_display_mode),
icon = if (displayMode == LibraryDisplayMode.List) {
Icons.Filled.ViewList
actions = persistentListOf<AppBar.AppBarAction>().builder()
.apply {
add(
AppBar.Action(
title = stringResource(R.string.action_display_mode),
icon = if (displayMode == LibraryDisplayMode.List) {
Icons.AutoMirrored.Filled.ViewList
} else {
Icons.Filled.ViewModule
},
onClick = { selectingDisplayMode = true },
),
)
if (isLocalSource) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.label_help),
onClick = onHelpClick,
),
)
} else {
Icons.Filled.ViewModule
},
onClick = { selectingDisplayMode = true },
),
if (isLocalSource) {
AppBar.OverflowAction(
title = stringResource(R.string.label_help),
onClick = onHelpClick,
)
} else {
AppBar.OverflowAction(
title = stringResource(R.string.action_open_in_web_view),
onClick = onWebViewClick,
)
},
AppBar.OverflowAction(
title = stringResource(R.string.action_settings),
onClick = onSettingsClick,
).takeIf { isConfigurableSource },
),
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_open_in_web_view),
onClick = onWebViewClick,
),
)
}
if (isConfigurableSource) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_settings),
onClick = onSettingsClick,
),
)
}
}
.build(),
)
DropdownMenu(

View file

@ -58,7 +58,7 @@ fun GlobalAnimeSearchToolbar(
)
if (progress in 1..<total) {
LinearProgressIndicator(
progress = progress / total.toFloat(),
progress = { progress / total.toFloat() },
modifier = Modifier
.align(Alignment.BottomStart)
.fillMaxWidth(),

View file

@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material.icons.outlined.Public
import androidx.compose.material.icons.outlined.Refresh
@ -24,6 +25,7 @@ import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.util.formattedMessage
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.MangaSource
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.StateFlow
import tachiyomi.domain.entries.manga.model.Manga
import tachiyomi.domain.library.model.LibraryDisplayMode
@ -76,15 +78,15 @@ fun BrowseSourceContent(
modifier = Modifier.padding(contentPadding),
message = getErrorMessage(errorState),
actions = if (source is LocalMangaSource) {
listOf(
persistentListOf(
EmptyScreenAction(
stringResId = R.string.local_source_help_guide,
icon = Icons.Outlined.HelpOutline,
icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = onLocalSourceHelpClick,
),
)
} else {
listOf(
persistentListOf(
EmptyScreenAction(
stringResId = R.string.action_retry,
icon = Icons.Outlined.Refresh,
@ -97,7 +99,7 @@ fun BrowseSourceContent(
),
EmptyScreenAction(
stringResId = R.string.label_help,
icon = Icons.Outlined.HelpOutline,
icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = onHelpClick,
),
)
@ -145,7 +147,7 @@ fun BrowseSourceContent(
}
@Composable
fun MissingSourceScreen(
internal fun MissingSourceScreen(
source: StubMangaSource,
navigateUp: () -> Unit,
) {

View file

@ -60,13 +60,13 @@ fun GlobalMangaSearchScreen(
@Composable
internal fun GlobalSearchContent(
fromSourceId: Long? = null,
items: Map<CatalogueSource, MangaSearchItemResult>,
contentPadding: PaddingValues,
getManga: @Composable (Manga) -> State<Manga>,
onClickSource: (CatalogueSource) -> Unit,
onClickItem: (Manga) -> Unit,
onLongClickItem: (Manga) -> Unit,
fromSourceId: Long? = null,
) {
LazyColumn(
contentPadding = contentPadding,

View file

@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material.icons.outlined.History
import androidx.compose.material.icons.outlined.Settings
@ -55,6 +56,7 @@ import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.ui.browse.manga.extension.details.MangaExtensionDetailsScreenModel
import eu.kanade.tachiyomi.util.system.LocaleHelper
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding
@ -80,40 +82,42 @@ fun ExtensionDetailsScreen(
navigateUp = navigateUp,
actions = {
AppBarActions(
actions = buildList {
if (state.extension?.isUnofficial == false) {
add(
AppBar.Action(
title = stringResource(R.string.whats_new),
icon = Icons.Outlined.History,
onClick = onClickWhatsNew,
),
)
add(
AppBar.Action(
title = stringResource(R.string.action_faq_and_guides),
icon = Icons.Outlined.HelpOutline,
onClick = onClickReadme,
actions = persistentListOf<AppBar.AppBarAction>().builder()
.apply {
if (state.extension?.isUnofficial == false) {
add(
AppBar.Action(
title = stringResource(R.string.whats_new),
icon = Icons.Outlined.History,
onClick = onClickWhatsNew,
),
)
add(
AppBar.Action(
title = stringResource(R.string.action_faq_and_guides),
icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = onClickReadme,
),
)
}
addAll(
listOf(
AppBar.OverflowAction(
title = stringResource(R.string.action_enable_all),
onClick = onClickEnableAll,
),
AppBar.OverflowAction(
title = stringResource(R.string.action_disable_all),
onClick = onClickDisableAll,
),
AppBar.OverflowAction(
title = stringResource(R.string.pref_clear_cookies),
onClick = onClickClearCookies,
),
),
)
}
addAll(
listOf(
AppBar.OverflowAction(
title = stringResource(R.string.action_enable_all),
onClick = onClickEnableAll,
),
AppBar.OverflowAction(
title = stringResource(R.string.action_disable_all),
onClick = onClickDisableAll,
),
AppBar.OverflowAction(
title = stringResource(R.string.pref_clear_cookies),
onClick = onClickClearCookies,
),
),
)
},
.build(),
)
},
scrollBehavior = scrollBehavior,
@ -187,7 +191,7 @@ private fun ExtensionDetails(
key = { it.source.id },
) { source ->
SourceSwitchPreference(
modifier = Modifier.animateItemPlacement(),
source = source,
onClickSourcePreferences = onClickSourcePreferences,
onClickSource = onClickSource,
@ -320,10 +324,10 @@ private fun DetailsHeader(
@Composable
private fun InfoText(
modifier: Modifier,
primaryText: String,
primaryTextStyle: TextStyle = MaterialTheme.typography.bodyLarge,
secondaryText: String,
modifier: Modifier = Modifier,
primaryTextStyle: TextStyle = MaterialTheme.typography.bodyLarge,
onClick: (() -> Unit)? = null,
) {
val interactionSource = remember { MutableInteractionSource() }
@ -363,10 +367,10 @@ private fun InfoDivider() {
@Composable
private fun SourceSwitchPreference(
modifier: Modifier = Modifier,
source: MangaExtensionSourceItem,
onClickSourcePreferences: (sourceId: Long) -> Unit,
onClickSource: (sourceId: Long) -> Unit,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current

View file

@ -58,7 +58,7 @@ private fun ExtensionFilterContent(
) {
items(state.languages) { language ->
SwitchPreferenceWidget(
modifier = Modifier.animateItemPlacement(),
title = LocaleHelper.getSourceDisplayName(language, context),
checked = language in state.enabledLanguages,
onCheckedChanged = { onClickLang(language) },

View file

@ -148,14 +148,14 @@ private fun ExtensionContent(
}
ExtensionHeader(
textRes = header.textRes,
modifier = Modifier.animateItemPlacement(),
action = action,
)
}
is MangaExtensionUiModel.Header.Text -> {
ExtensionHeader(
text = header.text,
modifier = Modifier.animateItemPlacement(),
)
}
}
@ -167,7 +167,7 @@ private fun ExtensionContent(
key = { "extension-${it.hashCode()}" },
) { item ->
ExtensionItem(
modifier = Modifier.animateItemPlacement(),
item = item,
onClickItem = {
when (it) {
@ -217,12 +217,12 @@ private fun ExtensionContent(
@Composable
private fun ExtensionItem(
modifier: Modifier = Modifier,
item: MangaExtensionUiModel.Item,
onClickItem: (MangaExtension) -> Unit,
onLongClickItem: (MangaExtension) -> Unit,
onClickItemCancel: (MangaExtension) -> Unit,
onClickItemAction: (MangaExtension) -> Unit,
modifier: Modifier = Modifier,
) {
val (extension, installStep) = item
BaseBrowseItem(

View file

@ -68,7 +68,7 @@ private fun SourcesFilterContent(
contentType = "source-filter-header",
) {
SourcesFilterHeader(
modifier = Modifier.animateItemPlacement(),
language = language,
enabled = enabled,
onClickItem = onClickLanguage,
@ -81,7 +81,7 @@ private fun SourcesFilterContent(
contentType = { "source-filter-item" },
) { source ->
SourcesFilterItem(
modifier = Modifier.animateItemPlacement(),
source = source,
enabled = "${source.id}" !in state.disabledSources,
onClickItem = onClickSource,
@ -94,10 +94,11 @@ private fun SourcesFilterContent(
@Composable
private fun SourcesFilterHeader(
modifier: Modifier,
language: String,
enabled: Boolean,
onClickItem: (String) -> Unit,
modifier: Modifier = Modifier,
) {
SwitchPreferenceWidget(
modifier = modifier,
@ -109,10 +110,10 @@ private fun SourcesFilterHeader(
@Composable
private fun SourcesFilterItem(
modifier: Modifier,
source: Source,
enabled: Boolean,
onClickItem: (Source) -> Unit,
modifier: Modifier = Modifier,
) {
BaseMangaSourceItem(
modifier = modifier,

View file

@ -74,12 +74,12 @@ fun MangaSourcesScreen(
when (model) {
is MangaSourceUiModel.Header -> {
SourceHeader(
modifier = Modifier.animateItemPlacement(),
language = model.language,
)
}
is MangaSourceUiModel.Item -> SourceItem(
modifier = Modifier.animateItemPlacement(),
source = model.source,
onClickItem = onClickItem,
onLongClickItem = onLongClickItem,
@ -94,8 +94,8 @@ fun MangaSourcesScreen(
@Composable
private fun SourceHeader(
modifier: Modifier = Modifier,
language: String,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
Text(
@ -111,11 +111,11 @@ private fun SourceHeader(
@Composable
private fun SourceItem(
modifier: Modifier = Modifier,
source: Source,
onClickItem: (Source, Listing) -> Unit,
onLongClickItem: (Source) -> Unit,
onClickPin: (Source) -> Unit,
modifier: Modifier = Modifier,
) {
BaseMangaSourceItem(
modifier = modifier,

View file

@ -70,10 +70,10 @@ private fun MigrateMangaContent(
@Composable
private fun MigrateMangaItem(
modifier: Modifier = Modifier,
manga: Manga,
onClickItem: (Manga) -> Unit,
onClickCover: (Manga) -> Unit,
modifier: Modifier = Modifier,
) {
BaseMangaListItem(
modifier = modifier,

View file

@ -132,7 +132,7 @@ private fun MigrateSourceList(
key = { (source, _) -> "migrate-${source.id}" },
) { (source, count) ->
MigrateSourceItem(
modifier = Modifier.animateItemPlacement(),
source = source,
count = count,
onClickItem = { onClickItem(source) },
@ -144,11 +144,11 @@ private fun MigrateSourceList(
@Composable
private fun MigrateSourceItem(
modifier: Modifier = Modifier,
source: Source,
count: Long,
onClickItem: () -> Unit,
onLongClickItem: () -> Unit,
modifier: Modifier = Modifier,
) {
BaseMangaSourceItem(
modifier = modifier,

View file

@ -17,8 +17,8 @@ import tachiyomi.presentation.core.util.secondaryItemAlpha
@Composable
fun BaseMangaSourceItem(
modifier: Modifier = Modifier,
source: Source,
modifier: Modifier = Modifier,
showLanguageInContent: Boolean = true,
onClickItem: () -> Unit = {},
onLongClickItem: () -> Unit = {},

View file

@ -1,6 +1,7 @@
package eu.kanade.presentation.browse.manga.components
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ViewList
import androidx.compose.material.icons.filled.ViewList
import androidx.compose.material.icons.filled.ViewModule
import androidx.compose.material3.Text
@ -20,6 +21,7 @@ import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.MangaSource
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.source.local.entries.manga.LocalMangaSource
@ -53,32 +55,44 @@ fun BrowseMangaSourceToolbar(
onClickCloseSearch = navigateUp,
actions = {
AppBarActions(
actions = listOfNotNull(
AppBar.Action(
title = stringResource(R.string.action_display_mode),
icon = if (displayMode == LibraryDisplayMode.List) {
Icons.Filled.ViewList
actions = persistentListOf<AppBar.AppBarAction>().builder()
.apply {
add(
AppBar.Action(
title = stringResource(R.string.action_display_mode),
icon = if (displayMode == LibraryDisplayMode.List) {
Icons.AutoMirrored.Filled.ViewList
} else {
Icons.Filled.ViewModule
},
onClick = { selectingDisplayMode = true },
),
)
if (isLocalSource) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.label_help),
onClick = onHelpClick,
),
)
} else {
Icons.Filled.ViewModule
},
onClick = { selectingDisplayMode = true },
),
if (isLocalSource) {
AppBar.OverflowAction(
title = stringResource(R.string.label_help),
onClick = onHelpClick,
)
} else {
AppBar.OverflowAction(
title = stringResource(R.string.action_open_in_web_view),
onClick = onWebViewClick,
)
},
AppBar.OverflowAction(
title = stringResource(R.string.action_settings),
onClick = onSettingsClick,
).takeIf { isConfigurableSource },
),
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_open_in_web_view),
onClick = onWebViewClick,
),
)
}
if (isConfigurableSource) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_settings),
onClick = onSettingsClick,
),
)
}
}
.build(),
)
DropdownMenu(

View file

@ -7,7 +7,6 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import tachiyomi.domain.category.model.Category
import tachiyomi.presentation.core.components.material.padding
@ -32,7 +31,7 @@ fun CategoryContent(
key = { _, category -> "category-${category.id}" },
) { index, category ->
CategoryListItem(
modifier = Modifier.animateItemPlacement(),
category = category,
canMoveUp = index != 0,
canMoveDown = index != categories.lastIndex,

View file

@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Label
import androidx.compose.material.icons.outlined.ArrowDropDown
import androidx.compose.material.icons.outlined.ArrowDropUp
import androidx.compose.material.icons.outlined.Delete
@ -28,7 +29,6 @@ import tachiyomi.presentation.core.components.material.padding
@Composable
fun CategoryListItem(
modifier: Modifier = Modifier,
category: Category,
canMoveUp: Boolean,
canMoveDown: Boolean,
@ -37,6 +37,7 @@ fun CategoryListItem(
onRename: () -> Unit,
onHide: () -> Unit,
onDelete: () -> Unit,
modifier: Modifier = Modifier,
) {
ElevatedCard(
modifier = modifier,
@ -52,7 +53,7 @@ fun CategoryListItem(
),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(imageVector = Icons.Outlined.Label, contentDescription = "")
Icon(imageVector = Icons.AutoMirrored.Outlined.Label, contentDescription = "")
Text(
text = category.name,
modifier = Modifier

View file

@ -73,11 +73,11 @@ fun NavigatorAdaptiveSheet(
*/
@Composable
fun AdaptiveSheet(
onDismissRequest: () -> Unit,
modifier: Modifier = Modifier,
hideSystemBars: Boolean = false,
tonalElevation: Dp = 1.dp,
enableSwipeDismiss: Boolean = true,
onDismissRequest: () -> Unit,
content: @Composable () -> Unit,
) {
val isTabletUi = isTabletUi()

View file

@ -13,7 +13,7 @@ import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.TextFieldDefaults
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material.icons.outlined.Search
@ -22,11 +22,14 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PlainTooltipBox
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.material3.rememberTooltipState
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
@ -52,6 +55,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.ImmutableList
import tachiyomi.presentation.core.components.Pill
import tachiyomi.presentation.core.util.clearFocusOnSoftKeyboardHide
import tachiyomi.presentation.core.util.runOnEnterKeyPressed
@ -205,18 +209,23 @@ fun AppBarTitle(
@Composable
fun AppBarActions(
actions: List<AppBar.AppBarAction>,
actions: ImmutableList<AppBar.AppBarAction>,
) {
var showMenu by remember { mutableStateOf(false) }
actions.filterIsInstance<AppBar.Action>().map {
PlainTooltipBox(
tooltip = { Text(it.title) },
TooltipBox(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
tooltip = {
PlainTooltip {
Text(it.title)
}
},
state = rememberTooltipState(),
) {
IconButton(
onClick = it.onClick,
enabled = it.enabled,
modifier = Modifier.tooltipTrigger(),
) {
Icon(
imageVector = it.icon,
@ -229,12 +238,17 @@ fun AppBarActions(
val overflowActions = actions.filterIsInstance<AppBar.OverflowAction>()
if (overflowActions.isNotEmpty()) {
PlainTooltipBox(
tooltip = { Text(stringResource(R.string.abc_action_menu_overflow_description)) },
TooltipBox(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
tooltip = {
PlainTooltip {
Text(stringResource(R.string.abc_action_menu_overflow_description))
}
},
state = rememberTooltipState(),
) {
IconButton(
onClick = { showMenu = !showMenu },
modifier = Modifier.tooltipTrigger(),
) {
Icon(
Icons.Outlined.MoreVert,
@ -356,12 +370,17 @@ fun SearchToolbar(
if (!searchEnabled) {
// Don't show search action
} else if (searchQuery == null) {
PlainTooltipBox(
tooltip = { Text(stringResource(R.string.action_search)) },
TooltipBox(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
tooltip = {
PlainTooltip {
Text(stringResource(R.string.action_search))
}
},
state = rememberTooltipState(),
) {
IconButton(
onClick = onClick,
modifier = Modifier.tooltipTrigger(),
) {
Icon(
Icons.Outlined.Search,
@ -370,15 +389,20 @@ fun SearchToolbar(
}
}
} else if (searchQuery.isNotEmpty()) {
PlainTooltipBox(
tooltip = { Text(stringResource(R.string.action_reset)) },
TooltipBox(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
tooltip = {
PlainTooltip {
Text(stringResource(R.string.action_reset))
}
},
state = rememberTooltipState(),
) {
IconButton(
onClick = {
onClick()
focusRequester.requestFocus()
},
modifier = Modifier.tooltipTrigger(),
) {
Icon(
Icons.Outlined.Close,
@ -400,7 +424,7 @@ fun SearchToolbar(
@Composable
fun UpIcon(navigationIcon: ImageVector? = null) {
val icon = navigationIcon
?: Icons.Outlined.ArrowBack
?: Icons.AutoMirrored.Outlined.ArrowBack
Icon(
imageVector = icon,
contentDescription = stringResource(R.string.abc_action_bar_up_description),

View file

@ -3,7 +3,7 @@ package eu.kanade.presentation.components
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowLeft
import androidx.compose.material.icons.automirrored.outlined.ArrowRight
import androidx.compose.material.icons.outlined.ArrowRight
import androidx.compose.material.icons.outlined.RadioButtonChecked
import androidx.compose.material.icons.outlined.RadioButtonUnchecked
@ -84,7 +84,7 @@ fun NestedMenuItem(
onClick = { nestedExpanded = true },
trailingIcon = {
Icon(
imageVector = if (isLtr) Icons.Outlined.ArrowRight else Icons.Outlined.ArrowLeft,
imageVector = Icons.AutoMirrored.Outlined.ArrowRight,
contentDescription = null,
)
},

View file

@ -1,6 +1,7 @@
package eu.kanade.presentation.components
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material.icons.outlined.Refresh
import androidx.compose.material3.Surface
@ -8,6 +9,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.PreviewLightDark
import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.EmptyScreenAction
@ -30,7 +32,7 @@ private fun WithActionPreview() {
Surface {
EmptyScreen(
textResource = R.string.empty_screen,
actions = listOf(
actions = persistentListOf(
EmptyScreenAction(
stringResId = R.string.action_retry,
icon = Icons.Outlined.Refresh,
@ -38,7 +40,7 @@ private fun WithActionPreview() {
),
EmptyScreenAction(
stringResId = R.string.getting_started_guide,
icon = Icons.Outlined.HelpOutline,
icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = {},
),
),

View file

@ -11,10 +11,10 @@ import java.util.Date
@Composable
fun RelativeDateHeader(
modifier: Modifier = Modifier,
date: Date,
relativeTime: Boolean,
dateFormat: DateFormat,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
ListGroupHeader(

View file

@ -14,8 +14,8 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PrimaryTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRow
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@ -29,9 +29,9 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEachIndexed
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.launch
import tachiyomi.presentation.core.components.HorizontalPager
import tachiyomi.presentation.core.components.material.TabIndicator
import tachiyomi.presentation.core.components.material.TabText
object TabbedDialogPaddings {
@ -41,9 +41,9 @@ object TabbedDialogPaddings {
@Composable
fun TabbedDialog(
modifier: Modifier = Modifier,
onDismissRequest: () -> Unit,
tabTitles: List<String>,
tabTitles: ImmutableList<String>,
modifier: Modifier = Modifier,
tabOverflowMenuContent: (@Composable ColumnScope.(() -> Unit) -> Unit)? = null,
onOverflowMenuClicked: (() -> Unit)? = null,
overflowIcon: ImageVector? = null,
@ -60,15 +60,9 @@ fun TabbedDialog(
Column {
Row {
TabRow(
PrimaryTabRow(
modifier = Modifier.weight(1f),
selectedTabIndex = pagerState.currentPage,
indicator = {
TabIndicator(
it[pagerState.currentPage],
pagerState.currentPageOffsetFraction,
)
},
divider = {},
) {
tabTitles.fastForEachIndexed { index, tab ->

View file

@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PrimaryTabRow
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
@ -25,16 +26,17 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.launch
import tachiyomi.presentation.core.components.HorizontalPager
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.TabIndicator
import tachiyomi.presentation.core.components.material.TabText
@Composable
fun TabbedScreen(
@StringRes titleRes: Int?,
tabs: List<TabContent>,
tabs: ImmutableList<TabContent>,
startIndex: Int? = null,
mangaSearchQuery: String? = null,
onChangeMangaSearchQuery: (String?) -> Unit = {},
@ -89,10 +91,8 @@ fun TabbedScreen(
end = contentPadding.calculateEndPadding(LocalLayoutDirection.current),
),
) {
FlexibleTabRow(
scrollable = scrollable,
PrimaryTabRow(
selectedTabIndex = state.currentPage,
indicator = { TabIndicator(it[state.currentPage], state.currentPageOffsetFraction) },
) {
tabs.forEachIndexed { index, tab ->
Tab(
@ -127,7 +127,7 @@ data class TabContent(
@StringRes val titleRes: Int,
val badgeNumber: Int? = null,
val searchEnabled: Boolean = false,
val actions: List<AppBar.Action> = emptyList(),
val actions: ImmutableList<AppBar.Action> = persistentListOf(),
val content: @Composable (contentPadding: PaddingValues, snackbarHostState: SnackbarHostState) -> Unit,
val numberTitle: Int = 0,
val cancelAction: () -> Unit = {},

View file

@ -23,6 +23,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.shape.ZeroCornerSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Label
import androidx.compose.material.icons.outlined.BookmarkAdd
import androidx.compose.material.icons.outlined.BookmarkRemove
import androidx.compose.material.icons.outlined.Delete
@ -304,7 +305,7 @@ fun LibraryBottomActionMenu(
) {
Button(
title = stringResource(R.string.action_move_category),
icon = Icons.Outlined.Label,
icon = Icons.AutoMirrored.Outlined.Label,
toConfirm = confirm[0],
onLongClick = { onLongClickItem(0) },
onClick = onChangeCategoryClicked,

View file

@ -29,6 +29,7 @@ import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.EntryDownloadDropdownMenu
import eu.kanade.presentation.components.UpIcon
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.presentation.core.theme.active
@Composable
@ -75,7 +76,7 @@ fun EntryToolbar(
actions = {
if (isActionMode) {
AppBarActions(
listOf(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_select_all),
icon = Icons.Outlined.SelectAll,
@ -102,71 +103,65 @@ fun EntryToolbar(
val filterTint = if (hasFilters) MaterialTheme.colorScheme.active else LocalContentColor.current
AppBarActions(
actions = buildList {
if (onClickDownload != null) {
actions = persistentListOf<AppBar.AppBarAction>().builder()
.apply {
if (onClickDownload != null) {
add(
AppBar.Action(
title = stringResource(R.string.manga_download),
icon = Icons.Outlined.Download,
onClick = { downloadExpanded = !downloadExpanded },
),
)
}
add(
AppBar.Action(
title = stringResource(R.string.manga_download),
icon = Icons.Outlined.Download,
onClick = { downloadExpanded = !downloadExpanded },
title = stringResource(R.string.action_filter),
icon = Icons.Outlined.FilterList,
iconTint = filterTint,
onClick = onClickFilter,
),
)
}
add(
AppBar.Action(
title = stringResource(R.string.action_filter),
icon = Icons.Outlined.FilterList,
iconTint = filterTint,
onClick = onClickFilter,
),
)
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_webview_refresh),
onClick = onClickRefresh,
),
)
if (onClickEditCategory != null) {
if (changeAnimeSkipIntro != null) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_change_intro_length),
onClick = changeAnimeSkipIntro,
),
)
}
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_edit_categories),
onClick = onClickEditCategory,
title = stringResource(R.string.action_webview_refresh),
onClick = onClickRefresh,
),
)
if (onClickEditCategory != null) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_edit_categories),
onClick = onClickEditCategory,
),
)
}
if (onClickMigrate != null) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_migrate),
onClick = onClickMigrate,
),
)
}
if (onClickShare != null) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_share),
onClick = onClickShare,
),
)
}
}
if (onClickMigrate != null) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_migrate),
onClick = onClickMigrate,
),
)
}
if (changeAnimeSkipIntro != null) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_change_intro_length),
onClick = changeAnimeSkipIntro,
),
)
}
if (onClickSettings != null) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.settings),
onClick = onClickSettings,
),
)
}
if (onClickShare != null) {
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_share),
onClick = onClickShare,
),
)
}
},
.build(),
)
}
},

View file

@ -16,6 +16,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.toImmutableList
import tachiyomi.presentation.core.components.WheelTextPicker
@Composable
@ -68,16 +69,18 @@ fun SetIntervalDialog(
contentAlignment = Alignment.Center,
) {
val size = DpSize(width = maxWidth / 2, height = 128.dp)
val items = (0..28).map {
if (it == 0) {
stringResource(R.string.label_default)
} else {
it.toString()
val items = (0..28)
.map {
if (it == 0) {
stringResource(R.string.label_default)
} else {
it.toString()
}
}
}
.toImmutableList()
WheelTextPicker(
size = size,
items = items,
size = size,
startIndex = selectedInterval,
onSelectionChanged = { selectedInterval = it },
)

View file

@ -88,7 +88,6 @@ import tachiyomi.presentation.core.components.VerticalFastScroller
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.components.material.padding
import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrollingUp
import java.text.DateFormat
@ -350,12 +349,12 @@ private fun AnimeScreenSmallImpl(
onClickEditCategory = onEditCategoryClicked,
onClickRefresh = onRefresh,
onClickMigrate = onMigrateClicked,
onClickSettings = onSettingsClicked,
changeAnimeSkipIntro = changeAnimeSkipIntro,
actionModeCounter = selectedEpisodeCount,
onSelectAll = { onAllEpisodeSelected(true) },
onInvertSelection = { onInvertSelection() },
isManga = false,
onClickSettings = onSettingsClicked,
)
},
bottomBar = {
@ -647,12 +646,12 @@ fun AnimeScreenLargeImpl(
onClickEditCategory = onEditCategoryClicked,
onClickRefresh = onRefresh,
onClickMigrate = onMigrateClicked,
onClickSettings = onSettingsClicked,
changeAnimeSkipIntro = changeAnimeSkipIntro,
actionModeCounter = selectedEpisodeCount,
onSelectAll = { onAllEpisodeSelected(true) },
onInvertSelection = { onInvertSelection() },
isManga = false,
onClickSettings = onSettingsClicked,
)
},
bottomBar = {

View file

@ -22,6 +22,7 @@ import eu.kanade.domain.entries.anime.model.forceDownloaded
import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.core.preference.TriState
import tachiyomi.domain.entries.anime.model.Anime
import tachiyomi.presentation.core.components.LabeledCheckbox
@ -50,7 +51,7 @@ fun EpisodeSettingsDialog(
TabbedDialog(
onDismissRequest = onDismissRequest,
tabTitles = listOf(
tabTitles = persistentListOf(
stringResource(R.string.action_filter),
stringResource(R.string.action_sort),
stringResource(R.string.action_display),

View file

@ -49,6 +49,7 @@ import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.entries.EditCoverAction
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderPageImageView
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.entries.anime.model.Anime
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.util.clickableNoIndication
@ -91,22 +92,18 @@ fun AnimeCoverDialog(
Spacer(modifier = Modifier.weight(1f))
ActionsPill {
AppBarActions(
actions = buildList {
add(
AppBar.Action(
title = stringResource(R.string.action_share),
icon = Icons.Outlined.Share,
onClick = onShareClick,
),
)
add(
AppBar.Action(
title = stringResource(R.string.action_save),
icon = Icons.Outlined.Save,
onClick = onSaveClick,
),
)
},
actions = persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_share),
icon = Icons.Outlined.Share,
onClick = onShareClick,
),
AppBar.Action(
title = stringResource(R.string.action_save),
icon = Icons.Outlined.Save,
onClick = onSaveClick,
),
),
)
if (onEditClick != null) {
Box {

View file

@ -145,7 +145,7 @@ private fun DownloadingIndicator(
MaterialTheme.colorScheme.background
}
CircularProgressIndicator(
progress = animatedProgress,
progress = { animatedProgress },
modifier = IndicatorModifier,
color = strokeColor,
strokeWidth = IndicatorSize / 2,

View file

@ -31,6 +31,7 @@ import eu.kanade.domain.entries.manga.model.forceDownloaded
import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.core.preference.TriState
import tachiyomi.domain.entries.manga.model.Manga
import tachiyomi.presentation.core.components.LabeledCheckbox
@ -63,7 +64,7 @@ fun ChapterSettingsDialog(
TabbedDialog(
onDismissRequest = onDismissRequest,
tabTitles = listOf(
tabTitles = persistentListOf(
stringResource(R.string.action_filter),
stringResource(R.string.action_sort),
stringResource(R.string.action_display),

View file

@ -81,7 +81,6 @@ import tachiyomi.presentation.core.components.VerticalFastScroller
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.components.material.padding
import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrollingUp
import java.text.DateFormat
@ -330,12 +329,12 @@ private fun MangaScreenSmallImpl(
onClickEditCategory = onEditCategoryClicked,
onClickRefresh = onRefresh,
onClickMigrate = onMigrateClicked,
onClickSettings = onSettingsClicked,
changeAnimeSkipIntro = null,
actionModeCounter = selectedChapterCount,
onSelectAll = { onAllChapterSelected(true) },
onInvertSelection = { onInvertSelection() },
isManga = true,
onClickSettings = onSettingsClicked,
)
},
bottomBar = {
@ -588,12 +587,12 @@ fun MangaScreenLargeImpl(
onClickEditCategory = onEditCategoryClicked,
onClickRefresh = onRefresh,
onClickMigrate = onMigrateClicked,
onClickSettings = onSettingsClicked,
changeAnimeSkipIntro = null,
actionModeCounter = selectedChapterCount,
onSelectAll = { onAllChapterSelected(true) },
onInvertSelection = { onInvertSelection() },
isManga = true,
onClickSettings = onSettingsClicked,
)
},
bottomBar = {

View file

@ -144,7 +144,7 @@ private fun DownloadingIndicator(
MaterialTheme.colorScheme.background
}
CircularProgressIndicator(
progress = animatedProgress,
progress = { animatedProgress },
modifier = IndicatorModifier,
color = strokeColor,
strokeWidth = IndicatorSize / 2,

View file

@ -49,6 +49,7 @@ import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.entries.EditCoverAction
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderPageImageView
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.entries.manga.model.Manga
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.util.clickableNoIndication
@ -91,22 +92,18 @@ fun MangaCoverDialog(
Spacer(modifier = Modifier.weight(1f))
ActionsPill {
AppBarActions(
actions = buildList {
add(
AppBar.Action(
title = stringResource(R.string.action_share),
icon = Icons.Outlined.Share,
onClick = onShareClick,
),
)
add(
AppBar.Action(
title = stringResource(R.string.action_save),
icon = Icons.Outlined.Save,
onClick = onSaveClick,
),
)
},
actions = persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_share),
icon = Icons.Outlined.Share,
onClick = onShareClick,
),
AppBar.Action(
title = stringResource(R.string.action_save),
icon = Icons.Outlined.Save,
onClick = onSaveClick,
),
),
)
if (onEditClick != null) {
Box {

View file

@ -4,7 +4,6 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import eu.kanade.domain.ui.UiPreferences
import eu.kanade.presentation.components.RelativeDateHeader
import tachiyomi.domain.history.anime.model.AnimeHistoryWithRelations
@ -38,7 +37,7 @@ fun AnimeHistoryContent(
when (item) {
is AnimeHistoryUiModel.Header -> {
RelativeDateHeader(
modifier = Modifier.animateItemPlacement(),
date = item.date,
relativeTime = relativeTime,
dateFormat = dateFormat,
@ -47,7 +46,7 @@ fun AnimeHistoryContent(
is AnimeHistoryUiModel.Item -> {
val value = item.item
AnimeHistoryItem(
modifier = Modifier.animateItemPlacement(),
history = value,
onClickCover = { onClickCover(value) },
onClickResume = { onClickResume(value) },

View file

@ -35,11 +35,11 @@ private val HistoryItemHeight = 96.dp
@Composable
fun AnimeHistoryItem(
modifier: Modifier = Modifier,
history: AnimeHistoryWithRelations,
onClickCover: () -> Unit,
onClickResume: () -> Unit,
onClickDelete: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier

View file

@ -1,13 +0,0 @@
package eu.kanade.presentation.history.anime
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import java.time.Instant
import java.util.Date
object AnimeHistoryUiModelProviders {
class HeadNow : PreviewParameterProvider<AnimeHistoryUiModel> {
override val values: Sequence<AnimeHistoryUiModel> =
sequenceOf(AnimeHistoryUiModel.Header(Date.from(Instant.now())))
}
}

View file

@ -4,7 +4,6 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import eu.kanade.domain.ui.UiPreferences
import eu.kanade.presentation.components.RelativeDateHeader
import tachiyomi.domain.history.manga.model.MangaHistoryWithRelations
@ -39,7 +38,6 @@ fun MangaHistoryContent(
when (item) {
is MangaHistoryUiModel.Header -> {
RelativeDateHeader(
modifier = Modifier.animateItemPlacement(),
date = item.date,
relativeTime = relativeTime,
dateFormat = dateFormat,
@ -48,7 +46,6 @@ fun MangaHistoryContent(
is MangaHistoryUiModel.Item -> {
val value = item.item
MangaHistoryItem(
modifier = Modifier.animateItemPlacement(),
history = value,
onClickCover = { onClickCover(value) },
onClickResume = { onClickResume(value) },

View file

@ -35,11 +35,11 @@ private val HISTORY_ITEM_HEIGHT = 96.dp
@Composable
fun MangaHistoryItem(
modifier: Modifier = Modifier,
history: MangaHistoryWithRelations,
onClickCover: () -> Unit,
onClickResume: () -> Unit,
onClickDelete: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier

View file

@ -1,13 +0,0 @@
package eu.kanade.presentation.history.manga
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import java.time.Instant
import java.util.Date
object MangaHistoryUiModelProviders {
class HeadNow : PreviewParameterProvider<MangaHistoryUiModel> {
override val values: Sequence<MangaHistoryUiModel> =
sequenceOf(MangaHistoryUiModel.Header(Date.from(Instant.now())))
}
}

View file

@ -33,11 +33,13 @@ import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import eu.kanade.presentation.entries.ItemCover
import eu.kanade.tachiyomi.R
import tachiyomi.domain.entries.EntryCover
import tachiyomi.presentation.core.components.BadgeGroup
import tachiyomi.presentation.core.util.selectedBackground
@ -377,7 +379,7 @@ private fun ContinueViewingButton(
) {
Icon(
imageVector = Icons.Filled.PlayArrow,
contentDescription = "",
contentDescription = stringResource(R.string.action_resume),
modifier = Modifier.size(16.dp),
)
}

View file

@ -4,13 +4,12 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.pager.PagerState
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.PrimaryScrollableTabRow
import androidx.compose.material3.Tab
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.category.visualName
import tachiyomi.domain.category.model.Category
import tachiyomi.presentation.core.components.material.TabIndicator
import tachiyomi.presentation.core.components.material.TabText
@Composable
@ -21,15 +20,9 @@ fun LibraryTabs(
onTabItemClick: (Int) -> Unit,
) {
Column {
ScrollableTabRow(
PrimaryScrollableTabRow(
selectedTabIndex = pagerState.currentPage,
edgePadding = 0.dp,
indicator = {
TabIndicator(
it[pagerState.currentPage],
pagerState.currentPageOffsetFraction,
)
},
// TODO: use default when width is fixed upstream
// https://issuetracker.google.com/issues/242879624
divider = {},

View file

@ -21,6 +21,7 @@ import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.presentation.core.components.Pill
import tachiyomi.presentation.core.theme.active
@ -99,7 +100,7 @@ fun LibraryRegularToolbar(
actions = {
val filterTint = if (hasFilters) MaterialTheme.colorScheme.active else LocalContentColor.current
AppBarActions(
listOf(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_filter),
icon = Icons.Outlined.FilterList,
@ -138,7 +139,7 @@ fun LibrarySelectionToolbar(
titleContent = { Text(text = "$selectedCount") },
actions = {
AppBarActions(
listOf(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_select_all),
icon = Icons.Outlined.SelectAll,

View file

@ -18,6 +18,7 @@ import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.anime.AnimeLibrarySettingsScreenModel
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.core.preference.TriState
import tachiyomi.domain.category.model.Category
import tachiyomi.domain.library.anime.model.AnimeLibrarySort
@ -40,7 +41,7 @@ fun AnimeLibrarySettingsDialog(
) {
TabbedDialog(
onDismissRequest = onDismissRequest,
tabTitles = listOf(
tabTitles = persistentListOf(
stringResource(R.string.action_filter),
stringResource(R.string.action_sort),
stringResource(R.string.action_display),

View file

@ -18,6 +18,7 @@ import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.manga.MangaLibrarySettingsScreenModel
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.core.preference.TriState
import tachiyomi.domain.category.model.Category
import tachiyomi.domain.library.manga.model.MangaLibrarySort
@ -40,7 +41,7 @@ fun MangaLibrarySettingsDialog(
) {
TabbedDialog(
onDismissRequest = onDismissRequest,
tabTitles = listOf(
tabTitles = persistentListOf(
stringResource(R.string.action_filter),
stringResource(R.string.action_sort),
stringResource(R.string.action_display),

View file

@ -9,13 +9,14 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.automirrored.outlined.Label
import androidx.compose.material.icons.outlined.CloudOff
import androidx.compose.material.icons.outlined.CollectionsBookmark
import androidx.compose.material.icons.outlined.GetApp
import androidx.compose.material.icons.outlined.HelpOutline
import androidx.compose.material.icons.outlined.History
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Label
import androidx.compose.material.icons.outlined.QueryStats
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.Storage
@ -163,7 +164,7 @@ fun MoreScreen(
item {
TextPreferenceWidget(
title = stringResource(R.string.general_categories),
icon = Icons.Outlined.Label,
icon = Icons.AutoMirrored.Outlined.Label,
onPreferenceClick = onClickCategories,
)
}
@ -208,7 +209,7 @@ fun MoreScreen(
item {
TextPreferenceWidget(
title = stringResource(R.string.label_help),
icon = Icons.Outlined.HelpOutline,
icon = Icons.AutoMirrored.Outlined.HelpOutline,
onPreferenceClick = { uriHandler.openUri(Constants.URL_HELP) },
)
}

View file

@ -5,7 +5,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.OpenInNew
import androidx.compose.material.icons.automirrored.outlined.OpenInNew
import androidx.compose.material.icons.outlined.NewReleases
import androidx.compose.material.icons.outlined.OpenInNew
import androidx.compose.material3.Icon
@ -61,7 +61,7 @@ fun NewUpdateScreen(
) {
Text(text = stringResource(R.string.update_check_open))
Spacer(modifier = Modifier.width(MaterialTheme.padding.tiny))
Icon(imageVector = Icons.Default.OpenInNew, contentDescription = null)
Icon(imageVector = Icons.AutoMirrored.Outlined.OpenInNew, contentDescription = null)
}
}
}

View file

@ -85,12 +85,11 @@ fun PreferenceScreen(
private fun List<Preference>.findHighlightedIndex(highlightKey: String): Int {
return flatMap {
if (it is Preference.PreferenceGroup) {
mutableListOf<String?>()
.apply {
add(null) // Header
addAll(it.preferenceItems.map { groupItem -> groupItem.title })
add(null) // Spacer
}
buildList<String?> {
add(null) // Header
addAll(it.preferenceItems.map { groupItem -> groupItem.title })
add(null) // Spacer
}
} else {
listOf(it.title)
}

View file

@ -1,6 +1,5 @@
package eu.kanade.presentation.more.settings.screen
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
@ -13,44 +12,39 @@ import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.screen.data.CreateBackupScreen
import eu.kanade.presentation.more.settings.widget.BasePreferenceWidget
import eu.kanade.presentation.more.settings.widget.PrefsHorizontalPadding
import eu.kanade.presentation.permissions.PermissionRequestHelper
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.BackupConst
import eu.kanade.tachiyomi.data.backup.BackupCreateJob
import eu.kanade.tachiyomi.data.backup.BackupFileValidator
import eu.kanade.tachiyomi.data.backup.BackupRestoreJob
import eu.kanade.tachiyomi.data.backup.models.Backup
import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.cache.EpisodeCache
import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.launch
import logcat.LogPriority
import tachiyomi.core.util.lang.launchNonCancellable
import tachiyomi.core.util.lang.withUIContext
@ -64,11 +58,7 @@ import tachiyomi.domain.backup.service.FLAG_HISTORY
import tachiyomi.domain.backup.service.FLAG_SETTINGS
import tachiyomi.domain.backup.service.FLAG_TRACK
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.util.collectAsState
import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -134,140 +124,11 @@ object SettingsDataScreen : SearchableSettings {
@Composable
private fun getCreateBackupPref(): Preference.PreferenceItem.TextPreference {
val scope = rememberCoroutineScope()
val context = LocalContext.current
var flag by rememberSaveable { mutableIntStateOf(0) }
val chooseBackupDir = rememberLauncherForActivityResult(
contract = ActivityResultContracts.CreateDocument("application/*"),
) {
if (it != null) {
context.contentResolver.takePersistableUriPermission(
it,
Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
)
BackupCreateJob.startNow(context, it, flag)
}
flag = 0
}
var showCreateDialog by rememberSaveable { mutableStateOf(false) }
if (showCreateDialog) {
CreateBackupDialog(
onConfirm = {
showCreateDialog = false
flag = it
try {
chooseBackupDir.launch(Backup.getFilename())
} catch (e: ActivityNotFoundException) {
flag = 0
context.toast(R.string.file_picker_error)
}
},
onDismissRequest = { showCreateDialog = false },
)
}
val navigator = LocalNavigator.currentOrThrow
return Preference.PreferenceItem.TextPreference(
title = stringResource(R.string.pref_create_backup),
subtitle = stringResource(R.string.pref_create_backup_summ),
onClick = {
scope.launch {
if (!BackupCreateJob.isManualJobRunning(context)) {
if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) {
context.toast(R.string.restore_miui_warning, Toast.LENGTH_LONG)
}
showCreateDialog = true
} else {
context.toast(R.string.backup_in_progress)
}
}
},
)
}
@Composable
private fun CreateBackupDialog(
onConfirm: (flag: Int) -> Unit,
onDismissRequest: () -> Unit,
) {
val choices = remember {
mapOf(
BackupConst.BACKUP_CATEGORY to R.string.general_categories,
BackupConst.BACKUP_CHAPTER to R.string.chapters_episodes,
BackupConst.BACKUP_TRACK to R.string.track,
BackupConst.BACKUP_HISTORY to R.string.history,
BackupConst.BACKUP_PREFS to R.string.settings,
BackupConst.BACKUP_EXT_PREFS to R.string.extension_settings,
BackupConst.BACKUP_EXTENSIONS to R.string.label_extensions,
)
}
val flags = remember {
mutableStateListOf(
BackupConst.BACKUP_CATEGORY,
BackupConst.BACKUP_CHAPTER,
BackupConst.BACKUP_TRACK,
BackupConst.BACKUP_HISTORY,
)
}
AlertDialog(
onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.backup_choice)) },
text = {
Box {
val state = rememberLazyListState()
ScrollbarLazyColumn(state = state) {
item {
LabeledCheckbox(
label = stringResource(R.string.entries),
checked = true,
onCheckedChange = {},
)
}
choices.forEach { (k, v) ->
item {
val isSelected = flags.contains(k)
LabeledCheckbox(
label = stringResource(v),
checked = isSelected,
onCheckedChange = {
if (it) {
flags.add(k)
} else {
flags.remove(k)
}
},
)
}
}
}
if (!state.isScrolledToStart()) {
HorizontalDivider(
modifier = Modifier.align(Alignment.TopCenter),
)
}
if (!state.isScrolledToEnd()) {
HorizontalDivider(
modifier = Modifier.align(Alignment.BottomCenter),
)
}
}
},
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel))
}
},
confirmButton = {
TextButton(
onClick = {
val flag = flags.fold(initial = 0, operation = { a, b -> a or b })
onConfirm(flag)
},
) {
Text(text = stringResource(R.string.action_ok))
}
},
onClick = { navigator.push(CreateBackupScreen()) },
)
}
@ -362,7 +223,7 @@ object SettingsDataScreen : SearchableSettings {
},
) {
if (it == null) {
error = InvalidRestore(message = context.getString(R.string.file_null_uri_error))
context.toast(R.string.file_null_uri_error)
return@rememberLauncherForActivityResult
}

View file

@ -9,6 +9,7 @@ import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ChromeReaderMode
import androidx.compose.material.icons.outlined.ChromeReaderMode
import androidx.compose.material.icons.outlined.Code
import androidx.compose.material.icons.outlined.CollectionsBookmark
@ -47,6 +48,7 @@ import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.presentation.util.LocalBackPress
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.presentation.core.components.material.Scaffold
import cafe.adriel.voyager.core.screen.Screen as VoyagerScreen
@ -87,7 +89,7 @@ object SettingsMainScreen : Screen() {
navigateUp = backPress::invoke,
actions = {
AppBarActions(
listOf(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_search),
icon = Icons.Outlined.Search,
@ -188,7 +190,7 @@ object SettingsMainScreen : Screen() {
Item(
titleRes = R.string.pref_category_reader,
subtitleRes = R.string.pref_reader_summary,
icon = Icons.Outlined.ChromeReaderMode,
icon = Icons.AutoMirrored.Outlined.ChromeReaderMode,
screen = SettingsReaderScreen,
),
Item(

View file

@ -36,6 +36,7 @@ import eu.kanade.tachiyomi.ui.player.VLC_PLAYER
import eu.kanade.tachiyomi.ui.player.WEB_VIDEO_CASTER
import eu.kanade.tachiyomi.ui.player.X_PLAYER
import eu.kanade.tachiyomi.ui.player.settings.PlayerPreferences
import kotlinx.collections.immutable.toImmutableList
import tachiyomi.presentation.core.components.WheelTextPicker
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
@ -395,7 +396,7 @@ object SettingsPlayerScreen : SearchableSettings {
R.string.seconds_short,
it,
)
},
}.toImmutableList(),
onSelectionChanged = {
newLength = it
},

View file

@ -20,6 +20,7 @@ import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.presentation.core.components.material.Scaffold
class OpenSourceLibraryLicenseScreen(
@ -41,7 +42,7 @@ class OpenSourceLibraryLicenseScreen(
actions = {
if (!website.isNullOrEmpty()) {
AppBarActions(
listOf(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.website),
icon = Icons.Default.Public,

View file

@ -41,6 +41,7 @@ import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.update
import tachiyomi.core.util.lang.launchIO
@ -106,7 +107,7 @@ class ClearAnimeDatabaseScreen : Screen() {
actions = {
if (s.items.isNotEmpty()) {
AppBarActions(
actions = listOf(
actions = persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_select_all),
icon = Icons.Outlined.SelectAll,

View file

@ -41,6 +41,7 @@ import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.update
import tachiyomi.core.util.lang.launchIO
@ -106,7 +107,7 @@ class ClearDatabaseScreen : Screen() {
actions = {
if (s.items.isNotEmpty()) {
AppBarActions(
actions = listOf(
actions = persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_select_all),
icon = Icons.Outlined.SelectAll,

View file

@ -0,0 +1,173 @@
package eu.kanade.presentation.more.settings.screen.data
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Button
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.BackupCreateFlags
import eu.kanade.tachiyomi.data.backup.BackupCreateJob
import eu.kanade.tachiyomi.data.backup.models.Backup
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.PersistentSet
import kotlinx.collections.immutable.minus
import kotlinx.collections.immutable.plus
import kotlinx.collections.immutable.toPersistentSet
import kotlinx.coroutines.flow.update
import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding
class CreateBackupScreen : Screen() {
@Composable
override fun Content() {
val context = LocalContext.current
val navigator = LocalNavigator.currentOrThrow
val model = rememberScreenModel { CreateBackupScreenModel() }
val state by model.state.collectAsState()
val chooseBackupDir = rememberLauncherForActivityResult(
contract = ActivityResultContracts.CreateDocument("application/*"),
) {
if (it != null) {
context.contentResolver.takePersistableUriPermission(
it,
Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
)
model.createBackup(context, it)
navigator.pop()
}
}
Scaffold(
topBar = {
AppBar(
title = stringResource(R.string.pref_create_backup),
navigateUp = navigator::pop,
scrollBehavior = it,
)
},
) { contentPadding ->
Column(
modifier = Modifier
.padding(contentPadding)
.fillMaxSize(),
) {
LazyColumn(
modifier = Modifier
.weight(1f)
.padding(horizontal = MaterialTheme.padding.medium),
) {
item {
LabeledCheckbox(
label = stringResource(R.string.entries),
checked = true,
onCheckedChange = {},
enabled = false,
)
}
BackupChoices.forEach { (k, v) ->
item {
LabeledCheckbox(
label = stringResource(v),
checked = state.flags.contains(k),
onCheckedChange = {
model.toggleFlag(k)
},
)
}
}
}
HorizontalDivider()
Button(
modifier = Modifier
.padding(horizontal = 16.dp, vertical = 8.dp)
.fillMaxWidth(),
onClick = {
if (!BackupCreateJob.isManualJobRunning(context)) {
if (DeviceUtil.isMiui && DeviceUtil.isMiuiOptimizationDisabled()) {
context.toast(R.string.restore_miui_warning, Toast.LENGTH_LONG)
}
try {
chooseBackupDir.launch(Backup.getFilename())
} catch (e: ActivityNotFoundException) {
context.toast(R.string.file_picker_error)
}
} else {
context.toast(R.string.backup_in_progress)
}
},
) {
Text(
text = stringResource(R.string.action_create),
color = MaterialTheme.colorScheme.onPrimary,
)
}
}
}
}
}
private class CreateBackupScreenModel : StateScreenModel<CreateBackupScreenModel.State>(State()) {
fun toggleFlag(flag: Int) {
mutableState.update {
if (it.flags.contains(flag)) {
it.copy(flags = it.flags - flag)
} else {
it.copy(flags = it.flags + flag)
}
}
}
fun createBackup(context: Context, uri: Uri) {
val flags = state.value.flags.fold(initial = 0, operation = { a, b -> a or b })
BackupCreateJob.startNow(context, uri, flags)
}
@Immutable
data class State(
val flags: PersistentSet<Int> = BackupChoices.keys.toPersistentSet(),
)
}
private val BackupChoices = mapOf(
BackupCreateFlags.BACKUP_CATEGORY to R.string.general_categories,
BackupCreateFlags.BACKUP_CHAPTER to R.string.chapters_episodes,
BackupCreateFlags.BACKUP_TRACK to R.string.track,
BackupCreateFlags.BACKUP_HISTORY to R.string.history,
BackupCreateFlags.BACKUP_PREFS to R.string.settings,
BackupCreateFlags.BACKUP_EXT_PREFS to R.string.extension_settings,
BackupCreateFlags.BACKUP_EXTENSIONS to R.string.label_extensions,
)

View file

@ -21,6 +21,7 @@ import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.models.Backup
import eu.kanade.tachiyomi.util.system.copyToClipboard
import kotlinx.collections.immutable.persistentListOf
import kotlinx.serialization.protobuf.schema.ProtoBufSchemaGenerator
import tachiyomi.presentation.core.components.material.Scaffold
@ -48,7 +49,7 @@ class BackupSchemaScreen : Screen() {
navigateUp = navigator::pop,
actions = {
AppBarActions(
listOf(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_copy_to_clipboard),
icon = Icons.Default.ContentCopy,

View file

@ -33,6 +33,7 @@ import eu.kanade.presentation.util.ioCoroutineScope
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.system.workManager
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
@ -62,7 +63,7 @@ class WorkerInfoScreen : Screen() {
navigateUp = navigator::pop,
actions = {
AppBarActions(
listOf(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_copy_to_clipboard),
icon = Icons.Default.ContentCopy,

View file

@ -29,6 +29,7 @@ import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import eu.kanade.tachiyomi.ui.reader.viewer.Viewer
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
import kotlinx.collections.immutable.persistentListOf
private val animationSpec = tween<IntOffset>(200)
@ -98,27 +99,43 @@ fun ReaderAppBars(
navigateUp = navigateUp,
actions = {
AppBarActions(
listOfNotNull(
AppBar.Action(
title = stringResource(
if (bookmarked) R.string.action_remove_bookmark else R.string.action_bookmark,
),
icon = if (bookmarked) Icons.Outlined.Bookmark else Icons.Outlined.BookmarkBorder,
onClick = onToggleBookmarked,
),
onOpenInWebView?.let {
AppBar.OverflowAction(
title = stringResource(R.string.action_open_in_web_view),
onClick = it,
actions = persistentListOf<AppBar.AppBarAction>().builder()
.apply {
add(
AppBar.Action(
title = stringResource(
if (bookmarked) {
R.string.action_remove_bookmark
} else {
R.string.action_bookmark
},
),
icon = if (bookmarked) {
Icons.Outlined.Bookmark
} else {
Icons.Outlined.BookmarkBorder
},
onClick = onToggleBookmarked,
),
)
},
onShare?.let {
AppBar.OverflowAction(
title = stringResource(R.string.action_share),
onClick = it,
)
},
),
onOpenInWebView?.let {
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_open_in_web_view),
onClick = it,
),
)
}
onShare?.let {
add(
AppBar.OverflowAction(
title = stringResource(R.string.action_share),
onClick = it,
),
)
}
}
.build(),
)
},
)

View file

@ -17,6 +17,7 @@ import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
import kotlinx.collections.immutable.persistentListOf
@Composable
fun ReaderSettingsDialog(
@ -25,7 +26,7 @@ fun ReaderSettingsDialog(
onHideMenus: () -> Unit,
screenModel: ReaderSettingsScreenModel,
) {
val tabTitles = listOf(
val tabTitles = persistentListOf(
stringResource(R.string.pref_category_reading_mode),
stringResource(R.string.pref_category_general),
stringResource(R.string.custom_filter),

View file

@ -36,6 +36,8 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.R
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.WheelNumberPicker
import tachiyomi.presentation.core.components.WheelTextPicker
@ -114,9 +116,9 @@ fun TrackItemSelector(
title = stringResource(titleText),
content = {
WheelNumberPicker(
items = range.toImmutableList(),
modifier = Modifier.align(Alignment.Center),
startIndex = selection,
items = range.toList(),
onSelectionChanged = { onSelectionChange(it) },
)
},
@ -129,7 +131,7 @@ fun TrackItemSelector(
fun TrackScoreSelector(
selection: String,
onSelectionChange: (String) -> Unit,
selections: List<String>,
selections: ImmutableList<String>,
onConfirm: () -> Unit,
onDismissRequest: () -> Unit,
) {
@ -137,9 +139,9 @@ fun TrackScoreSelector(
title = stringResource(R.string.score),
content = {
WheelTextPicker(
items = selections,
modifier = Modifier.align(Alignment.Center),
startIndex = selections.indexOf(selection).takeIf { it > 0 } ?: (selections.size / 2),
items = selections,
onSelectionChanged = { onSelectionChange(selections[it]) },
)
},
@ -203,9 +205,9 @@ fun TrackDateSelector(
fun BaseSelector(
title: String,
content: @Composable BoxScope.() -> Unit,
thirdButton: @Composable (RowScope.() -> Unit)? = null,
onConfirm: () -> Unit,
onDismissRequest: () -> Unit,
thirdButton: @Composable (RowScope.() -> Unit)? = null,
) {
AlertDialogContent(
modifier = Modifier.windowInsetsPadding(WindowInsets.systemBars),

View file

@ -2,8 +2,8 @@ package eu.kanade.presentation.track.anime
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import eu.kanade.tachiyomi.dev.preview.DummyTracker
import eu.kanade.tachiyomi.ui.entries.anime.track.AnimeTrackItem
import eu.kanade.test.DummyTracker
import tachiyomi.domain.track.anime.model.AnimeTrack
import java.text.DateFormat

View file

@ -18,7 +18,7 @@ import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material3.Button
@ -81,7 +81,7 @@ fun AnimeTrackerSearch(
navigationIcon = {
IconButton(onClick = onDismissRequest) {
Icon(
imageVector = Icons.Default.ArrowBack,
imageVector = Icons.AutoMirrored.Outlined.ArrowBack,
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurfaceVariant,
)

View file

@ -4,7 +4,7 @@ import android.graphics.Color
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.Tracker
import eu.kanade.tachiyomi.dev.preview.DummyTracker
import eu.kanade.test.DummyTracker
internal class TrackLogoIconPreviewProvider : PreviewParameterProvider<Tracker> {

View file

@ -243,10 +243,10 @@ private fun TrackInfoItem(
@Composable
fun TrackDetailsItem(
modifier: Modifier = Modifier,
text: String?,
placeholder: String = "",
onClick: () -> Unit,
modifier: Modifier = Modifier,
placeholder: String = "",
) {
Box(
modifier = modifier

View file

@ -2,8 +2,8 @@ package eu.kanade.presentation.track.manga
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import eu.kanade.tachiyomi.dev.preview.DummyTracker
import eu.kanade.tachiyomi.ui.entries.manga.track.MangaTrackItem
import eu.kanade.test.DummyTracker
import tachiyomi.domain.track.manga.model.MangaTrack
import java.text.DateFormat

View file

@ -28,10 +28,9 @@ import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.HorizontalDivider
@ -99,7 +98,7 @@ fun MangaTrackerSearch(
navigationIcon = {
IconButton(onClick = onDismissRequest) {
Icon(
imageVector = Icons.Default.ArrowBack,
imageVector = Icons.AutoMirrored.Outlined.ArrowBack,
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurfaceVariant,
)

View file

@ -98,14 +98,14 @@ fun LazyListScope.animeUpdatesUiItems(
when (item) {
is AnimeUpdatesUiModel.Header -> {
ListGroupHeader(
modifier = Modifier.animateItemPlacement(),
text = item.date,
)
}
is AnimeUpdatesUiModel.Item -> {
val updatesItem = item.item
AnimeUpdatesUiItem(
modifier = Modifier.animateItemPlacement(),
update = updatesItem.update,
selected = updatesItem.selected,
watchProgress = updatesItem.update.lastSecondSeen
@ -146,7 +146,6 @@ fun LazyListScope.animeUpdatesUiItems(
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun AnimeUpdatesUiItem(
modifier: Modifier,
update: AnimeUpdatesWithRelations,
selected: Boolean,
watchProgress: String?,
@ -157,6 +156,7 @@ fun AnimeUpdatesUiItem(
// Download Indicator
downloadStateProvider: () -> AnimeDownload.State,
downloadProgressProvider: () -> Int,
modifier: Modifier = Modifier,
) {
val haptic = LocalHapticFeedback.current
val textAlpha = if (update.seen) ReadItemAlpha else 1f

View file

@ -97,14 +97,14 @@ fun LazyListScope.mangaUpdatesUiItems(
when (item) {
is MangaUpdatesUiModel.Header -> {
ListGroupHeader(
modifier = Modifier.animateItemPlacement(),
text = item.date,
)
}
is MangaUpdatesUiModel.Item -> {
val updatesItem = item.item
MangaUpdatesUiItem(
modifier = Modifier.animateItemPlacement(),
update = updatesItem.update,
selected = updatesItem.selected,
readProgress = updatesItem.update.lastPageRead
@ -144,7 +144,6 @@ fun LazyListScope.mangaUpdatesUiItems(
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MangaUpdatesUiItem(
modifier: Modifier,
update: MangaUpdatesWithRelations,
selected: Boolean,
readProgress: String?,
@ -155,6 +154,7 @@ fun MangaUpdatesUiItem(
// Download Indicator
downloadStateProvider: () -> MangaDownload.State,
downloadProgressProvider: () -> Int,
modifier: Modifier = Modifier,
) {
val haptic = LocalHapticFeedback.current
val textAlpha = if (update.read) ReadItemAlpha else 1f

View file

@ -1,5 +1,6 @@
package eu.kanade.presentation.util
import android.annotation.SuppressLint
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.ContentTransform
@ -27,6 +28,7 @@ import soup.compose.material.motion.animation.rememberSlideDistance
/**
* For invoking back press to the parent activity
*/
@SuppressLint("ComposeCompositionLocalUsage")
val LocalBackPress: ProvidableCompositionLocal<(() -> Unit)?> = staticCompositionLocalOf { null }
abstract class Tab : cafe.adriel.voyager.navigator.tab.Tab {
@ -81,7 +83,7 @@ fun ScreenTransition(
targetState = navigator.lastItem,
transitionSpec = transition,
modifier = modifier,
label = "",
label = "transition",
) { screen ->
navigator.saveableState("transition", screen) {
content(screen)

View file

@ -41,6 +41,7 @@ import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.getHtml
import eu.kanade.tachiyomi.util.system.setDefaultSettings
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.launch
import tachiyomi.presentation.core.components.material.Scaffold
@ -49,11 +50,11 @@ fun WebViewScreenContent(
onNavigateUp: () -> Unit,
initialTitle: String?,
url: String,
headers: Map<String, String> = emptyMap(),
onUrlChange: (String) -> Unit = {},
onShare: (String) -> Unit,
onOpenInBrowser: (String) -> Unit,
onClearCookies: (String) -> Unit,
headers: Map<String, String> = emptyMap(),
onUrlChange: (String) -> Unit = {},
) {
val state = rememberWebViewState(url = url, additionalHttpHeaders = headers)
val navigator = rememberWebViewNavigator()
@ -116,7 +117,7 @@ fun WebViewScreenContent(
navigationIcon = Icons.Outlined.Close,
actions = {
AppBarActions(
listOf(
persistentListOf(
AppBar.Action(
title = stringResource(R.string.action_webview_back),
icon = Icons.Outlined.ArrowBack,
@ -182,7 +183,7 @@ fun WebViewScreenContent(
.align(Alignment.BottomCenter),
)
is LoadingState.Loading -> LinearProgressIndicator(
progress = (loadingState as? LoadingState.Loading)?.progress ?: 1f,
progress = { (loadingState as? LoadingState.Loading)?.progress ?: 1f },
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter),

View file

@ -38,6 +38,8 @@ import eu.kanade.tachiyomi.data.coil.MangaCoverKeyer
import eu.kanade.tachiyomi.data.coil.MangaKeyer
import eu.kanade.tachiyomi.data.coil.TachiyomiImageDecoder
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.di.AppModule
import eu.kanade.tachiyomi.di.PreferenceModule
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.NetworkPreferences
import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
@ -59,8 +61,8 @@ import org.acra.ktx.initAcra
import org.acra.sender.HttpSender
import org.conscrypt.Conscrypt
import tachiyomi.core.util.system.logcat
import tachiyomi.presentation.widget.entries.anime.TachiyomiAnimeWidgetManager
import tachiyomi.presentation.widget.entries.manga.TachiyomiMangaWidgetManager
import tachiyomi.presentation.widget.entries.anime.AnimeWidgetManager
import tachiyomi.presentation.widget.entries.manga.MangaWidgetManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
@ -134,11 +136,11 @@ class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
setAppCompatDelegateThemeMode(Injekt.get<UiPreferences>().themeMode().get())
// Updates widget update
with(TachiyomiMangaWidgetManager(Injekt.get(), Injekt.get())) {
with(MangaWidgetManager(Injekt.get(), Injekt.get())) {
init(ProcessLifecycleOwner.get().lifecycleScope)
}
with(TachiyomiAnimeWidgetManager(Injekt.get(), Injekt.get())) {
with(AnimeWidgetManager(Injekt.get(), Injekt.get())) {
init(ProcessLifecycleOwner.get().lifecycleScope)
}

View file

@ -1,27 +0,0 @@
package eu.kanade.tachiyomi.data.backup
// Filter options
internal object BackupConst {
const val BACKUP_CATEGORY = 0x1
const val BACKUP_CATEGORY_MASK = 0x1
const val BACKUP_CHAPTER = 0x2
const val BACKUP_CHAPTER_MASK = 0x2
const val BACKUP_HISTORY = 0x4
const val BACKUP_HISTORY_MASK = 0x4
const val BACKUP_TRACK = 0x8
const val BACKUP_TRACK_MASK = 0x8
const val BACKUP_PREFS = 0x10
const val BACKUP_PREFS_MASK = 0x10
const val BACKUP_EXT_PREFS = 0x20
const val BACKUP_EXT_PREFS_MASK = 0x20
const val BACKUP_EXTENSIONS = 0x40
const val BACKUP_EXTENSIONS_MASK = 0x40
const val BACKUP_ALL = 0x7F
}

View file

@ -0,0 +1,18 @@
package eu.kanade.tachiyomi.data.backup
internal object BackupCreateFlags {
const val BACKUP_CATEGORY = 0x1
const val BACKUP_CHAPTER = 0x2
const val BACKUP_HISTORY = 0x4
const val BACKUP_TRACK = 0x8
const val BACKUP_PREFS = 0x10
const val BACKUP_EXT_PREFS = 0x20
const val BACKUP_EXTENSIONS = 0x40
const val AutomaticDefaults = BACKUP_CATEGORY or
BACKUP_CHAPTER or
BACKUP_HISTORY or
BACKUP_TRACK or
BACKUP_PREFS or
BACKUP_EXT_PREFS
}

View file

@ -40,7 +40,7 @@ class BackupCreateJob(private val context: Context, workerParams: WorkerParamete
val backupPreferences = Injekt.get<BackupPreferences>()
val uri = inputData.getString(LOCATION_URI_KEY)?.toUri()
?: backupPreferences.backupsDirectory().get().toUri()
val flags = inputData.getInt(BACKUP_FLAGS_KEY, BackupConst.BACKUP_ALL)
val flags = inputData.getInt(BACKUP_FLAGS_KEY, BackupCreateFlags.AutomaticDefaults)
try {
setForeground(getForegroundInfo())
} catch (e: IllegalStateException) {

View file

@ -8,6 +8,13 @@ import android.net.Uri
import androidx.preference.PreferenceManager
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.BackupCreateFlags.BACKUP_CATEGORY
import eu.kanade.tachiyomi.data.backup.BackupCreateFlags.BACKUP_CHAPTER
import eu.kanade.tachiyomi.data.backup.BackupCreateFlags.BACKUP_EXTENSIONS
import eu.kanade.tachiyomi.data.backup.BackupCreateFlags.BACKUP_EXT_PREFS
import eu.kanade.tachiyomi.data.backup.BackupCreateFlags.BACKUP_HISTORY
import eu.kanade.tachiyomi.data.backup.BackupCreateFlags.BACKUP_PREFS
import eu.kanade.tachiyomi.data.backup.BackupCreateFlags.BACKUP_TRACK
import eu.kanade.tachiyomi.data.backup.models.Backup
import eu.kanade.tachiyomi.data.backup.models.BackupAnime
import eu.kanade.tachiyomi.data.backup.models.BackupAnimeHistory
@ -190,7 +197,7 @@ class BackupCreator(
*/
private suspend fun backupCategories(options: Int): List<BackupCategory> {
// Check if user wants category information in backup
return if (options and BackupConst.BACKUP_CATEGORY_MASK == BackupConst.BACKUP_CATEGORY) {
return if (options and BACKUP_CATEGORY == BACKUP_CATEGORY) {
getMangaCategories.await()
.filterNot(Category::isSystemCategory)
.map(backupCategoryMapper)
@ -206,7 +213,7 @@ class BackupCreator(
*/
private suspend fun backupAnimeCategories(options: Int): List<BackupCategory> {
// Check if user wants category information in backup
return if (options and BackupConst.BACKUP_CATEGORY_MASK == BackupConst.BACKUP_CATEGORY) {
return if (options and BACKUP_CATEGORY == BACKUP_CATEGORY) {
getAnimeCategories.await()
.filterNot(Category::isSystemCategory)
.map(backupCategoryMapper)
@ -239,7 +246,7 @@ class BackupCreator(
val mangaObject = BackupManga.copyFrom(manga)
// Check if user wants chapter information in backup
if (options and BackupConst.BACKUP_CHAPTER_MASK == BackupConst.BACKUP_CHAPTER) {
if (options and BACKUP_CHAPTER == BACKUP_CHAPTER) {
// Backup all the chapters
mangaHandler.awaitList {
chaptersQueries.getChaptersByMangaId(
@ -253,7 +260,7 @@ class BackupCreator(
}
// Check if user wants category information in backup
if (options and BackupConst.BACKUP_CATEGORY_MASK == BackupConst.BACKUP_CATEGORY) {
if (options and BACKUP_CATEGORY == BACKUP_CATEGORY) {
// Backup categories for this manga
val categoriesForManga = getMangaCategories.await(manga.id)
if (categoriesForManga.isNotEmpty()) {
@ -262,7 +269,7 @@ class BackupCreator(
}
// Check if user wants track information in backup
if (options and BackupConst.BACKUP_TRACK_MASK == BackupConst.BACKUP_TRACK) {
if (options and BACKUP_TRACK == BACKUP_TRACK) {
val tracks = mangaHandler.awaitList {
manga_syncQueries.getTracksByMangaId(
manga.id,
@ -275,7 +282,7 @@ class BackupCreator(
}
// Check if user wants history information in backup
if (options and BackupConst.BACKUP_HISTORY_MASK == BackupConst.BACKUP_HISTORY) {
if (options and BACKUP_HISTORY == BACKUP_HISTORY) {
val historyByMangaId = getMangaHistory.await(manga.id)
if (historyByMangaId.isNotEmpty()) {
val history = historyByMangaId.map { history ->
@ -307,7 +314,7 @@ class BackupCreator(
val animeObject = BackupAnime.copyFrom(anime)
// Check if user wants chapter information in backup
if (options and BackupConst.BACKUP_CHAPTER_MASK == BackupConst.BACKUP_CHAPTER) {
if (options and BACKUP_CHAPTER == BACKUP_CHAPTER) {
// Backup all the chapters
val episodes = animeHandler.awaitList {
episodesQueries.getEpisodesByAnimeId(
@ -321,7 +328,7 @@ class BackupCreator(
}
// Check if user wants category information in backup
if (options and BackupConst.BACKUP_CATEGORY_MASK == BackupConst.BACKUP_CATEGORY) {
if (options and BACKUP_CATEGORY == BACKUP_CATEGORY) {
// Backup categories for this manga
val categoriesForAnime = getAnimeCategories.await(anime.id)
if (categoriesForAnime.isNotEmpty()) {
@ -330,7 +337,7 @@ class BackupCreator(
}
// Check if user wants track information in backup
if (options and BackupConst.BACKUP_TRACK_MASK == BackupConst.BACKUP_TRACK) {
if (options and BACKUP_TRACK == BACKUP_TRACK) {
val tracks = animeHandler.awaitList {
anime_syncQueries.getTracksByAnimeId(
anime.id,
@ -343,7 +350,7 @@ class BackupCreator(
}
// Check if user wants history information in backup
if (options and BackupConst.BACKUP_HISTORY_MASK == BackupConst.BACKUP_HISTORY) {
if (options and BACKUP_HISTORY == BACKUP_HISTORY) {
val historyByAnimeId = getAnimeHistory.await(anime.id)
if (historyByAnimeId.isNotEmpty()) {
val history = historyByAnimeId.map { history ->
@ -364,7 +371,7 @@ class BackupCreator(
}
private fun backupExtensionPreferences(flags: Int): List<BackupExtensionPreferences> {
if (flags and BackupConst.BACKUP_EXT_PREFS_MASK != BackupConst.BACKUP_EXT_PREFS) return emptyList()
if (flags and BACKUP_EXT_PREFS != BACKUP_EXT_PREFS) return emptyList()
val prefs = mutableListOf<Pair<String, SharedPreferences>>()
Injekt.get<AnimeSourceManager>().getCatalogueSources().forEach {
val name = it.getPreferenceKey()
@ -377,14 +384,14 @@ class BackupCreator(
return prefs.map {
BackupExtensionPreferences(
it.first,
backupPreferences(it.second, BackupConst.BACKUP_PREFS),
backupPreferences(it.second, BACKUP_PREFS),
)
}
}
@Suppress("DEPRECATION")
private fun backupExtensions(flags: Int): List<BackupExtension> {
if (flags and BackupConst.BACKUP_EXTENSIONS_MASK != BackupConst.BACKUP_EXTENSIONS) return emptyList()
if (flags and BACKUP_EXTENSIONS != BACKUP_EXTENSIONS) return emptyList()
val installedExtensions = mutableListOf<BackupExtension>()
Injekt.get<AnimeExtensionManager>().installedExtensionsFlow.value.forEach {
val packageName = it.pkgName
@ -416,7 +423,7 @@ class BackupCreator(
}
private fun backupPreferences(prefs: SharedPreferences, flags: Int): List<BackupPreference> {
if (flags and BackupConst.BACKUP_PREFS_MASK != BackupConst.BACKUP_PREFS) return emptyList()
if (flags and BACKUP_PREFS != BACKUP_PREFS) return emptyList()
val backupPreferences = mutableListOf<BackupPreference>()
for (pref in prefs.all) {
val toAdd = when (pref.value) {

View file

@ -6,6 +6,7 @@ import eu.kanade.domain.track.anime.model.toDomainTrack
import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.ImmutableList
import logcat.LogPriority
import tachiyomi.core.util.lang.withIOContext
import tachiyomi.core.util.lang.withUIContext
@ -24,7 +25,7 @@ interface AnimeTracker {
// Common functions
fun getCompletionStatus(): Int
fun getScoreList(): List<String>
fun getScoreList(): ImmutableList<String>
fun indexToScore(index: Int): Float {
return index.toFloat()

View file

@ -6,6 +6,7 @@ import eu.kanade.domain.track.manga.model.toDomainTrack
import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack
import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.ImmutableList
import logcat.LogPriority
import tachiyomi.core.util.lang.withIOContext
import tachiyomi.core.util.lang.withUIContext
@ -24,7 +25,7 @@ interface MangaTracker {
// Common functions
fun getCompletionStatus(): Int
fun getScoreList(): List<String>
fun getScoreList(): ImmutableList<String>
fun indexToScore(index: Int): Float {
return index.toFloat()

View file

@ -4,6 +4,7 @@ import androidx.annotation.CallSuper
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import kotlinx.collections.immutable.ImmutableList
import okhttp3.OkHttpClient
interface Tracker {
@ -25,8 +26,11 @@ interface Tracker {
@StringRes
fun getStatus(status: Int): Int?
fun getCompletionStatus(): Int
fun getScoreList(): List<String>
fun getScoreList(): ImmutableList<String>
suspend fun login(username: String, password: String)
@CallSuper

View file

@ -12,6 +12,9 @@ import eu.kanade.tachiyomi.data.track.DeletableMangaTracker
import eu.kanade.tachiyomi.data.track.MangaTracker
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
@ -103,18 +106,18 @@ class Anilist(id: Long) :
override fun getCompletionStatus(): Int = COMPLETED
override fun getScoreList(): List<String> {
override fun getScoreList(): ImmutableList<String> {
return when (scorePreference.get()) {
// 10 point
POINT_10 -> IntRange(0, 10).map(Int::toString)
POINT_10 -> IntRange(0, 10).map(Int::toString).toImmutableList()
// 100 point
POINT_100 -> IntRange(0, 100).map(Int::toString)
POINT_100 -> IntRange(0, 100).map(Int::toString).toImmutableList()
// 5 stars
POINT_5 -> IntRange(0, 5).map { "$it" }
POINT_5 -> IntRange(0, 5).map { "$it" }.toImmutableList()
// Smiley
POINT_3 -> listOf("-", "😦", "😐", "😊")
POINT_3 -> persistentListOf("-", "😦", "😐", "😊")
// 10 point decimal
POINT_10_DECIMAL -> IntRange(0, 100).map { (it / 10f).toString() }
POINT_10_DECIMAL -> IntRange(0, 100).map { (it / 10f).toString() }.toImmutableList()
else -> throw Exception("Unknown score type")
}
}

View file

@ -10,6 +10,8 @@ import eu.kanade.tachiyomi.data.track.BaseTracker
import eu.kanade.tachiyomi.data.track.MangaTracker
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
@ -23,9 +25,7 @@ class Bangumi(id: Long) : BaseTracker(id, "Bangumi"), MangaTracker, AnimeTracker
private val api by lazy { BangumiApi(id, client, interceptor) }
override fun getScoreList(): List<String> {
return IntRange(0, 10).map(Int::toString)
}
override fun getScoreList(): ImmutableList<String> = SCORE_LIST
override fun indexToScore(index: Int): Float {
return index.toFloat()
@ -218,5 +218,9 @@ class Bangumi(id: Long) : BaseTracker(id, "Bangumi"), MangaTracker, AnimeTracker
const val ON_HOLD = 4
const val DROPPED = 5
const val PLAN_TO_READ = 1
private val SCORE_LIST = IntRange(0, 10)
.map(Int::toString)
.toImmutableList()
}
}

View file

@ -12,6 +12,8 @@ import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.MangaSource
import eu.kanade.tachiyomi.source.sourcePreferences
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.entries.manga.model.Manga
import tachiyomi.domain.source.manga.service.MangaSourceManager
import uy.kohesive.injekt.injectLazy
@ -53,7 +55,7 @@ class Kavita(id: Long) : BaseTracker(id, "Kavita"), EnhancedMangaTracker, MangaT
override fun getCompletionStatus(): Int = COMPLETED
override fun getScoreList(): List<String> = emptyList()
override fun getScoreList(): ImmutableList<String> = persistentListOf()
override fun displayScore(track: MangaTrack): String = ""

View file

@ -12,6 +12,8 @@ import eu.kanade.tachiyomi.data.track.DeletableMangaTracker
import eu.kanade.tachiyomi.data.track.MangaTracker
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy
@ -79,9 +81,9 @@ class Kitsu(id: Long) :
override fun getCompletionStatus(): Int = COMPLETED
override fun getScoreList(): List<String> {
override fun getScoreList(): ImmutableList<String> {
val df = DecimalFormat("0.#")
return listOf("0") + IntRange(2, 20).map { df.format(it / 2f) }
return (listOf("0") + IntRange(2, 20).map { df.format(it / 2f) }).toImmutableList()
}
override fun indexToScore(index: Int): Float {

View file

@ -9,6 +9,8 @@ import eu.kanade.tachiyomi.data.track.EnhancedMangaTracker
import eu.kanade.tachiyomi.data.track.MangaTracker
import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch
import eu.kanade.tachiyomi.source.MangaSource
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import okhttp3.Dns
import okhttp3.OkHttpClient
import tachiyomi.domain.entries.manga.model.Manga
@ -51,7 +53,7 @@ class Komga(id: Long) : BaseTracker(id, "Komga"), EnhancedMangaTracker, MangaTra
override fun getCompletionStatus(): Int = COMPLETED
override fun getScoreList(): List<String> = emptyList()
override fun getScoreList(): ImmutableList<String> = persistentListOf()
override suspend fun update(track: MangaTrack, didReadChapter: Boolean): MangaTrack {
if (track.status != COMPLETED) {

View file

@ -10,6 +10,8 @@ import eu.kanade.tachiyomi.data.track.MangaTracker
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.copyTo
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.toTrackSearch
import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), MangaTracker, DeletableMangaTracker {
@ -19,6 +21,12 @@ class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), MangaTracker, De
const val COMPLETE_LIST = 2
const val UNFINISHED_LIST = 3
const val ON_HOLD_LIST = 4
private val SCORE_LIST = (
(0..9)
.flatMap { i -> (0..9).map { j -> "$i.$j" } } + listOf("10.0")
)
.toImmutableList()
}
private val interceptor by lazy { MangaUpdatesInterceptor(this) }
@ -49,11 +57,9 @@ class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), MangaTracker, De
override fun getCompletionStatus(): Int = COMPLETE_LIST
private val _scoreList = (0..9).flatMap { i -> (0..9).map { j -> "$i.$j" } } + listOf("10.0")
override fun getScoreList(): ImmutableList<String> = SCORE_LIST
override fun getScoreList(): List<String> = _scoreList
override fun indexToScore(index: Int): Float = _scoreList[index].toFloat()
override fun indexToScore(index: Int): Float = SCORE_LIST[index].toFloat()
override fun displayScore(track: MangaTrack): String = track.score.toString()

View file

@ -12,6 +12,8 @@ import eu.kanade.tachiyomi.data.track.DeletableMangaTracker
import eu.kanade.tachiyomi.data.track.MangaTracker
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
@ -40,6 +42,10 @@ class MyAnimeList(id: Long) :
private const val SEARCH_ID_PREFIX = "id:"
private const val SEARCH_LIST_PREFIX = "my:"
private val SCORE_LIST = IntRange(0, 10)
.map(Int::toString)
.toImmutableList()
}
private val json: Json by injectLazy()
@ -85,9 +91,7 @@ class MyAnimeList(id: Long) :
override fun getCompletionStatus(): Int = COMPLETED
override fun getScoreList(): List<String> {
return IntRange(0, 10).map(Int::toString)
}
override fun getScoreList(): ImmutableList<String> = SCORE_LIST
override fun indexToScore(index: Int): Float {
return index.toFloat()

View file

@ -12,6 +12,8 @@ import eu.kanade.tachiyomi.data.track.DeletableMangaTracker
import eu.kanade.tachiyomi.data.track.MangaTracker
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
@ -34,6 +36,10 @@ class Shikimori(id: Long) :
const val DROPPED = 4
const val PLAN_TO_READ = 5
const val REREADING = 6
private val SCORE_LIST = IntRange(0, 10)
.map(Int::toString)
.toImmutableList()
}
private val json: Json by injectLazy()
@ -42,9 +48,7 @@ class Shikimori(id: Long) :
private val api by lazy { ShikimoriApi(id, client, interceptor) }
override fun getScoreList(): List<String> {
return IntRange(0, 10).map(Int::toString)
}
override fun getScoreList(): ImmutableList<String> = SCORE_LIST
override fun indexToScore(index: Int): Float {
return index.toFloat()

View file

@ -7,6 +7,8 @@ import eu.kanade.tachiyomi.data.database.models.anime.AnimeTrack
import eu.kanade.tachiyomi.data.track.AnimeTracker
import eu.kanade.tachiyomi.data.track.BaseTracker
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
@ -20,6 +22,10 @@ class Simkl(id: Long) : BaseTracker(id, "Simkl"), AnimeTracker {
const val ON_HOLD = 3
const val NOT_INTERESTING = 4
const val PLAN_TO_WATCH = 5
private val SCORE_LIST = IntRange(0, 10)
.map(Int::toString)
.toImmutableList()
}
private val json: Json by injectLazy()
@ -28,9 +34,7 @@ class Simkl(id: Long) : BaseTracker(id, "Simkl"), AnimeTracker {
private val api by lazy { SimklApi(client, interceptor) }
override fun getScoreList(): List<String> {
return IntRange(0, 10).map(Int::toString)
}
override fun getScoreList(): ImmutableList<String> = SCORE_LIST
override fun displayScore(track: AnimeTrack): String {
return track.score.toInt().toString()

View file

@ -9,6 +9,8 @@ import eu.kanade.tachiyomi.data.track.EnhancedMangaTracker
import eu.kanade.tachiyomi.data.track.MangaTracker
import eu.kanade.tachiyomi.data.track.model.MangaTrackSearch
import eu.kanade.tachiyomi.source.MangaSource
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.entries.manga.model.Manga as DomainManga
import tachiyomi.domain.track.manga.model.MangaTrack as DomainTrack
@ -42,7 +44,7 @@ class Suwayomi(id: Long) : BaseTracker(id, "Suwayomi"), EnhancedMangaTracker, Ma
override fun getCompletionStatus(): Int = COMPLETED
override fun getScoreList(): List<String> = emptyList()
override fun getScoreList(): ImmutableList<String> = persistentListOf()
override fun displayScore(track: MangaTrack): String = ""

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