mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-21 20:27:06 +03:00
parent
564a959bab
commit
f51b36a759
38 changed files with 383 additions and 442 deletions
|
@ -56,7 +56,7 @@ import tachiyomi.domain.category.anime.interactor.RenameAnimeCategory
|
||||||
import tachiyomi.domain.category.anime.interactor.ReorderAnimeCategory
|
import tachiyomi.domain.category.anime.interactor.ReorderAnimeCategory
|
||||||
import tachiyomi.domain.category.anime.interactor.ResetAnimeCategoryFlags
|
import tachiyomi.domain.category.anime.interactor.ResetAnimeCategoryFlags
|
||||||
import tachiyomi.domain.category.anime.interactor.SetAnimeCategories
|
import tachiyomi.domain.category.anime.interactor.SetAnimeCategories
|
||||||
import tachiyomi.domain.category.anime.interactor.SetDisplayModeForAnimeCategory
|
import tachiyomi.domain.category.anime.interactor.SetAnimeDisplayMode
|
||||||
import tachiyomi.domain.category.anime.interactor.SetSortModeForAnimeCategory
|
import tachiyomi.domain.category.anime.interactor.SetSortModeForAnimeCategory
|
||||||
import tachiyomi.domain.category.anime.interactor.UpdateAnimeCategory
|
import tachiyomi.domain.category.anime.interactor.UpdateAnimeCategory
|
||||||
import tachiyomi.domain.category.anime.repository.AnimeCategoryRepository
|
import tachiyomi.domain.category.anime.repository.AnimeCategoryRepository
|
||||||
|
@ -68,8 +68,8 @@ import tachiyomi.domain.category.manga.interactor.HideMangaCategory
|
||||||
import tachiyomi.domain.category.manga.interactor.RenameMangaCategory
|
import tachiyomi.domain.category.manga.interactor.RenameMangaCategory
|
||||||
import tachiyomi.domain.category.manga.interactor.ReorderMangaCategory
|
import tachiyomi.domain.category.manga.interactor.ReorderMangaCategory
|
||||||
import tachiyomi.domain.category.manga.interactor.ResetMangaCategoryFlags
|
import tachiyomi.domain.category.manga.interactor.ResetMangaCategoryFlags
|
||||||
import tachiyomi.domain.category.manga.interactor.SetDisplayModeForMangaCategory
|
|
||||||
import tachiyomi.domain.category.manga.interactor.SetMangaCategories
|
import tachiyomi.domain.category.manga.interactor.SetMangaCategories
|
||||||
|
import tachiyomi.domain.category.manga.interactor.SetMangaDisplayMode
|
||||||
import tachiyomi.domain.category.manga.interactor.SetSortModeForMangaCategory
|
import tachiyomi.domain.category.manga.interactor.SetSortModeForMangaCategory
|
||||||
import tachiyomi.domain.category.manga.interactor.UpdateMangaCategory
|
import tachiyomi.domain.category.manga.interactor.UpdateMangaCategory
|
||||||
import tachiyomi.domain.category.manga.repository.MangaCategoryRepository
|
import tachiyomi.domain.category.manga.repository.MangaCategoryRepository
|
||||||
|
@ -151,7 +151,7 @@ class DomainModule : InjektModule {
|
||||||
addFactory { GetAnimeCategories(get()) }
|
addFactory { GetAnimeCategories(get()) }
|
||||||
addFactory { GetVisibleAnimeCategories(get()) }
|
addFactory { GetVisibleAnimeCategories(get()) }
|
||||||
addFactory { ResetAnimeCategoryFlags(get(), get()) }
|
addFactory { ResetAnimeCategoryFlags(get(), get()) }
|
||||||
addFactory { SetDisplayModeForAnimeCategory(get(), get()) }
|
addFactory { SetAnimeDisplayMode(get()) }
|
||||||
addFactory { SetSortModeForAnimeCategory(get(), get()) }
|
addFactory { SetSortModeForAnimeCategory(get(), get()) }
|
||||||
addFactory { CreateAnimeCategoryWithName(get(), get()) }
|
addFactory { CreateAnimeCategoryWithName(get(), get()) }
|
||||||
addFactory { RenameAnimeCategory(get()) }
|
addFactory { RenameAnimeCategory(get()) }
|
||||||
|
@ -164,7 +164,7 @@ class DomainModule : InjektModule {
|
||||||
addFactory { GetMangaCategories(get()) }
|
addFactory { GetMangaCategories(get()) }
|
||||||
addFactory { GetVisibleMangaCategories(get()) }
|
addFactory { GetVisibleMangaCategories(get()) }
|
||||||
addFactory { ResetMangaCategoryFlags(get(), get()) }
|
addFactory { ResetMangaCategoryFlags(get(), get()) }
|
||||||
addFactory { SetDisplayModeForMangaCategory(get(), get()) }
|
addFactory { SetMangaDisplayMode(get()) }
|
||||||
addFactory { SetSortModeForMangaCategory(get(), get()) }
|
addFactory { SetSortModeForMangaCategory(get(), get()) }
|
||||||
addFactory { CreateMangaCategoryWithName(get(), get()) }
|
addFactory { CreateMangaCategoryWithName(get(), get()) }
|
||||||
addFactory { RenameMangaCategory(get()) }
|
addFactory { RenameMangaCategory(get()) }
|
||||||
|
|
|
@ -43,7 +43,7 @@ fun AnimeLibraryContent(
|
||||||
onRefresh: (Category?) -> Boolean,
|
onRefresh: (Category?) -> Boolean,
|
||||||
onGlobalSearchClicked: () -> Unit,
|
onGlobalSearchClicked: () -> Unit,
|
||||||
getNumberOfAnimeForCategory: (Category) -> Int?,
|
getNumberOfAnimeForCategory: (Category) -> Int?,
|
||||||
getDisplayModeForPage: @Composable (Int) -> LibraryDisplayMode,
|
getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>,
|
||||||
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
||||||
getAnimeLibraryForPage: (Int) -> List<AnimeLibraryItem>,
|
getAnimeLibraryForPage: (Int) -> List<AnimeLibraryItem>,
|
||||||
) {
|
) {
|
||||||
|
@ -103,7 +103,7 @@ fun AnimeLibraryContent(
|
||||||
selectedAnime = selection,
|
selectedAnime = selection,
|
||||||
searchQuery = searchQuery,
|
searchQuery = searchQuery,
|
||||||
onGlobalSearchClicked = onGlobalSearchClicked,
|
onGlobalSearchClicked = onGlobalSearchClicked,
|
||||||
getDisplayModeForPage = getDisplayModeForPage,
|
getDisplayMode = getDisplayMode,
|
||||||
getColumnsForOrientation = getColumnsForOrientation,
|
getColumnsForOrientation = getColumnsForOrientation,
|
||||||
getLibraryForPage = getAnimeLibraryForPage,
|
getLibraryForPage = getAnimeLibraryForPage,
|
||||||
onClickAnime = onClickAnime,
|
onClickAnime = onClickAnime,
|
||||||
|
|
|
@ -26,7 +26,7 @@ fun AnimeLibraryPager(
|
||||||
selectedAnime: List<LibraryAnime>,
|
selectedAnime: List<LibraryAnime>,
|
||||||
searchQuery: String?,
|
searchQuery: String?,
|
||||||
onGlobalSearchClicked: () -> Unit,
|
onGlobalSearchClicked: () -> Unit,
|
||||||
getDisplayModeForPage: @Composable (Int) -> LibraryDisplayMode,
|
getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>,
|
||||||
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
||||||
getLibraryForPage: (Int) -> List<AnimeLibraryItem>,
|
getLibraryForPage: (Int) -> List<AnimeLibraryItem>,
|
||||||
onClickAnime: (LibraryAnime) -> Unit,
|
onClickAnime: (LibraryAnime) -> Unit,
|
||||||
|
@ -54,7 +54,7 @@ fun AnimeLibraryPager(
|
||||||
return@HorizontalPager
|
return@HorizontalPager
|
||||||
}
|
}
|
||||||
|
|
||||||
val displayMode = getDisplayModeForPage(page)
|
val displayMode by getDisplayMode(page)
|
||||||
val columns by if (displayMode != LibraryDisplayMode.List) {
|
val columns by if (displayMode != LibraryDisplayMode.List) {
|
||||||
val configuration = LocalConfiguration.current
|
val configuration = LocalConfiguration.current
|
||||||
val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||||
|
|
|
@ -33,7 +33,6 @@ import tachiyomi.domain.entries.TriStateFilter
|
||||||
import tachiyomi.domain.library.anime.model.AnimeLibrarySort
|
import tachiyomi.domain.library.anime.model.AnimeLibrarySort
|
||||||
import tachiyomi.domain.library.anime.model.sort
|
import tachiyomi.domain.library.anime.model.sort
|
||||||
import tachiyomi.domain.library.model.LibraryDisplayMode
|
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||||
import tachiyomi.domain.library.model.display
|
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.presentation.core.components.CheckboxItem
|
import tachiyomi.presentation.core.components.CheckboxItem
|
||||||
import tachiyomi.presentation.core.components.HeadingItem
|
import tachiyomi.presentation.core.components.HeadingItem
|
||||||
|
@ -45,7 +44,7 @@ import tachiyomi.presentation.core.components.SortItem
|
||||||
fun AnimeLibrarySettingsDialog(
|
fun AnimeLibrarySettingsDialog(
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
screenModel: AnimeLibrarySettingsScreenModel,
|
screenModel: AnimeLibrarySettingsScreenModel,
|
||||||
category: Category,
|
category: Category?,
|
||||||
) {
|
) {
|
||||||
TabbedDialog(
|
TabbedDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
|
@ -69,7 +68,6 @@ fun AnimeLibrarySettingsDialog(
|
||||||
screenModel = screenModel,
|
screenModel = screenModel,
|
||||||
)
|
)
|
||||||
2 -> DisplayPage(
|
2 -> DisplayPage(
|
||||||
category = category,
|
|
||||||
screenModel = screenModel,
|
screenModel = screenModel,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -148,7 +146,7 @@ private fun ColumnScope.FilterPage(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ColumnScope.SortPage(
|
private fun ColumnScope.SortPage(
|
||||||
category: Category,
|
category: Category?,
|
||||||
screenModel: AnimeLibrarySettingsScreenModel,
|
screenModel: AnimeLibrarySettingsScreenModel,
|
||||||
) {
|
) {
|
||||||
val sortingMode = category.sort.type
|
val sortingMode = category.sort.type
|
||||||
|
@ -182,10 +180,10 @@ private fun ColumnScope.SortPage(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ColumnScope.DisplayPage(
|
private fun ColumnScope.DisplayPage(
|
||||||
category: Category,
|
|
||||||
screenModel: AnimeLibrarySettingsScreenModel,
|
screenModel: AnimeLibrarySettingsScreenModel,
|
||||||
) {
|
) {
|
||||||
HeadingItem(R.string.action_display_mode)
|
HeadingItem(R.string.action_display_mode)
|
||||||
|
val displayMode by screenModel.libraryPreferences.libraryDisplayMode().collectAsState()
|
||||||
listOf(
|
listOf(
|
||||||
R.string.action_display_grid to LibraryDisplayMode.CompactGrid,
|
R.string.action_display_grid to LibraryDisplayMode.CompactGrid,
|
||||||
R.string.action_display_comfortable_grid to LibraryDisplayMode.ComfortableGrid,
|
R.string.action_display_comfortable_grid to LibraryDisplayMode.ComfortableGrid,
|
||||||
|
@ -194,12 +192,12 @@ private fun ColumnScope.DisplayPage(
|
||||||
).map { (titleRes, mode) ->
|
).map { (titleRes, mode) ->
|
||||||
RadioItem(
|
RadioItem(
|
||||||
label = stringResource(titleRes),
|
label = stringResource(titleRes),
|
||||||
selected = category.display == mode,
|
selected = displayMode == mode,
|
||||||
onClick = { screenModel.setDisplayMode(category, mode) },
|
onClick = { screenModel.setDisplayMode(mode) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (category.display != LibraryDisplayMode.List) {
|
if (displayMode != LibraryDisplayMode.List) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
|
|
@ -43,7 +43,7 @@ fun MangaLibraryContent(
|
||||||
onRefresh: (Category?) -> Boolean,
|
onRefresh: (Category?) -> Boolean,
|
||||||
onGlobalSearchClicked: () -> Unit,
|
onGlobalSearchClicked: () -> Unit,
|
||||||
getNumberOfMangaForCategory: (Category) -> Int?,
|
getNumberOfMangaForCategory: (Category) -> Int?,
|
||||||
getDisplayModeForPage: @Composable (Int) -> LibraryDisplayMode,
|
getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>,
|
||||||
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
||||||
getLibraryForPage: (Int) -> List<MangaLibraryItem>,
|
getLibraryForPage: (Int) -> List<MangaLibraryItem>,
|
||||||
) {
|
) {
|
||||||
|
@ -103,7 +103,7 @@ fun MangaLibraryContent(
|
||||||
selectedManga = selection,
|
selectedManga = selection,
|
||||||
searchQuery = searchQuery,
|
searchQuery = searchQuery,
|
||||||
onGlobalSearchClicked = onGlobalSearchClicked,
|
onGlobalSearchClicked = onGlobalSearchClicked,
|
||||||
getDisplayModeForPage = getDisplayModeForPage,
|
getDisplayMode = getDisplayMode,
|
||||||
getColumnsForOrientation = getColumnsForOrientation,
|
getColumnsForOrientation = getColumnsForOrientation,
|
||||||
getLibraryForPage = getLibraryForPage,
|
getLibraryForPage = getLibraryForPage,
|
||||||
onClickManga = onClickManga,
|
onClickManga = onClickManga,
|
||||||
|
|
|
@ -35,7 +35,7 @@ fun MangaLibraryPager(
|
||||||
selectedManga: List<LibraryManga>,
|
selectedManga: List<LibraryManga>,
|
||||||
searchQuery: String?,
|
searchQuery: String?,
|
||||||
onGlobalSearchClicked: () -> Unit,
|
onGlobalSearchClicked: () -> Unit,
|
||||||
getDisplayModeForPage: @Composable (Int) -> LibraryDisplayMode,
|
getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>,
|
||||||
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
||||||
getLibraryForPage: (Int) -> List<MangaLibraryItem>,
|
getLibraryForPage: (Int) -> List<MangaLibraryItem>,
|
||||||
onClickManga: (LibraryManga) -> Unit,
|
onClickManga: (LibraryManga) -> Unit,
|
||||||
|
@ -63,7 +63,7 @@ fun MangaLibraryPager(
|
||||||
return@HorizontalPager
|
return@HorizontalPager
|
||||||
}
|
}
|
||||||
|
|
||||||
val displayMode = getDisplayModeForPage(page)
|
val displayMode by getDisplayMode(page)
|
||||||
val columns by if (displayMode != LibraryDisplayMode.List) {
|
val columns by if (displayMode != LibraryDisplayMode.List) {
|
||||||
val configuration = LocalConfiguration.current
|
val configuration = LocalConfiguration.current
|
||||||
val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||||
|
|
|
@ -33,7 +33,6 @@ import tachiyomi.domain.entries.TriStateFilter
|
||||||
import tachiyomi.domain.library.manga.model.MangaLibrarySort
|
import tachiyomi.domain.library.manga.model.MangaLibrarySort
|
||||||
import tachiyomi.domain.library.manga.model.sort
|
import tachiyomi.domain.library.manga.model.sort
|
||||||
import tachiyomi.domain.library.model.LibraryDisplayMode
|
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||||
import tachiyomi.domain.library.model.display
|
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.presentation.core.components.CheckboxItem
|
import tachiyomi.presentation.core.components.CheckboxItem
|
||||||
import tachiyomi.presentation.core.components.HeadingItem
|
import tachiyomi.presentation.core.components.HeadingItem
|
||||||
|
@ -45,7 +44,7 @@ import tachiyomi.presentation.core.components.SortItem
|
||||||
fun MangaLibrarySettingsDialog(
|
fun MangaLibrarySettingsDialog(
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
screenModel: MangaLibrarySettingsScreenModel,
|
screenModel: MangaLibrarySettingsScreenModel,
|
||||||
category: Category,
|
category: Category?,
|
||||||
) {
|
) {
|
||||||
TabbedDialog(
|
TabbedDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
|
@ -69,7 +68,6 @@ fun MangaLibrarySettingsDialog(
|
||||||
screenModel = screenModel,
|
screenModel = screenModel,
|
||||||
)
|
)
|
||||||
2 -> DisplayPage(
|
2 -> DisplayPage(
|
||||||
category = category,
|
|
||||||
screenModel = screenModel,
|
screenModel = screenModel,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -148,7 +146,7 @@ private fun ColumnScope.FilterPage(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ColumnScope.SortPage(
|
private fun ColumnScope.SortPage(
|
||||||
category: Category,
|
category: Category?,
|
||||||
screenModel: MangaLibrarySettingsScreenModel,
|
screenModel: MangaLibrarySettingsScreenModel,
|
||||||
) {
|
) {
|
||||||
val sortingMode = category.sort.type
|
val sortingMode = category.sort.type
|
||||||
|
@ -181,10 +179,10 @@ private fun ColumnScope.SortPage(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ColumnScope.DisplayPage(
|
private fun ColumnScope.DisplayPage(
|
||||||
category: Category,
|
|
||||||
screenModel: MangaLibrarySettingsScreenModel,
|
screenModel: MangaLibrarySettingsScreenModel,
|
||||||
) {
|
) {
|
||||||
HeadingItem(R.string.action_display_mode)
|
HeadingItem(R.string.action_display_mode)
|
||||||
|
val displayMode by screenModel.libraryPreferences.libraryDisplayMode().collectAsState()
|
||||||
listOf(
|
listOf(
|
||||||
R.string.action_display_grid to LibraryDisplayMode.CompactGrid,
|
R.string.action_display_grid to LibraryDisplayMode.CompactGrid,
|
||||||
R.string.action_display_comfortable_grid to LibraryDisplayMode.ComfortableGrid,
|
R.string.action_display_comfortable_grid to LibraryDisplayMode.ComfortableGrid,
|
||||||
|
@ -193,12 +191,12 @@ private fun ColumnScope.DisplayPage(
|
||||||
).map { (titleRes, mode) ->
|
).map { (titleRes, mode) ->
|
||||||
RadioItem(
|
RadioItem(
|
||||||
label = stringResource(titleRes),
|
label = stringResource(titleRes),
|
||||||
selected = category.display == mode,
|
selected = displayMode == mode,
|
||||||
onClick = { screenModel.setDisplayMode(category, mode) },
|
onClick = { screenModel.setDisplayMode(mode) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (category.display != LibraryDisplayMode.List) {
|
if (displayMode != LibraryDisplayMode.List) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
|
|
@ -3,6 +3,7 @@ package eu.kanade.presentation.more.settings.screen
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.webkit.WebStorage
|
import android.webkit.WebStorage
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
|
@ -73,6 +74,7 @@ import uy.kohesive.injekt.api.get
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
object SettingsAdvancedScreen : SearchableSettings {
|
object SettingsAdvancedScreen : SearchableSettings {
|
||||||
|
|
||||||
@ReadOnlyComposable
|
@ReadOnlyComposable
|
||||||
@Composable
|
@Composable
|
||||||
@StringRes
|
@StringRes
|
||||||
|
@ -87,44 +89,65 @@ object SettingsAdvancedScreen : SearchableSettings {
|
||||||
val basePreferences = remember { Injekt.get<BasePreferences>() }
|
val basePreferences = remember { Injekt.get<BasePreferences>() }
|
||||||
val networkPreferences = remember { Injekt.get<NetworkPreferences>() }
|
val networkPreferences = remember { Injekt.get<NetworkPreferences>() }
|
||||||
|
|
||||||
return listOf(
|
return buildList {
|
||||||
Preference.PreferenceItem.SwitchPreference(
|
addAll(
|
||||||
pref = basePreferences.acraEnabled(),
|
listOf(
|
||||||
title = stringResource(R.string.pref_enable_acra),
|
Preference.PreferenceItem.SwitchPreference(
|
||||||
subtitle = stringResource(R.string.pref_acra_summary),
|
pref = basePreferences.acraEnabled(),
|
||||||
enabled = isPreviewBuildType || isReleaseBuildType,
|
title = stringResource(R.string.pref_enable_acra),
|
||||||
),
|
subtitle = stringResource(R.string.pref_acra_summary),
|
||||||
Preference.PreferenceItem.TextPreference(
|
enabled = isPreviewBuildType || isReleaseBuildType,
|
||||||
title = stringResource(R.string.pref_dump_crash_logs),
|
),
|
||||||
subtitle = stringResource(R.string.pref_dump_crash_logs_summary),
|
Preference.PreferenceItem.TextPreference(
|
||||||
onClick = {
|
title = stringResource(R.string.pref_dump_crash_logs),
|
||||||
scope.launch {
|
subtitle = stringResource(R.string.pref_dump_crash_logs_summary),
|
||||||
CrashLogUtil(context).dumpLogs()
|
onClick = {
|
||||||
}
|
scope.launch {
|
||||||
},
|
CrashLogUtil(context).dumpLogs()
|
||||||
),
|
}
|
||||||
Preference.PreferenceItem.SwitchPreference(
|
},
|
||||||
pref = networkPreferences.verboseLogging(),
|
),
|
||||||
title = stringResource(R.string.pref_verbose_logging),
|
Preference.PreferenceItem.SwitchPreference(
|
||||||
subtitle = stringResource(R.string.pref_verbose_logging_summary),
|
pref = networkPreferences.verboseLogging(),
|
||||||
onValueChanged = {
|
title = stringResource(R.string.pref_verbose_logging),
|
||||||
context.toast(R.string.requires_app_restart)
|
subtitle = stringResource(R.string.pref_verbose_logging_summary),
|
||||||
true
|
onValueChanged = {
|
||||||
},
|
context.toast(R.string.requires_app_restart)
|
||||||
),
|
true
|
||||||
Preference.PreferenceItem.TextPreference(
|
},
|
||||||
title = stringResource(R.string.pref_debug_info),
|
),
|
||||||
onClick = { navigator.push(DebugInfoScreen) },
|
Preference.PreferenceItem.TextPreference(
|
||||||
),
|
title = stringResource(R.string.pref_debug_info),
|
||||||
getBackgroundActivityGroup(),
|
onClick = { navigator.push(DebugInfoScreen) },
|
||||||
getDataGroup(),
|
),
|
||||||
getNetworkGroup(networkPreferences = networkPreferences),
|
),
|
||||||
getLibraryGroup(),
|
)
|
||||||
getExtensionsGroup(basePreferences = basePreferences),
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
// SY -->
|
add(
|
||||||
getDataSaverGroup(),
|
Preference.PreferenceItem.TextPreference(
|
||||||
// SY <--
|
title = stringResource(R.string.pref_manage_notifications),
|
||||||
)
|
onClick = {
|
||||||
|
val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
|
||||||
|
putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
|
||||||
|
}
|
||||||
|
context.startActivity(intent)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
addAll(
|
||||||
|
listOf(
|
||||||
|
getBackgroundActivityGroup(),
|
||||||
|
getDataGroup(),
|
||||||
|
getNetworkGroup(networkPreferences = networkPreferences),
|
||||||
|
getLibraryGroup(),
|
||||||
|
getExtensionsGroup(basePreferences = basePreferences),
|
||||||
|
// SY -->
|
||||||
|
getDataSaverGroup(),
|
||||||
|
// SY <--
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
@ -4,14 +4,18 @@ import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.ReadOnlyComposable
|
import androidx.compose.runtime.ReadOnlyComposable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.os.LocaleListCompat
|
||||||
import eu.kanade.domain.ui.UiPreferences
|
import eu.kanade.domain.ui.UiPreferences
|
||||||
import eu.kanade.domain.ui.model.TabletUiMode
|
import eu.kanade.domain.ui.model.TabletUiMode
|
||||||
import eu.kanade.domain.ui.model.ThemeMode
|
import eu.kanade.domain.ui.model.ThemeMode
|
||||||
|
@ -19,10 +23,14 @@ import eu.kanade.domain.ui.model.setAppCompatDelegateThemeMode
|
||||||
import eu.kanade.presentation.more.settings.Preference
|
import eu.kanade.presentation.more.settings.Preference
|
||||||
import eu.kanade.presentation.util.collectAsState
|
import eu.kanade.presentation.util.collectAsState
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.ui.home.HomeScreen
|
||||||
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.drop
|
import kotlinx.coroutines.flow.drop
|
||||||
import kotlinx.coroutines.flow.merge
|
import kotlinx.coroutines.flow.merge
|
||||||
|
import org.xmlpull.v1.XmlPullParser
|
||||||
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
@ -103,9 +111,61 @@ object SettingsAppearanceScreen : SearchableSettings {
|
||||||
context: Context,
|
context: Context,
|
||||||
uiPreferences: UiPreferences,
|
uiPreferences: UiPreferences,
|
||||||
): Preference.PreferenceGroup {
|
): Preference.PreferenceGroup {
|
||||||
|
val langs = remember { getLangs(context) }
|
||||||
|
var currentLanguage by remember { mutableStateOf(AppCompatDelegate.getApplicationLocales().get(0)?.toLanguageTag() ?: "") }
|
||||||
|
|
||||||
|
LaunchedEffect(currentLanguage) {
|
||||||
|
val locale = if (currentLanguage.isEmpty()) {
|
||||||
|
LocaleListCompat.getEmptyLocaleList()
|
||||||
|
} else {
|
||||||
|
LocaleListCompat.forLanguageTags(currentLanguage)
|
||||||
|
}
|
||||||
|
AppCompatDelegate.setApplicationLocales(locale)
|
||||||
|
}
|
||||||
|
|
||||||
|
val libraryPrefs = remember { Injekt.get<LibraryPreferences>() }
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
libraryPrefs.bottomNavStyle().changes()
|
||||||
|
.drop(1)
|
||||||
|
.collectLatest { value ->
|
||||||
|
HomeScreen.tabs = when (value) {
|
||||||
|
0 -> HomeScreen.tabsNoHistory
|
||||||
|
1 -> HomeScreen.tabsNoUpdates
|
||||||
|
else -> HomeScreen.tabsNoManga
|
||||||
|
}
|
||||||
|
(context as? Activity)?.let {
|
||||||
|
ActivityCompat.recreate(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Preference.PreferenceGroup(
|
return Preference.PreferenceGroup(
|
||||||
title = stringResource(R.string.pref_category_display),
|
title = stringResource(R.string.pref_category_display),
|
||||||
preferenceItems = listOf(
|
preferenceItems = listOf(
|
||||||
|
Preference.PreferenceItem.ListPreference(
|
||||||
|
pref = libraryPrefs.bottomNavStyle(),
|
||||||
|
title = stringResource(R.string.pref_bottom_nav_style),
|
||||||
|
entries = mapOf(
|
||||||
|
0 to stringResource(R.string.pref_bottom_nav_no_history),
|
||||||
|
1 to stringResource(R.string.pref_bottom_nav_no_updates),
|
||||||
|
2 to stringResource(R.string.pref_bottom_nav_no_manga),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Preference.PreferenceItem.SwitchPreference(
|
||||||
|
pref = libraryPrefs.isDefaultHomeTabLibraryManga(),
|
||||||
|
title = stringResource(R.string.pref_default_home_tab_library),
|
||||||
|
enabled = libraryPrefs.bottomNavStyle().get() != 2,
|
||||||
|
),
|
||||||
|
Preference.PreferenceItem.BasicListPreference(
|
||||||
|
value = currentLanguage,
|
||||||
|
title = stringResource(R.string.pref_app_language),
|
||||||
|
entries = langs,
|
||||||
|
onValueChanged = { newValue ->
|
||||||
|
currentLanguage = newValue
|
||||||
|
true
|
||||||
|
},
|
||||||
|
),
|
||||||
Preference.PreferenceItem.ListPreference(
|
Preference.PreferenceItem.ListPreference(
|
||||||
pref = uiPreferences.tabletUiMode(),
|
pref = uiPreferences.tabletUiMode(),
|
||||||
title = stringResource(R.string.pref_tablet_ui_mode),
|
title = stringResource(R.string.pref_tablet_ui_mode),
|
||||||
|
@ -146,6 +206,31 @@ object SettingsAppearanceScreen : SearchableSettings {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getLangs(context: Context): Map<String, String> {
|
||||||
|
val langs = mutableListOf<Pair<String, String>>()
|
||||||
|
val parser = context.resources.getXml(R.xml.locales_config)
|
||||||
|
var eventType = parser.eventType
|
||||||
|
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||||
|
if (eventType == XmlPullParser.START_TAG && parser.name == "locale") {
|
||||||
|
for (i in 0 until parser.attributeCount) {
|
||||||
|
if (parser.getAttributeName(i) == "name") {
|
||||||
|
val langTag = parser.getAttributeValue(i)
|
||||||
|
val displayName = LocaleHelper.getDisplayName(langTag)
|
||||||
|
if (displayName.isNotEmpty()) {
|
||||||
|
langs.add(Pair(langTag, displayName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eventType = parser.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
langs.sortBy { it.second }
|
||||||
|
langs.add(0, Pair("", context.getString(R.string.label_default)))
|
||||||
|
|
||||||
|
return langs.toMap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val DateFormats = listOf(
|
private val DateFormats = listOf(
|
||||||
|
|
|
@ -1,149 +0,0 @@
|
||||||
package eu.kanade.presentation.more.settings.screen
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Build
|
|
||||||
import android.provider.Settings
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.ReadOnlyComposable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.core.app.ActivityCompat
|
|
||||||
import androidx.core.os.LocaleListCompat
|
|
||||||
import eu.kanade.presentation.more.settings.Preference
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.ui.home.HomeScreen
|
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
|
||||||
import kotlinx.coroutines.flow.drop
|
|
||||||
import org.xmlpull.v1.XmlPullParser
|
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
|
||||||
import uy.kohesive.injekt.Injekt
|
|
||||||
import uy.kohesive.injekt.api.get
|
|
||||||
|
|
||||||
object SettingsGeneralScreen : SearchableSettings {
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
@ReadOnlyComposable
|
|
||||||
@StringRes
|
|
||||||
override fun getTitleRes() = R.string.pref_category_general
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
override fun getPreferences(): List<Preference> {
|
|
||||||
val libraryPrefs = remember { Injekt.get<LibraryPreferences>() }
|
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
libraryPrefs.bottomNavStyle().changes()
|
|
||||||
.drop(1)
|
|
||||||
.collectLatest { value ->
|
|
||||||
HomeScreen.tabs = when (value) {
|
|
||||||
0 -> HomeScreen.tabsNoHistory
|
|
||||||
1 -> HomeScreen.tabsNoUpdates
|
|
||||||
else -> HomeScreen.tabsNoManga
|
|
||||||
}
|
|
||||||
(context as? Activity)?.let {
|
|
||||||
ActivityCompat.recreate(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val langs = remember { getLangs(context) }
|
|
||||||
var currentLanguage by remember { mutableStateOf(AppCompatDelegate.getApplicationLocales().get(0)?.toLanguageTag() ?: "") }
|
|
||||||
|
|
||||||
return buildList {
|
|
||||||
add(
|
|
||||||
Preference.PreferenceItem.ListPreference(
|
|
||||||
pref = libraryPrefs.bottomNavStyle(),
|
|
||||||
title = stringResource(R.string.pref_bottom_nav_style),
|
|
||||||
entries = mapOf(
|
|
||||||
0 to stringResource(R.string.pref_bottom_nav_no_history),
|
|
||||||
1 to stringResource(R.string.pref_bottom_nav_no_updates),
|
|
||||||
2 to stringResource(R.string.pref_bottom_nav_no_manga),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
add(
|
|
||||||
Preference.PreferenceItem.SwitchPreference(
|
|
||||||
pref = libraryPrefs.isDefaultHomeTabLibraryManga(),
|
|
||||||
title = stringResource(R.string.pref_default_home_tab_library),
|
|
||||||
enabled = libraryPrefs.bottomNavStyle().get() != 2,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
add(
|
|
||||||
Preference.PreferenceItem.SwitchPreference(
|
|
||||||
pref = libraryPrefs.newShowUpdatesCount(),
|
|
||||||
title = stringResource(R.string.pref_library_update_show_tab_badge),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
add(
|
|
||||||
Preference.PreferenceItem.TextPreference(
|
|
||||||
title = stringResource(R.string.pref_manage_notifications),
|
|
||||||
onClick = {
|
|
||||||
val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
|
|
||||||
putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
|
|
||||||
}
|
|
||||||
context.startActivity(intent)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
add(
|
|
||||||
Preference.PreferenceItem.BasicListPreference(
|
|
||||||
value = currentLanguage,
|
|
||||||
title = stringResource(R.string.pref_app_language),
|
|
||||||
entries = langs,
|
|
||||||
onValueChanged = { newValue ->
|
|
||||||
currentLanguage = newValue
|
|
||||||
true
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
LaunchedEffect(currentLanguage) {
|
|
||||||
val locale = if (currentLanguage.isEmpty()) {
|
|
||||||
LocaleListCompat.getEmptyLocaleList()
|
|
||||||
} else {
|
|
||||||
LocaleListCompat.forLanguageTags(currentLanguage)
|
|
||||||
}
|
|
||||||
AppCompatDelegate.setApplicationLocales(locale)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getLangs(context: Context): Map<String, String> {
|
|
||||||
val langs = mutableListOf<Pair<String, String>>()
|
|
||||||
val parser = context.resources.getXml(R.xml.locales_config)
|
|
||||||
var eventType = parser.eventType
|
|
||||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
|
||||||
if (eventType == XmlPullParser.START_TAG && parser.name == "locale") {
|
|
||||||
for (i in 0 until parser.attributeCount) {
|
|
||||||
if (parser.getAttributeName(i) == "name") {
|
|
||||||
val langTag = parser.getAttributeValue(i)
|
|
||||||
val displayName = LocaleHelper.getDisplayName(langTag)
|
|
||||||
if (displayName.isNotEmpty()) {
|
|
||||||
langs.add(Pair(langTag, displayName))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eventType = parser.next()
|
|
||||||
}
|
|
||||||
|
|
||||||
langs.sortBy { it.second }
|
|
||||||
langs.add(0, Pair("", context.getString(R.string.label_default)))
|
|
||||||
|
|
||||||
return langs.toMap()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -365,7 +365,6 @@ object SettingsLibraryScreen : SearchableSettings {
|
||||||
Preference.PreferenceItem.InfoPreference(
|
Preference.PreferenceItem.InfoPreference(
|
||||||
title = stringResource(R.string.pref_update_release_grace_period_info),
|
title = stringResource(R.string.pref_update_release_grace_period_info),
|
||||||
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateMangaRestriction && isDevFlavor },
|
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateMangaRestriction && isDevFlavor },
|
||||||
|
|
||||||
Preference.PreferenceItem.TextPreference(
|
Preference.PreferenceItem.TextPreference(
|
||||||
title = stringResource(R.string.pref_update_anime_release_grace_period),
|
title = stringResource(R.string.pref_update_anime_release_grace_period),
|
||||||
subtitle = listOf(
|
subtitle = listOf(
|
||||||
|
@ -377,6 +376,11 @@ object SettingsLibraryScreen : SearchableSettings {
|
||||||
Preference.PreferenceItem.InfoPreference(
|
Preference.PreferenceItem.InfoPreference(
|
||||||
title = stringResource(R.string.pref_update_release_grace_period_info),
|
title = stringResource(R.string.pref_update_release_grace_period_info),
|
||||||
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateAnimeRestriction && isDevFlavor },
|
).takeIf { ENTRY_OUTSIDE_RELEASE_PERIOD in libraryUpdateAnimeRestriction && isDevFlavor },
|
||||||
|
|
||||||
|
Preference.PreferenceItem.SwitchPreference(
|
||||||
|
pref = libraryPreferences.newShowUpdatesCount(),
|
||||||
|
title = stringResource(R.string.pref_library_update_show_tab_badge),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import androidx.compose.material.icons.outlined.Search
|
||||||
import androidx.compose.material.icons.outlined.Security
|
import androidx.compose.material.icons.outlined.Security
|
||||||
import androidx.compose.material.icons.outlined.SettingsBackupRestore
|
import androidx.compose.material.icons.outlined.SettingsBackupRestore
|
||||||
import androidx.compose.material.icons.outlined.Sync
|
import androidx.compose.material.icons.outlined.Sync
|
||||||
import androidx.compose.material.icons.outlined.Tune
|
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
@ -187,12 +186,6 @@ object SettingsMainScreen : Screen() {
|
||||||
)
|
)
|
||||||
|
|
||||||
private val items = listOf(
|
private val items = listOf(
|
||||||
Item(
|
|
||||||
titleRes = R.string.pref_category_general,
|
|
||||||
subtitleRes = R.string.pref_general_summary,
|
|
||||||
icon = Icons.Outlined.Tune,
|
|
||||||
screen = SettingsGeneralScreen,
|
|
||||||
),
|
|
||||||
Item(
|
Item(
|
||||||
titleRes = R.string.pref_category_appearance,
|
titleRes = R.string.pref_category_appearance,
|
||||||
subtitleRes = R.string.pref_appearance_summary,
|
subtitleRes = R.string.pref_appearance_summary,
|
||||||
|
|
|
@ -283,7 +283,6 @@ private fun getLocalizedBreadcrumb(path: String, node: String?): String {
|
||||||
}
|
}
|
||||||
|
|
||||||
private val settingScreens = listOf(
|
private val settingScreens = listOf(
|
||||||
SettingsGeneralScreen,
|
|
||||||
SettingsAppearanceScreen,
|
SettingsAppearanceScreen,
|
||||||
SettingsLibraryScreen,
|
SettingsLibraryScreen,
|
||||||
SettingsReaderScreen,
|
SettingsReaderScreen,
|
||||||
|
|
|
@ -32,7 +32,6 @@ object SettingsSecurityScreen : SearchableSettings {
|
||||||
val authSupported = remember { context.isAuthenticationSupported() }
|
val authSupported = remember { context.isAuthenticationSupported() }
|
||||||
|
|
||||||
val useAuthPref = securityPreferences.useAuthenticator()
|
val useAuthPref = securityPreferences.useAuthenticator()
|
||||||
|
|
||||||
val useAuth by useAuthPref.collectAsState()
|
val useAuth by useAuthPref.collectAsState()
|
||||||
|
|
||||||
return listOf(
|
return listOf(
|
||||||
|
|
|
@ -58,6 +58,7 @@ import tachiyomi.domain.items.episode.model.Episode
|
||||||
import tachiyomi.domain.library.anime.LibraryAnime
|
import tachiyomi.domain.library.anime.LibraryAnime
|
||||||
import tachiyomi.domain.library.anime.model.AnimeLibrarySort
|
import tachiyomi.domain.library.anime.model.AnimeLibrarySort
|
||||||
import tachiyomi.domain.library.anime.model.sort
|
import tachiyomi.domain.library.anime.model.sort
|
||||||
|
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.domain.source.anime.service.AnimeSourceManager
|
import tachiyomi.domain.source.anime.service.AnimeSourceManager
|
||||||
import tachiyomi.domain.track.anime.interactor.GetTracksPerAnime
|
import tachiyomi.domain.track.anime.interactor.GetTracksPerAnime
|
||||||
|
@ -524,6 +525,10 @@ class AnimeLibraryScreenModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getDisplayMode(): PreferenceMutableState<LibraryDisplayMode> {
|
||||||
|
return libraryPreferences.libraryDisplayMode().asState(coroutineScope)
|
||||||
|
}
|
||||||
|
|
||||||
fun getColumnsPreferenceForCurrentOrientation(isLandscape: Boolean): PreferenceMutableState<Int> {
|
fun getColumnsPreferenceForCurrentOrientation(isLandscape: Boolean): PreferenceMutableState<Int> {
|
||||||
return (if (isLandscape) libraryPreferences.animeLandscapeColumns() else libraryPreferences.animePortraitColumns()).asState(coroutineScope)
|
return (if (isLandscape) libraryPreferences.animeLandscapeColumns() else libraryPreferences.animePortraitColumns()).asState(coroutineScope)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,7 @@ import eu.kanade.tachiyomi.util.preference.toggle
|
||||||
import tachiyomi.core.preference.Preference
|
import tachiyomi.core.preference.Preference
|
||||||
import tachiyomi.core.preference.getAndSet
|
import tachiyomi.core.preference.getAndSet
|
||||||
import tachiyomi.core.util.lang.launchIO
|
import tachiyomi.core.util.lang.launchIO
|
||||||
import tachiyomi.domain.category.anime.interactor.GetAnimeCategories
|
import tachiyomi.domain.category.anime.interactor.SetAnimeDisplayMode
|
||||||
import tachiyomi.domain.category.anime.interactor.SetDisplayModeForAnimeCategory
|
|
||||||
import tachiyomi.domain.category.anime.interactor.SetSortModeForAnimeCategory
|
import tachiyomi.domain.category.anime.interactor.SetSortModeForAnimeCategory
|
||||||
import tachiyomi.domain.category.model.Category
|
import tachiyomi.domain.category.model.Category
|
||||||
import tachiyomi.domain.entries.TriStateFilter
|
import tachiyomi.domain.entries.TriStateFilter
|
||||||
|
@ -22,8 +21,7 @@ import uy.kohesive.injekt.api.get
|
||||||
class AnimeLibrarySettingsScreenModel(
|
class AnimeLibrarySettingsScreenModel(
|
||||||
val preferences: BasePreferences = Injekt.get(),
|
val preferences: BasePreferences = Injekt.get(),
|
||||||
val libraryPreferences: LibraryPreferences = Injekt.get(),
|
val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||||
private val getCategories: GetAnimeCategories = Injekt.get(),
|
private val setAnimeDisplayMode: SetAnimeDisplayMode = Injekt.get(),
|
||||||
private val setDisplayModeForCategory: SetDisplayModeForAnimeCategory = Injekt.get(),
|
|
||||||
private val setSortModeForCategory: SetSortModeForAnimeCategory = Injekt.get(),
|
private val setSortModeForCategory: SetSortModeForAnimeCategory = Injekt.get(),
|
||||||
private val trackManager: TrackManager = Injekt.get(),
|
private val trackManager: TrackManager = Injekt.get(),
|
||||||
) : ScreenModel {
|
) : ScreenModel {
|
||||||
|
@ -45,13 +43,11 @@ class AnimeLibrarySettingsScreenModel(
|
||||||
toggleFilter { libraryPreferences.filterTrackedAnime(id) }
|
toggleFilter { libraryPreferences.filterTrackedAnime(id) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setDisplayMode(category: Category, mode: LibraryDisplayMode) {
|
fun setDisplayMode(mode: LibraryDisplayMode) {
|
||||||
coroutineScope.launchIO {
|
setAnimeDisplayMode.await(mode)
|
||||||
setDisplayModeForCategory.await(category, mode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSort(category: Category, mode: AnimeLibrarySort.Type, direction: AnimeLibrarySort.Direction) {
|
fun setSort(category: Category?, mode: AnimeLibrarySort.Type, direction: AnimeLibrarySort.Direction) {
|
||||||
coroutineScope.launchIO {
|
coroutineScope.launchIO {
|
||||||
setSortModeForCategory.await(category, mode, direction)
|
setSortModeForCategory.await(category, mode, direction)
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,6 @@ import tachiyomi.domain.category.model.Category
|
||||||
import tachiyomi.domain.entries.anime.model.Anime
|
import tachiyomi.domain.entries.anime.model.Anime
|
||||||
import tachiyomi.domain.items.episode.model.Episode
|
import tachiyomi.domain.items.episode.model.Episode
|
||||||
import tachiyomi.domain.library.anime.LibraryAnime
|
import tachiyomi.domain.library.anime.LibraryAnime
|
||||||
import tachiyomi.domain.library.model.display
|
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.screens.EmptyScreen
|
import tachiyomi.presentation.core.screens.EmptyScreen
|
||||||
|
@ -212,7 +211,7 @@ object AnimeLibraryTab : Tab() {
|
||||||
navigator.push(GlobalAnimeSearchScreen(screenModel.state.value.searchQuery ?: ""))
|
navigator.push(GlobalAnimeSearchScreen(screenModel.state.value.searchQuery ?: ""))
|
||||||
},
|
},
|
||||||
getNumberOfAnimeForCategory = { state.getAnimeCountForCategory(it) },
|
getNumberOfAnimeForCategory = { state.getAnimeCountForCategory(it) },
|
||||||
getDisplayModeForPage = { state.categories[it].display },
|
getDisplayMode = { screenModel.getDisplayMode() },
|
||||||
getColumnsForOrientation = { screenModel.getColumnsPreferenceForCurrentOrientation(it) },
|
getColumnsForOrientation = { screenModel.getColumnsPreferenceForCurrentOrientation(it) },
|
||||||
) { state.getAnimelibItemsByPage(it) }
|
) { state.getAnimelibItemsByPage(it) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ import tachiyomi.domain.items.chapter.model.Chapter
|
||||||
import tachiyomi.domain.library.manga.LibraryManga
|
import tachiyomi.domain.library.manga.LibraryManga
|
||||||
import tachiyomi.domain.library.manga.model.MangaLibrarySort
|
import tachiyomi.domain.library.manga.model.MangaLibrarySort
|
||||||
import tachiyomi.domain.library.manga.model.sort
|
import tachiyomi.domain.library.manga.model.sort
|
||||||
|
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.domain.source.manga.service.MangaSourceManager
|
import tachiyomi.domain.source.manga.service.MangaSourceManager
|
||||||
import tachiyomi.domain.track.manga.interactor.GetTracksPerManga
|
import tachiyomi.domain.track.manga.interactor.GetTracksPerManga
|
||||||
|
@ -518,6 +519,10 @@ class MangaLibraryScreenModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getDisplayMode(): PreferenceMutableState<LibraryDisplayMode> {
|
||||||
|
return libraryPreferences.libraryDisplayMode().asState(coroutineScope)
|
||||||
|
}
|
||||||
|
|
||||||
fun getColumnsPreferenceForCurrentOrientation(isLandscape: Boolean): PreferenceMutableState<Int> {
|
fun getColumnsPreferenceForCurrentOrientation(isLandscape: Boolean): PreferenceMutableState<Int> {
|
||||||
return (if (isLandscape) libraryPreferences.mangaLandscapeColumns() else libraryPreferences.mangaPortraitColumns()).asState(coroutineScope)
|
return (if (isLandscape) libraryPreferences.mangaLandscapeColumns() else libraryPreferences.mangaPortraitColumns()).asState(coroutineScope)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,7 @@ import eu.kanade.tachiyomi.util.preference.toggle
|
||||||
import tachiyomi.core.preference.Preference
|
import tachiyomi.core.preference.Preference
|
||||||
import tachiyomi.core.preference.getAndSet
|
import tachiyomi.core.preference.getAndSet
|
||||||
import tachiyomi.core.util.lang.launchIO
|
import tachiyomi.core.util.lang.launchIO
|
||||||
import tachiyomi.domain.category.manga.interactor.GetMangaCategories
|
import tachiyomi.domain.category.manga.interactor.SetMangaDisplayMode
|
||||||
import tachiyomi.domain.category.manga.interactor.SetDisplayModeForMangaCategory
|
|
||||||
import tachiyomi.domain.category.manga.interactor.SetSortModeForMangaCategory
|
import tachiyomi.domain.category.manga.interactor.SetSortModeForMangaCategory
|
||||||
import tachiyomi.domain.category.model.Category
|
import tachiyomi.domain.category.model.Category
|
||||||
import tachiyomi.domain.entries.TriStateFilter
|
import tachiyomi.domain.entries.TriStateFilter
|
||||||
|
@ -22,8 +21,7 @@ import uy.kohesive.injekt.api.get
|
||||||
class MangaLibrarySettingsScreenModel(
|
class MangaLibrarySettingsScreenModel(
|
||||||
val preferences: BasePreferences = Injekt.get(),
|
val preferences: BasePreferences = Injekt.get(),
|
||||||
val libraryPreferences: LibraryPreferences = Injekt.get(),
|
val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||||
private val getCategories: GetMangaCategories = Injekt.get(),
|
private val setMangaDisplayMode: SetMangaDisplayMode = Injekt.get(),
|
||||||
private val setDisplayModeForCategory: SetDisplayModeForMangaCategory = Injekt.get(),
|
|
||||||
private val setSortModeForCategory: SetSortModeForMangaCategory = Injekt.get(),
|
private val setSortModeForCategory: SetSortModeForMangaCategory = Injekt.get(),
|
||||||
private val trackManager: TrackManager = Injekt.get(),
|
private val trackManager: TrackManager = Injekt.get(),
|
||||||
) : ScreenModel {
|
) : ScreenModel {
|
||||||
|
@ -45,13 +43,11 @@ class MangaLibrarySettingsScreenModel(
|
||||||
toggleFilter { libraryPreferences.filterTrackedManga(id) }
|
toggleFilter { libraryPreferences.filterTrackedManga(id) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setDisplayMode(category: Category, mode: LibraryDisplayMode) {
|
fun setDisplayMode(mode: LibraryDisplayMode) {
|
||||||
coroutineScope.launchIO {
|
setMangaDisplayMode.await(mode)
|
||||||
setDisplayModeForCategory.await(category, mode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSort(category: Category, mode: MangaLibrarySort.Type, direction: MangaLibrarySort.Direction) {
|
fun setSort(category: Category?, mode: MangaLibrarySort.Type, direction: MangaLibrarySort.Direction) {
|
||||||
coroutineScope.launchIO {
|
coroutineScope.launchIO {
|
||||||
setSortModeForCategory.await(category, mode, direction)
|
setSortModeForCategory.await(category, mode, direction)
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ import tachiyomi.core.util.lang.launchIO
|
||||||
import tachiyomi.domain.category.model.Category
|
import tachiyomi.domain.category.model.Category
|
||||||
import tachiyomi.domain.entries.manga.model.Manga
|
import tachiyomi.domain.entries.manga.model.Manga
|
||||||
import tachiyomi.domain.library.manga.LibraryManga
|
import tachiyomi.domain.library.manga.LibraryManga
|
||||||
import tachiyomi.domain.library.model.display
|
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.screens.EmptyScreen
|
import tachiyomi.presentation.core.screens.EmptyScreen
|
||||||
|
@ -213,7 +212,7 @@ object MangaLibraryTab : Tab() {
|
||||||
navigator.push(GlobalMangaSearchScreen(screenModel.state.value.searchQuery ?: ""))
|
navigator.push(GlobalMangaSearchScreen(screenModel.state.value.searchQuery ?: ""))
|
||||||
},
|
},
|
||||||
getNumberOfMangaForCategory = { state.getMangaCountForCategory(it) },
|
getNumberOfMangaForCategory = { state.getMangaCountForCategory(it) },
|
||||||
getDisplayModeForPage = { state.categories[it].display },
|
getDisplayMode = { screenModel.getDisplayMode() },
|
||||||
getColumnsForOrientation = { screenModel.getColumnsPreferenceForCurrentOrientation(it) },
|
getColumnsForOrientation = { screenModel.getColumnsPreferenceForCurrentOrientation(it) },
|
||||||
) { state.getLibraryItemsByPage(it) }
|
) { state.getLibraryItemsByPage(it) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.view.Gravity
|
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
@ -24,7 +23,6 @@ import android.view.View.LAYER_TYPE_HARDWARE
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.view.animation.Animation
|
import android.view.animation.Animation
|
||||||
import android.view.animation.AnimationUtils
|
import android.view.animation.AnimationUtils
|
||||||
import android.widget.FrameLayout
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
@ -36,7 +34,6 @@ import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.WindowInsetsControllerCompat
|
import androidx.core.view.WindowInsetsControllerCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updateLayoutParams
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||||
import com.google.android.material.internal.ToolbarUtils
|
import com.google.android.material.internal.ToolbarUtils
|
||||||
|
@ -70,7 +67,6 @@ import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
|
||||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
||||||
import eu.kanade.tachiyomi.util.preference.toggle
|
import eu.kanade.tachiyomi.util.preference.toggle
|
||||||
import eu.kanade.tachiyomi.util.system.applySystemAnimatorScale
|
import eu.kanade.tachiyomi.util.system.applySystemAnimatorScale
|
||||||
import eu.kanade.tachiyomi.util.system.createReaderThemeContext
|
|
||||||
import eu.kanade.tachiyomi.util.system.hasDisplayCutout
|
import eu.kanade.tachiyomi.util.system.hasDisplayCutout
|
||||||
import eu.kanade.tachiyomi.util.system.isNightMode
|
import eu.kanade.tachiyomi.util.system.isNightMode
|
||||||
import eu.kanade.tachiyomi.util.system.toShareIntent
|
import eu.kanade.tachiyomi.util.system.toShareIntent
|
||||||
|
@ -662,12 +658,7 @@ class ReaderActivity : BaseActivity() {
|
||||||
|
|
||||||
supportActionBar?.title = manga.title
|
supportActionBar?.title = manga.title
|
||||||
|
|
||||||
val loadingIndicatorContext = createReaderThemeContext()
|
loadingIndicator = ReaderProgressIndicator(this)
|
||||||
loadingIndicator = ReaderProgressIndicator(loadingIndicatorContext).apply {
|
|
||||||
updateLayoutParams<FrameLayout.LayoutParams> {
|
|
||||||
gravity = Gravity.CENTER
|
|
||||||
}
|
|
||||||
}
|
|
||||||
binding.readerContainer.addView(loadingIndicator)
|
binding.readerContainer.addView(loadingIndicator)
|
||||||
|
|
||||||
startPostponedEnterTransition()
|
startPostponedEnterTransition()
|
||||||
|
|
|
@ -2,13 +2,20 @@ package eu.kanade.tachiyomi.ui.reader.viewer
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import android.view.Gravity
|
||||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
import android.view.animation.Animation
|
|
||||||
import android.view.animation.LinearInterpolator
|
|
||||||
import android.view.animation.RotateAnimation
|
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.annotation.IntRange
|
import androidx.annotation.IntRange
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableFloatStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.platform.AbstractComposeView
|
||||||
|
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import com.google.android.material.progressindicator.CircularProgressIndicator
|
import com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
|
import eu.kanade.presentation.theme.TachiyomiTheme
|
||||||
|
import tachiyomi.presentation.core.components.CombinedCircularProgressIndicator
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper for [CircularProgressIndicator] that always rotates.
|
* A wrapper for [CircularProgressIndicator] that always rotates.
|
||||||
|
@ -19,76 +26,31 @@ class ReaderProgressIndicator @JvmOverloads constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
attrs: AttributeSet? = null,
|
attrs: AttributeSet? = null,
|
||||||
defStyleAttr: Int = 0,
|
defStyleAttr: Int = 0,
|
||||||
) : FrameLayout(context, attrs, defStyleAttr) {
|
) : AbstractComposeView(context, attrs, defStyleAttr) {
|
||||||
|
|
||||||
private val indicator: CircularProgressIndicator
|
|
||||||
|
|
||||||
private val rotateAnimation by lazy {
|
|
||||||
RotateAnimation(
|
|
||||||
0F,
|
|
||||||
360F,
|
|
||||||
Animation.RELATIVE_TO_SELF,
|
|
||||||
0.5F,
|
|
||||||
Animation.RELATIVE_TO_SELF,
|
|
||||||
0.5F,
|
|
||||||
).apply {
|
|
||||||
interpolator = LinearInterpolator()
|
|
||||||
repeatCount = Animation.INFINITE
|
|
||||||
duration = 4000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
|
layoutParams = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity.CENTER)
|
||||||
indicator = CircularProgressIndicator(context)
|
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnDetachedFromWindowOrReleasedFromPool)
|
||||||
indicator.max = 100
|
|
||||||
indicator.isIndeterminate = true
|
|
||||||
addView(indicator)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAttachedToWindow() {
|
private var progress by mutableFloatStateOf(0f)
|
||||||
super.onAttachedToWindow()
|
|
||||||
updateRotateAnimation()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDetachedFromWindow() {
|
@Composable
|
||||||
super.onDetachedFromWindow()
|
override fun Content() {
|
||||||
updateRotateAnimation()
|
TachiyomiTheme {
|
||||||
|
CombinedCircularProgressIndicator(progress = progress)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun show() {
|
fun show() {
|
||||||
indicator.show()
|
isVisible = true
|
||||||
updateRotateAnimation()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hide() {
|
fun hide() {
|
||||||
indicator.hide()
|
isVisible = false
|
||||||
updateRotateAnimation()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun setProgress(@IntRange(from = 0, to = 100) progress: Int) {
|
||||||
* Sets the current indicator progress to the specified value.
|
this.progress = progress / 100f
|
||||||
*
|
|
||||||
* @param progress Indicator will be set indeterminate if this value is 0
|
|
||||||
*/
|
|
||||||
fun setProgress(@IntRange(from = 0, to = 100) progress: Int, animated: Boolean = true) {
|
|
||||||
if (progress > 0) {
|
|
||||||
indicator.setProgressCompat(progress, animated)
|
|
||||||
} else if (!indicator.isIndeterminate) {
|
|
||||||
indicator.hide()
|
|
||||||
indicator.isIndeterminate = true
|
|
||||||
indicator.show()
|
|
||||||
}
|
|
||||||
updateRotateAnimation()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateRotateAnimation() {
|
|
||||||
if (isAttachedToWindow && indicator.isShown && !indicator.isIndeterminate) {
|
|
||||||
if (animation == null) {
|
|
||||||
startAnimation(rotateAnimation)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
clearAnimation()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,8 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.Gravity
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updateLayoutParams
|
|
||||||
import eu.kanade.tachiyomi.databinding.ReaderErrorBinding
|
import eu.kanade.tachiyomi.databinding.ReaderErrorBinding
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.ui.reader.model.InsertPage
|
import eu.kanade.tachiyomi.ui.reader.model.InsertPage
|
||||||
|
@ -46,11 +44,7 @@ class PagerPageHolder(
|
||||||
/**
|
/**
|
||||||
* Loading progress bar to indicate the current progress.
|
* Loading progress bar to indicate the current progress.
|
||||||
*/
|
*/
|
||||||
private val progressIndicator: ReaderProgressIndicator = ReaderProgressIndicator(readerThemedContext).apply {
|
private val progressIndicator: ReaderProgressIndicator = ReaderProgressIndicator(readerThemedContext)
|
||||||
updateLayoutParams<LayoutParams> {
|
|
||||||
gravity = Gravity.CENTER
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error layout to show when the image fails to load.
|
* Error layout to show when the image fails to load.
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
|
package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
|
||||||
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.view.Gravity
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
@ -119,7 +118,7 @@ class WebtoonPageHolder(
|
||||||
|
|
||||||
removeErrorLayout()
|
removeErrorLayout()
|
||||||
frame.recycle()
|
frame.recycle()
|
||||||
progressIndicator.setProgress(0, animated = false)
|
progressIndicator.setProgress(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -288,7 +287,6 @@ class WebtoonPageHolder(
|
||||||
|
|
||||||
val progress = ReaderProgressIndicator(context).apply {
|
val progress = ReaderProgressIndicator(context).apply {
|
||||||
updateLayoutParams<FrameLayout.LayoutParams> {
|
updateLayoutParams<FrameLayout.LayoutParams> {
|
||||||
gravity = Gravity.CENTER_HORIZONTAL
|
|
||||||
updateMargins(top = parentHeight / 4)
|
updateMargins(top = parentHeight / 4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,8 @@ import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.Navigator
|
import cafe.adriel.voyager.navigator.Navigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
import eu.kanade.presentation.more.settings.screen.AboutScreen
|
import eu.kanade.presentation.more.settings.screen.AboutScreen
|
||||||
|
import eu.kanade.presentation.more.settings.screen.SettingsAppearanceScreen
|
||||||
import eu.kanade.presentation.more.settings.screen.SettingsBackupScreen
|
import eu.kanade.presentation.more.settings.screen.SettingsBackupScreen
|
||||||
import eu.kanade.presentation.more.settings.screen.SettingsGeneralScreen
|
|
||||||
import eu.kanade.presentation.more.settings.screen.SettingsMainScreen
|
import eu.kanade.presentation.more.settings.screen.SettingsMainScreen
|
||||||
import eu.kanade.presentation.util.DefaultNavigatorScreenTransition
|
import eu.kanade.presentation.util.DefaultNavigatorScreenTransition
|
||||||
import eu.kanade.presentation.util.LocalBackPress
|
import eu.kanade.presentation.util.LocalBackPress
|
||||||
|
@ -59,7 +59,7 @@ class SettingsScreen private constructor(
|
||||||
} else if (toAbout) {
|
} else if (toAbout) {
|
||||||
AboutScreen
|
AboutScreen
|
||||||
} else {
|
} else {
|
||||||
SettingsGeneralScreen
|
SettingsAppearanceScreen
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
val insets = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal)
|
val insets = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal)
|
||||||
|
|
|
@ -15,9 +15,7 @@ class CreateAnimeCategoryWithName(
|
||||||
private val initialFlags: Long
|
private val initialFlags: Long
|
||||||
get() {
|
get() {
|
||||||
val sort = preferences.libraryAnimeSortingMode().get()
|
val sort = preferences.libraryAnimeSortingMode().get()
|
||||||
return preferences.libraryDisplayMode().get().flag or
|
return sort.type.flag or sort.direction.flag
|
||||||
sort.type.flag or
|
|
||||||
sort.direction.flag
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun await(name: String): Result = withNonCancellableContext {
|
suspend fun await(name: String): Result = withNonCancellableContext {
|
||||||
|
|
|
@ -10,8 +10,7 @@ class ResetAnimeCategoryFlags(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await() {
|
suspend fun await() {
|
||||||
val display = preferences.libraryDisplayMode().get()
|
|
||||||
val sort = preferences.libraryAnimeSortingMode().get()
|
val sort = preferences.libraryAnimeSortingMode().get()
|
||||||
categoryRepository.updateAllAnimeCategoryFlags(display + sort.type + sort.direction)
|
categoryRepository.updateAllAnimeCategoryFlags(sort.type + sort.direction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package tachiyomi.domain.category.anime.interactor
|
||||||
|
|
||||||
|
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||||
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
|
|
||||||
|
class SetAnimeDisplayMode(
|
||||||
|
private val preferences: LibraryPreferences,
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun await(display: LibraryDisplayMode) {
|
||||||
|
preferences.libraryDisplayMode().set(display)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,34 +0,0 @@
|
||||||
package tachiyomi.domain.category.anime.interactor
|
|
||||||
|
|
||||||
import tachiyomi.domain.category.anime.repository.AnimeCategoryRepository
|
|
||||||
import tachiyomi.domain.category.model.Category
|
|
||||||
import tachiyomi.domain.category.model.CategoryUpdate
|
|
||||||
import tachiyomi.domain.library.model.LibraryDisplayMode
|
|
||||||
import tachiyomi.domain.library.model.plus
|
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
|
||||||
|
|
||||||
class SetDisplayModeForAnimeCategory(
|
|
||||||
private val preferences: LibraryPreferences,
|
|
||||||
private val categoryRepository: AnimeCategoryRepository,
|
|
||||||
) {
|
|
||||||
|
|
||||||
suspend fun await(categoryId: Long, display: LibraryDisplayMode) {
|
|
||||||
val category = categoryRepository.getAnimeCategory(categoryId) ?: return
|
|
||||||
val flags = category.flags + display
|
|
||||||
if (preferences.categorizedDisplaySettings().get()) {
|
|
||||||
categoryRepository.updatePartialAnimeCategory(
|
|
||||||
CategoryUpdate(
|
|
||||||
id = category.id,
|
|
||||||
flags = flags,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
preferences.libraryDisplayMode().set(display)
|
|
||||||
categoryRepository.updateAllAnimeCategoryFlags(flags)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun await(category: Category, display: LibraryDisplayMode) {
|
|
||||||
await(category.id, display)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,10 +12,10 @@ class SetSortModeForAnimeCategory(
|
||||||
private val categoryRepository: AnimeCategoryRepository,
|
private val categoryRepository: AnimeCategoryRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(categoryId: Long, type: AnimeLibrarySort.Type, direction: AnimeLibrarySort.Direction) {
|
suspend fun await(categoryId: Long?, type: AnimeLibrarySort.Type, direction: AnimeLibrarySort.Direction) {
|
||||||
val category = categoryRepository.getAnimeCategory(categoryId) ?: return
|
val category = categoryId?.let { categoryRepository.getAnimeCategory(it) }
|
||||||
val flags = category.flags + type + direction
|
val flags = (category?.flags ?: 0) + type + direction
|
||||||
if (preferences.categorizedDisplaySettings().get()) {
|
if (category != null && preferences.categorizedDisplaySettings().get()) {
|
||||||
categoryRepository.updatePartialAnimeCategory(
|
categoryRepository.updatePartialAnimeCategory(
|
||||||
CategoryUpdate(
|
CategoryUpdate(
|
||||||
id = category.id,
|
id = category.id,
|
||||||
|
@ -28,7 +28,7 @@ class SetSortModeForAnimeCategory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun await(category: Category, type: AnimeLibrarySort.Type, direction: AnimeLibrarySort.Direction) {
|
suspend fun await(category: Category?, type: AnimeLibrarySort.Type, direction: AnimeLibrarySort.Direction) {
|
||||||
await(category.id, type, direction)
|
await(category?.id, type, direction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,7 @@ class CreateMangaCategoryWithName(
|
||||||
private val initialFlags: Long
|
private val initialFlags: Long
|
||||||
get() {
|
get() {
|
||||||
val sort = preferences.libraryMangaSortingMode().get()
|
val sort = preferences.libraryMangaSortingMode().get()
|
||||||
return preferences.libraryDisplayMode().get().flag or
|
return sort.type.flag or sort.direction.flag
|
||||||
sort.type.flag or
|
|
||||||
sort.direction.flag
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun await(name: String): Result = withNonCancellableContext {
|
suspend fun await(name: String): Result = withNonCancellableContext {
|
||||||
|
|
|
@ -10,8 +10,7 @@ class ResetMangaCategoryFlags(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await() {
|
suspend fun await() {
|
||||||
val display = preferences.libraryDisplayMode().get()
|
|
||||||
val sort = preferences.libraryMangaSortingMode().get()
|
val sort = preferences.libraryMangaSortingMode().get()
|
||||||
categoryRepository.updateAllMangaCategoryFlags(display + sort.type + sort.direction)
|
categoryRepository.updateAllMangaCategoryFlags(sort.type + sort.direction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
package tachiyomi.domain.category.manga.interactor
|
|
||||||
|
|
||||||
import tachiyomi.domain.category.manga.repository.MangaCategoryRepository
|
|
||||||
import tachiyomi.domain.category.model.Category
|
|
||||||
import tachiyomi.domain.category.model.CategoryUpdate
|
|
||||||
import tachiyomi.domain.library.model.LibraryDisplayMode
|
|
||||||
import tachiyomi.domain.library.model.plus
|
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
|
||||||
|
|
||||||
class SetDisplayModeForMangaCategory(
|
|
||||||
private val preferences: LibraryPreferences,
|
|
||||||
private val categoryRepository: MangaCategoryRepository,
|
|
||||||
) {
|
|
||||||
|
|
||||||
suspend fun await(categoryId: Long, display: LibraryDisplayMode) {
|
|
||||||
val category = categoryRepository.getMangaCategory(categoryId) ?: return
|
|
||||||
val flags = category.flags + display
|
|
||||||
if (preferences.categorizedDisplaySettings().get()) {
|
|
||||||
categoryRepository.updatePartialMangaCategory(
|
|
||||||
CategoryUpdate(
|
|
||||||
id = category.id,
|
|
||||||
flags = flags,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
preferences.libraryDisplayMode().set(display)
|
|
||||||
categoryRepository.updateAllMangaCategoryFlags(flags)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun await(category: Category, display: LibraryDisplayMode) {
|
|
||||||
await(category.id, display)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package tachiyomi.domain.category.manga.interactor
|
||||||
|
|
||||||
|
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||||
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
|
|
||||||
|
class SetMangaDisplayMode(
|
||||||
|
private val preferences: LibraryPreferences,
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun await(display: LibraryDisplayMode) {
|
||||||
|
preferences.libraryDisplayMode().set(display)
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,10 +12,10 @@ class SetSortModeForMangaCategory(
|
||||||
private val categoryRepository: MangaCategoryRepository,
|
private val categoryRepository: MangaCategoryRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(categoryId: Long, type: MangaLibrarySort.Type, direction: MangaLibrarySort.Direction) {
|
suspend fun await(categoryId: Long?, type: MangaLibrarySort.Type, direction: MangaLibrarySort.Direction) {
|
||||||
val category = categoryRepository.getMangaCategory(categoryId) ?: return
|
val category = categoryId?.let { categoryRepository.getMangaCategory(it) }
|
||||||
val flags = category.flags + type + direction
|
val flags = (category?.flags ?: 0) + type + direction
|
||||||
if (preferences.categorizedDisplaySettings().get()) {
|
if (category != null && preferences.categorizedDisplaySettings().get()) {
|
||||||
categoryRepository.updatePartialMangaCategory(
|
categoryRepository.updatePartialMangaCategory(
|
||||||
CategoryUpdate(
|
CategoryUpdate(
|
||||||
id = category.id,
|
id = category.id,
|
||||||
|
@ -28,7 +28,7 @@ class SetSortModeForMangaCategory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun await(category: Category, type: MangaLibrarySort.Type, direction: MangaLibrarySort.Direction) {
|
suspend fun await(category: Category?, type: MangaLibrarySort.Type, direction: MangaLibrarySort.Direction) {
|
||||||
await(category.id, type, direction)
|
await(category?.id, type, direction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
package tachiyomi.domain.library.model
|
package tachiyomi.domain.library.model
|
||||||
|
|
||||||
import tachiyomi.domain.category.model.Category
|
sealed class LibraryDisplayMode {
|
||||||
|
|
||||||
sealed class LibraryDisplayMode(
|
object CompactGrid : LibraryDisplayMode()
|
||||||
override val flag: Long,
|
object ComfortableGrid : LibraryDisplayMode()
|
||||||
) : FlagWithMask {
|
object List : LibraryDisplayMode()
|
||||||
|
object CoverOnlyGrid : LibraryDisplayMode()
|
||||||
override val mask: Long = 0b00000011L
|
|
||||||
|
|
||||||
object CompactGrid : LibraryDisplayMode(0b00000000)
|
|
||||||
object ComfortableGrid : LibraryDisplayMode(0b00000001)
|
|
||||||
object List : LibraryDisplayMode(0b00000010)
|
|
||||||
object CoverOnlyGrid : LibraryDisplayMode(0b00000011)
|
|
||||||
|
|
||||||
object Serializer {
|
object Serializer {
|
||||||
fun deserialize(serialized: String): LibraryDisplayMode {
|
fun deserialize(serialized: String): LibraryDisplayMode {
|
||||||
|
@ -27,13 +21,6 @@ sealed class LibraryDisplayMode(
|
||||||
val values by lazy { setOf(CompactGrid, ComfortableGrid, List, CoverOnlyGrid) }
|
val values by lazy { setOf(CompactGrid, ComfortableGrid, List, CoverOnlyGrid) }
|
||||||
val default = CompactGrid
|
val default = CompactGrid
|
||||||
|
|
||||||
fun valueOf(flag: Long?): LibraryDisplayMode {
|
|
||||||
if (flag == null) return default
|
|
||||||
return values
|
|
||||||
.find { mode -> mode.flag == flag and mode.mask }
|
|
||||||
?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
fun deserialize(serialized: String): LibraryDisplayMode {
|
fun deserialize(serialized: String): LibraryDisplayMode {
|
||||||
return when (serialized) {
|
return when (serialized) {
|
||||||
"COMFORTABLE_GRID" -> ComfortableGrid
|
"COMFORTABLE_GRID" -> ComfortableGrid
|
||||||
|
@ -54,6 +41,3 @@ sealed class LibraryDisplayMode(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val Category?.display: LibraryDisplayMode
|
|
||||||
get() = LibraryDisplayMode.valueOf(this?.flags)
|
|
||||||
|
|
|
@ -280,7 +280,7 @@
|
||||||
|
|
||||||
<string name="default_category">Default category</string>
|
<string name="default_category">Default category</string>
|
||||||
<string name="default_category_summary">Always ask</string>
|
<string name="default_category_summary">Always ask</string>
|
||||||
<string name="categorized_display_settings">Per-category settings for sort and display</string>
|
<string name="categorized_display_settings">Per-category settings for sort</string>
|
||||||
<plurals name="num_categories">
|
<plurals name="num_categories">
|
||||||
<item quantity="one">%d category</item>
|
<item quantity="one">%d category</item>
|
||||||
<item quantity="other">%d categories</item>
|
<item quantity="other">%d categories</item>
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
package tachiyomi.presentation.core.components
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedContent
|
||||||
|
import androidx.compose.animation.core.LinearEasing
|
||||||
|
import androidx.compose.animation.core.RepeatMode
|
||||||
|
import androidx.compose.animation.core.animateFloat
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
|
import androidx.compose.animation.core.infiniteRepeatable
|
||||||
|
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.fadeOut
|
||||||
|
import androidx.compose.animation.togetherWith
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.ProgressIndicatorDefaults
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableFloatStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.rotate
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A combined [CircularProgressIndicator] that always rotates.
|
||||||
|
*
|
||||||
|
* By always rotating we give the feedback to the user that the application isn't 'stuck'.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun CombinedCircularProgressIndicator(
|
||||||
|
progress: Float,
|
||||||
|
) {
|
||||||
|
val animatedProgress by animateFloatAsState(
|
||||||
|
targetValue = progress,
|
||||||
|
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec,
|
||||||
|
label = "progress",
|
||||||
|
)
|
||||||
|
AnimatedContent(
|
||||||
|
targetState = progress == 0f,
|
||||||
|
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
||||||
|
label = "progressState",
|
||||||
|
) { indeterminate ->
|
||||||
|
if (indeterminate) {
|
||||||
|
// Indeterminate
|
||||||
|
CircularProgressIndicator()
|
||||||
|
} else {
|
||||||
|
// Determinate
|
||||||
|
val infiniteTransition = rememberInfiniteTransition(label = "infiniteRotation")
|
||||||
|
val rotation by infiniteTransition.animateFloat(
|
||||||
|
initialValue = 0f,
|
||||||
|
targetValue = 360f,
|
||||||
|
animationSpec = infiniteRepeatable(
|
||||||
|
animation = tween(2000, easing = LinearEasing),
|
||||||
|
repeatMode = RepeatMode.Restart,
|
||||||
|
),
|
||||||
|
label = "rotation",
|
||||||
|
)
|
||||||
|
CircularProgressIndicator(
|
||||||
|
progress = animatedProgress,
|
||||||
|
modifier = Modifier.rotate(rotation),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun CombinedCircularProgressIndicatorPreview() {
|
||||||
|
var progress by remember { mutableFloatStateOf(0f) }
|
||||||
|
MaterialTheme {
|
||||||
|
Scaffold(
|
||||||
|
bottomBar = {
|
||||||
|
Button(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
onClick = {
|
||||||
|
progress = when (progress) {
|
||||||
|
0f -> 0.15f
|
||||||
|
0.15f -> 0.25f
|
||||||
|
0.25f -> 0.5f
|
||||||
|
0.5f -> 0.75f
|
||||||
|
0.75f -> 0.95f
|
||||||
|
else -> 0f
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text("change")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(it),
|
||||||
|
) {
|
||||||
|
CombinedCircularProgressIndicator(progress = progress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue