Allow more flexible custom preference composables
(cherry picked from commit 8ff0c9d61a1d5b1cc08a3615ef4bfa3d1f04a5d2) # Conflicts: # app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt # app/src/main/java/eu/kanade/presentation/more/settings/PreferenceModel.kt
This commit is contained in:
parent
2e9c265a45
commit
12b2d368ab
@ -5,28 +5,18 @@ import androidx.compose.animation.expandVertically
|
|||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.shrinkVertically
|
import androidx.compose.animation.shrinkVertically
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material.Icon
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.outlined.PeopleAlt
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.compositionLocalOf
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.structuralEqualityPolicy
|
import androidx.compose.runtime.structuralEqualityPolicy
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import eu.kanade.domain.track.service.TrackPreferences
|
import eu.kanade.domain.track.service.TrackPreferences
|
||||||
import eu.kanade.domain.ui.UiPreferences
|
|
||||||
import eu.kanade.presentation.more.settings.widget.AppThemePreferenceWidget
|
|
||||||
import eu.kanade.presentation.more.settings.widget.BasePreferenceWidget
|
|
||||||
import eu.kanade.presentation.more.settings.widget.EditTextPreferenceWidget
|
import eu.kanade.presentation.more.settings.widget.EditTextPreferenceWidget
|
||||||
import eu.kanade.presentation.more.settings.widget.InfoWidget
|
import eu.kanade.presentation.more.settings.widget.InfoWidget
|
||||||
import eu.kanade.presentation.more.settings.widget.ListPreferenceWidget
|
import eu.kanade.presentation.more.settings.widget.ListPreferenceWidget
|
||||||
import eu.kanade.presentation.more.settings.widget.MultiSelectListPreferenceWidget
|
import eu.kanade.presentation.more.settings.widget.MultiSelectListPreferenceWidget
|
||||||
import eu.kanade.presentation.more.settings.widget.PrefsHorizontalPadding
|
|
||||||
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
|
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
|
||||||
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
|
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
|
||||||
import eu.kanade.presentation.more.settings.widget.TrackingPreferenceWidget
|
import eu.kanade.presentation.more.settings.widget.TrackingPreferenceWidget
|
||||||
@ -34,7 +24,6 @@ import kotlinx.coroutines.launch
|
|||||||
import tachiyomi.core.preference.PreferenceStore
|
import tachiyomi.core.preference.PreferenceStore
|
||||||
import tachiyomi.presentation.core.components.SliderItem
|
import tachiyomi.presentation.core.components.SliderItem
|
||||||
import tachiyomi.presentation.core.util.collectAsState
|
import tachiyomi.presentation.core.util.collectAsState
|
||||||
import tachiyomi.presentation.core.util.secondaryItemAlpha
|
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -167,16 +156,6 @@ internal fun PreferenceItem(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is Preference.PreferenceItem.AppThemePreference -> {
|
|
||||||
val value by item.pref.collectAsState()
|
|
||||||
val amoled by Injekt.get<UiPreferences>().themeDarkAmoled().collectAsState()
|
|
||||||
AppThemePreferenceWidget(
|
|
||||||
title = item.title,
|
|
||||||
value = value,
|
|
||||||
amoled = amoled,
|
|
||||||
onItemClick = { scope.launch { item.pref.set(it) } },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is Preference.PreferenceItem.TrackingPreference -> {
|
is Preference.PreferenceItem.TrackingPreference -> {
|
||||||
val uName by Injekt.get<PreferenceStore>()
|
val uName by Injekt.get<PreferenceStore>()
|
||||||
.getString(TrackPreferences.trackUsername(item.service.id))
|
.getString(TrackPreferences.trackUsername(item.service.id))
|
||||||
@ -192,33 +171,9 @@ internal fun PreferenceItem(
|
|||||||
is Preference.PreferenceItem.InfoPreference -> {
|
is Preference.PreferenceItem.InfoPreference -> {
|
||||||
InfoWidget(text = item.title)
|
InfoWidget(text = item.title)
|
||||||
}
|
}
|
||||||
// SY -->
|
is Preference.PreferenceItem.CustomPreference -> {
|
||||||
is Preference.PreferenceItem.MangaDexPreference -> {
|
item.content(item)
|
||||||
BasePreferenceWidget(
|
|
||||||
title = item.title,
|
|
||||||
widget = {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Outlined.PeopleAlt,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(start = 12.dp, end = PrefsHorizontalPadding)
|
|
||||||
.secondaryItemAlpha(),
|
|
||||||
tint = if (item.loggedIn) {
|
|
||||||
MaterialTheme.colorScheme.primary
|
|
||||||
} else {
|
|
||||||
MaterialTheme.colorScheme.onSurface
|
|
||||||
},
|
|
||||||
)
|
|
||||||
},
|
|
||||||
subcomponent = null,
|
|
||||||
onClick = if (item.loggedIn) {
|
|
||||||
item.logout
|
|
||||||
} else {
|
|
||||||
item.login
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
// SY <--
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.domain.ui.model.AppTheme
|
|
||||||
import eu.kanade.presentation.more.settings.Preference.PreferenceItem
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import tachiyomi.core.preference.Preference as PreferenceData
|
import tachiyomi.core.preference.Preference as PreferenceData
|
||||||
@ -136,19 +134,6 @@ sealed class Preference {
|
|||||||
override val onValueChanged: suspend (newValue: String) -> Boolean = { true },
|
override val onValueChanged: suspend (newValue: String) -> Boolean = { true },
|
||||||
) : PreferenceItem<String>()
|
) : PreferenceItem<String>()
|
||||||
|
|
||||||
/**
|
|
||||||
* A [PreferenceItem] that shows previews of [AppTheme] selection.
|
|
||||||
*/
|
|
||||||
data class AppThemePreference(
|
|
||||||
val pref: PreferenceData<AppTheme>,
|
|
||||||
override val title: String,
|
|
||||||
) : PreferenceItem<AppTheme>() {
|
|
||||||
override val enabled: Boolean = true
|
|
||||||
override val subtitle: String? = null
|
|
||||||
override val icon: ImageVector? = null
|
|
||||||
override val onValueChanged: suspend (newValue: AppTheme) -> Boolean = { true }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A [PreferenceItem] for individual tracking service.
|
* A [PreferenceItem] for individual tracking service.
|
||||||
*/
|
*/
|
||||||
@ -173,22 +158,15 @@ sealed class Preference {
|
|||||||
override val onValueChanged: suspend (newValue: String) -> Boolean = { true }
|
override val onValueChanged: suspend (newValue: String) -> Boolean = { true }
|
||||||
}
|
}
|
||||||
|
|
||||||
// SY -->
|
data class CustomPreference(
|
||||||
/**
|
|
||||||
* A [PreferenceItem] for mangadex login.
|
|
||||||
*/
|
|
||||||
data class MangaDexPreference(
|
|
||||||
override val title: String,
|
override val title: String,
|
||||||
val loggedIn: Boolean,
|
val content: @Composable (PreferenceItem<String>) -> Unit,
|
||||||
val login: () -> Unit,
|
|
||||||
val logout: () -> Unit,
|
|
||||||
) : PreferenceItem<String>() {
|
) : PreferenceItem<String>() {
|
||||||
override val enabled: Boolean = true
|
override val enabled: Boolean = true
|
||||||
override val subtitle: String? = null
|
override val subtitle: String? = null
|
||||||
override val icon: ImageVector? = null
|
override val icon: ImageVector? = null
|
||||||
override val onValueChanged: suspend (newValue: String) -> Boolean = { true }
|
override val onValueChanged: suspend (newValue: String) -> Boolean = { true }
|
||||||
}
|
}
|
||||||
// SY <--
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PreferenceGroup(
|
data class PreferenceGroup(
|
||||||
|
@ -21,6 +21,7 @@ import eu.kanade.domain.ui.model.TabletUiMode
|
|||||||
import eu.kanade.domain.ui.model.ThemeMode
|
import eu.kanade.domain.ui.model.ThemeMode
|
||||||
import eu.kanade.domain.ui.model.setAppCompatDelegateThemeMode
|
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.more.settings.widget.AppThemePreferenceWidget
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
@ -63,8 +64,11 @@ object SettingsAppearanceScreen : SearchableSettings {
|
|||||||
): Preference.PreferenceGroup {
|
): Preference.PreferenceGroup {
|
||||||
val themeModePref = uiPreferences.themeMode()
|
val themeModePref = uiPreferences.themeMode()
|
||||||
val themeMode by themeModePref.collectAsState()
|
val themeMode by themeModePref.collectAsState()
|
||||||
|
|
||||||
val appThemePref = uiPreferences.appTheme()
|
val appThemePref = uiPreferences.appTheme()
|
||||||
|
|
||||||
val amoledPref = uiPreferences.themeDarkAmoled()
|
val amoledPref = uiPreferences.themeDarkAmoled()
|
||||||
|
val amoled by amoledPref.collectAsState()
|
||||||
|
|
||||||
LaunchedEffect(themeMode) {
|
LaunchedEffect(themeMode) {
|
||||||
setAppCompatDelegateThemeMode(themeMode)
|
setAppCompatDelegateThemeMode(themeMode)
|
||||||
@ -95,10 +99,17 @@ object SettingsAppearanceScreen : SearchableSettings {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Preference.PreferenceItem.AppThemePreference(
|
Preference.PreferenceItem.CustomPreference(
|
||||||
title = stringResource(R.string.pref_app_theme),
|
title = stringResource(R.string.pref_app_theme),
|
||||||
pref = appThemePref,
|
) { item ->
|
||||||
),
|
val value by appThemePref.collectAsState()
|
||||||
|
AppThemePreferenceWidget(
|
||||||
|
title = item.title,
|
||||||
|
value = value,
|
||||||
|
amoled = amoled,
|
||||||
|
onItemClick = { appThemePref.set(it) },
|
||||||
|
)
|
||||||
|
},
|
||||||
Preference.PreferenceItem.SwitchPreference(
|
Preference.PreferenceItem.SwitchPreference(
|
||||||
pref = amoledPref,
|
pref = amoledPref,
|
||||||
title = stringResource(R.string.pref_dark_theme_pure_black),
|
title = stringResource(R.string.pref_dark_theme_pure_black),
|
||||||
|
@ -8,8 +8,11 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.PeopleAlt
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Checkbox
|
import androidx.compose.material3.Checkbox
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
@ -25,9 +28,12 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
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.compose.ui.unit.dp
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
import eu.kanade.domain.track.service.TrackPreferences
|
import eu.kanade.domain.track.service.TrackPreferences
|
||||||
import eu.kanade.presentation.more.settings.Preference
|
import eu.kanade.presentation.more.settings.Preference
|
||||||
|
import eu.kanade.presentation.more.settings.widget.BasePreferenceWidget
|
||||||
|
import eu.kanade.presentation.more.settings.widget.PrefsHorizontalPadding
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
||||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||||
@ -42,6 +48,7 @@ import tachiyomi.core.util.system.logcat
|
|||||||
import tachiyomi.domain.UnsortedPreferences
|
import tachiyomi.domain.UnsortedPreferences
|
||||||
import tachiyomi.presentation.core.components.material.padding
|
import tachiyomi.presentation.core.components.material.padding
|
||||||
import tachiyomi.presentation.core.util.collectAsState
|
import tachiyomi.presentation.core.util.collectAsState
|
||||||
|
import tachiyomi.presentation.core.util.secondaryItemAlpha
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -93,7 +100,7 @@ object SettingsMangadexScreen : SearchableSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun loginPreference(mdex: MangaDex, trackPreferences: TrackPreferences): Preference.PreferenceItem.MangaDexPreference {
|
fun loginPreference(mdex: MangaDex, trackPreferences: TrackPreferences): Preference.PreferenceItem.CustomPreference {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val loggedIn by remember { trackPreferences.trackToken(mdex.mdList) }.collectAsState()
|
val loggedIn by remember { trackPreferences.trackToken(mdex.mdList) }.collectAsState()
|
||||||
@ -124,17 +131,39 @@ object SettingsMangadexScreen : SearchableSettings {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return Preference.PreferenceItem.MangaDexPreference(
|
return Preference.PreferenceItem.CustomPreference(
|
||||||
title = mdex.name + " Login",
|
title = mdex.name + " Login",
|
||||||
loggedIn = loggedIn.isNotEmpty(),
|
content = {
|
||||||
login = {
|
BasePreferenceWidget(
|
||||||
|
title = it.title,
|
||||||
|
widget = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.PeopleAlt,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 12.dp, end = PrefsHorizontalPadding)
|
||||||
|
.secondaryItemAlpha(),
|
||||||
|
tint = if (loggedIn.isNotEmpty()) {
|
||||||
|
MaterialTheme.colorScheme.primary
|
||||||
|
} else {
|
||||||
|
MaterialTheme.colorScheme.onSurface
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
subcomponent = null,
|
||||||
|
onClick = if (loggedIn.isNotEmpty()) {
|
||||||
|
{
|
||||||
|
logoutDialogOpen = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
{
|
||||||
context.openInBrowser(
|
context.openInBrowser(
|
||||||
MdConstants.Login.authUrl(MdUtil.getPkceChallengeCode()),
|
MdConstants.Login.authUrl(MdUtil.getPkceChallengeCode()),
|
||||||
forceDefaultBrowser = true,
|
forceDefaultBrowser = true,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
logout = {
|
)
|
||||||
logoutDialogOpen = true
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
@ -30,7 +31,6 @@ import nl.adaptivity.xmlutil.serialization.XML
|
|||||||
import nl.adaptivity.xmlutil.serialization.XmlSerialName
|
import nl.adaptivity.xmlutil.serialization.XmlSerialName
|
||||||
import nl.adaptivity.xmlutil.serialization.XmlValue
|
import nl.adaptivity.xmlutil.serialization.XmlValue
|
||||||
import tachiyomi.core.util.lang.withIOContext
|
import tachiyomi.core.util.lang.withIOContext
|
||||||
import tachiyomi.presentation.core.components.material.Divider
|
|
||||||
import tachiyomi.presentation.core.components.material.padding
|
import tachiyomi.presentation.core.components.material.padding
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -72,7 +72,7 @@ fun WhatsNewDialog(onDismissRequest: () -> Unit) {
|
|||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
style = MaterialTheme.typography.titleSmall,
|
style = MaterialTheme.typography.titleSmall,
|
||||||
)
|
)
|
||||||
Divider(Modifier.padding(vertical = 8.dp))
|
HorizontalDivider(Modifier.padding(vertical = 8.dp))
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||||
) {
|
) {
|
||||||
|
@ -25,6 +25,7 @@ import androidx.compose.foundation.text.selection.SelectionContainer
|
|||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Switch
|
import androidx.compose.material3.Switch
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@ -56,7 +57,6 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
|
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
|
||||||
import tachiyomi.presentation.core.components.material.Divider
|
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.components.material.topSmallPaddingValues
|
import tachiyomi.presentation.core.components.material.topSmallPaddingValues
|
||||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
@ -153,7 +153,7 @@ class SettingsDebugScreen : Screen() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
Divider()
|
HorizontalDivider()
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
Text(
|
Text(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user