mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-07-31 08:39:24 +00:00
Merge branch 'cmp-rewrite' into desktopweb
This commit is contained in:
commit
330d2537d9
4 changed files with 71 additions and 51 deletions
|
|
@ -26,7 +26,6 @@ actual object ThemeSettingsStorage {
|
|||
liquidGlassNativeTabBarEnabledKey,
|
||||
desktopNavigationLayoutKey,
|
||||
)
|
||||
private val globalSyncKeys = listOf(selectedAppLanguageKey)
|
||||
|
||||
private var preferences: SharedPreferences? = null
|
||||
|
||||
|
|
@ -107,20 +106,17 @@ actual object ThemeSettingsStorage {
|
|||
loadAmoledEnabled()?.let { put(amoledEnabledKey, encodeSyncBoolean(it)) }
|
||||
loadLiquidGlassNativeTabBarEnabled()?.let { put(liquidGlassNativeTabBarEnabledKey, encodeSyncBoolean(it)) }
|
||||
loadDesktopNavigationLayout()?.let { put(desktopNavigationLayoutKey, encodeSyncString(it)) }
|
||||
loadSelectedAppLanguage()?.let { put(selectedAppLanguageKey, encodeSyncString(it)) }
|
||||
}
|
||||
|
||||
actual fun replaceFromSyncPayload(payload: JsonObject) {
|
||||
preferences?.edit()?.apply {
|
||||
profileScopedSyncKeys.forEach { remove(ProfileScopedKey.of(it)) }
|
||||
globalSyncKeys.forEach { remove(it) }
|
||||
}?.apply()
|
||||
|
||||
payload.decodeSyncString(selectedThemeKey)?.let(::saveSelectedTheme)
|
||||
payload.decodeSyncBoolean(amoledEnabledKey)?.let(::saveAmoledEnabled)
|
||||
payload.decodeSyncBoolean(liquidGlassNativeTabBarEnabledKey)?.let(::saveLiquidGlassNativeTabBarEnabled)
|
||||
payload.decodeSyncString(desktopNavigationLayoutKey)?.let(::saveDesktopNavigationLayout)
|
||||
payload.decodeSyncString(selectedAppLanguageKey)?.let(::saveSelectedAppLanguage)
|
||||
applySelectedAppLanguage(loadSelectedAppLanguage() ?: AppLanguage.ENGLISH.code)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ import androidx.compose.foundation.border
|
|||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
|
|
@ -38,6 +38,7 @@ import androidx.compose.ui.draw.clip
|
|||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.nuvio.app.isDesktop
|
||||
|
|
@ -71,7 +72,6 @@ import org.jetbrains.compose.resources.stringResource
|
|||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
internal fun LazyListScope.appearanceSettingsContent(
|
||||
isTablet: Boolean,
|
||||
selectedTheme: AppTheme,
|
||||
|
|
@ -93,28 +93,50 @@ internal fun LazyListScope.appearanceSettingsContent(
|
|||
) {
|
||||
SettingsGroup(isTablet = isTablet) {
|
||||
val themes = listOf(AppTheme.WHITE) + AppTheme.entries.filterNot { it == AppTheme.WHITE }
|
||||
FlowRow(
|
||||
val horizontalPadding = if (isTablet) 20.dp else 16.dp
|
||||
val verticalPadding = if (isTablet) 18.dp else 14.dp
|
||||
val themeSpacing = if (isTablet) 16.dp else 12.dp
|
||||
BoxWithConstraints(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
horizontal = if (isTablet) 20.dp else 16.dp,
|
||||
vertical = if (isTablet) 18.dp else 14.dp,
|
||||
horizontal = horizontalPadding,
|
||||
vertical = verticalPadding,
|
||||
),
|
||||
horizontalArrangement = Arrangement.spacedBy(if (isTablet) 16.dp else 12.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(if (isTablet) 16.dp else 12.dp),
|
||||
) {
|
||||
themes.forEach { theme ->
|
||||
ThemeChip(
|
||||
theme = theme,
|
||||
isSelected = theme == selectedTheme,
|
||||
onClick = { onThemeSelected(theme) },
|
||||
)
|
||||
val preferredColumns = if (isTablet) 4 else 3
|
||||
val minThemeCellWidth = if (isTablet) 92.dp else 78.dp
|
||||
val themeColumns = ((maxWidth + themeSpacing) / (minThemeCellWidth + themeSpacing))
|
||||
.toInt()
|
||||
.coerceAtLeast(1)
|
||||
.coerceAtMost(preferredColumns)
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(themeSpacing),
|
||||
) {
|
||||
themes.chunked(themeColumns).forEach { rowThemes ->
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(themeSpacing),
|
||||
) {
|
||||
rowThemes.forEach { theme ->
|
||||
ThemeChip(
|
||||
theme = theme,
|
||||
isSelected = theme == selectedTheme,
|
||||
onClick = { onThemeSelected(theme) },
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
}
|
||||
repeat(themeColumns - rowThemes.size) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
var showLanguageSheet by remember { mutableStateOf(false) }
|
||||
var showDesktopNavigationSheet by remember { mutableStateOf(false) }
|
||||
|
|
@ -352,41 +374,48 @@ private fun ThemeChip(
|
|||
theme: AppTheme,
|
||||
isSelected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val palette = ThemeColors.getColorPalette(theme)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
modifier = modifier
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.clickable(onClick = onClick)
|
||||
.then(
|
||||
if (isSelected) {
|
||||
Modifier.border(
|
||||
width = 1.5.dp,
|
||||
color = palette.focusRing,
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
},
|
||||
)
|
||||
.padding(horizontal = 12.dp, vertical = 10.dp),
|
||||
.padding(horizontal = 4.dp, vertical = 8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(44.dp)
|
||||
.clip(CircleShape)
|
||||
.background(palette.secondary),
|
||||
.size(56.dp)
|
||||
.then(
|
||||
if (isSelected) {
|
||||
Modifier.border(
|
||||
width = 1.5.dp,
|
||||
color = palette.focusRing,
|
||||
shape = RoundedCornerShape(14.dp),
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
},
|
||||
),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
if (isSelected) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Check,
|
||||
contentDescription = stringResource(Res.string.cd_selected),
|
||||
tint = palette.onSecondary,
|
||||
modifier = Modifier.size(22.dp),
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(44.dp)
|
||||
.clip(CircleShape)
|
||||
.background(palette.secondary),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
if (isSelected) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Check,
|
||||
contentDescription = stringResource(Res.string.cd_selected),
|
||||
tint = palette.onSecondary,
|
||||
modifier = Modifier.size(22.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -402,6 +431,9 @@ private fun ThemeChip(
|
|||
},
|
||||
fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Medium,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
|
|
|
|||
|
|
@ -70,16 +70,14 @@ internal actual object ThemeSettingsStorage {
|
|||
loadAmoledEnabled()?.let { put(amoledEnabledKey, encodeSyncBoolean(it)) }
|
||||
loadLiquidGlassNativeTabBarEnabled()?.let { put(liquidGlassNativeTabBarEnabledKey, encodeSyncBoolean(it)) }
|
||||
loadDesktopNavigationLayout()?.let { put(desktopNavigationLayoutKey, encodeSyncString(it)) }
|
||||
loadSelectedAppLanguage()?.let { put(selectedAppLanguageKey, encodeSyncString(it)) }
|
||||
}
|
||||
|
||||
actual fun replaceFromSyncPayload(payload: JsonObject) {
|
||||
store.removeAll(profileScopedSyncKeys.map(ProfileScopedKey::of) + selectedAppLanguageKey)
|
||||
store.removeAll(profileScopedSyncKeys.map(ProfileScopedKey::of))
|
||||
payload.decodeSyncString(selectedThemeKey)?.let(::saveSelectedTheme)
|
||||
payload.decodeSyncBoolean(amoledEnabledKey)?.let(::saveAmoledEnabled)
|
||||
payload.decodeSyncBoolean(liquidGlassNativeTabBarEnabledKey)?.let(::saveLiquidGlassNativeTabBarEnabled)
|
||||
payload.decodeSyncString(desktopNavigationLayoutKey)?.let(::saveDesktopNavigationLayout)
|
||||
payload.decodeSyncString(selectedAppLanguageKey)?.let(::saveSelectedAppLanguage)
|
||||
applySelectedAppLanguage(loadSelectedAppLanguage() ?: AppLanguage.ENGLISH.code)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ actual object ThemeSettingsStorage {
|
|||
liquidGlassNativeTabBarEnabledKey,
|
||||
desktopNavigationLayoutKey,
|
||||
)
|
||||
private val globalSyncKeys = listOf(selectedAppLanguageKey)
|
||||
|
||||
actual fun loadSelectedTheme(): String? =
|
||||
NSUserDefaults.standardUserDefaults.stringForKey(ProfileScopedKey.of(selectedThemeKey))
|
||||
|
|
@ -101,22 +100,17 @@ actual object ThemeSettingsStorage {
|
|||
loadAmoledEnabled()?.let { put(amoledEnabledKey, encodeSyncBoolean(it)) }
|
||||
loadLiquidGlassNativeTabBarEnabled()?.let { put(liquidGlassNativeTabBarEnabledKey, encodeSyncBoolean(it)) }
|
||||
loadDesktopNavigationLayout()?.let { put(desktopNavigationLayoutKey, encodeSyncString(it)) }
|
||||
loadSelectedAppLanguage()?.let { put(selectedAppLanguageKey, encodeSyncString(it)) }
|
||||
}
|
||||
|
||||
actual fun replaceFromSyncPayload(payload: JsonObject) {
|
||||
profileScopedSyncKeys.forEach { key ->
|
||||
NSUserDefaults.standardUserDefaults.removeObjectForKey(ProfileScopedKey.of(key))
|
||||
}
|
||||
globalSyncKeys.forEach { key ->
|
||||
NSUserDefaults.standardUserDefaults.removeObjectForKey(key)
|
||||
}
|
||||
|
||||
payload.decodeSyncString(selectedThemeKey)?.let(::saveSelectedTheme)
|
||||
payload.decodeSyncBoolean(amoledEnabledKey)?.let(::saveAmoledEnabled)
|
||||
payload.decodeSyncBoolean(liquidGlassNativeTabBarEnabledKey)?.let(::saveLiquidGlassNativeTabBarEnabled)
|
||||
payload.decodeSyncString(desktopNavigationLayoutKey)?.let(::saveDesktopNavigationLayout)
|
||||
payload.decodeSyncString(selectedAppLanguageKey)?.let(::saveSelectedAppLanguage)
|
||||
applySelectedAppLanguage(loadSelectedAppLanguage() ?: AppLanguage.ENGLISH.code)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue