mirror of
https://github.com/FluxaMedia/fluxa.git
synced 2026-08-07 09:18:58 +00:00
Polish shared Settings screen: nav icons, profile avatar, drop restart button
Adds Material icons to each Settings hub nav row (Account, General, Appearance, Playback, Catalogs, Add-ons, Downloads, Developer) and shows the active profile's avatar next to the display name at the top of the hub. Removes the "Restart app" action end-to-end (action, store handling, FluxaAppHost plumbing) since it was a no-op in both native and shared code.
This commit is contained in:
parent
c983e6702f
commit
339e525d34
6 changed files with 60 additions and 18 deletions
|
|
@ -121,6 +121,7 @@ class AndroidSettingsDataSource(
|
|||
return SettingsUiState(
|
||||
account = SettingsAccountUiModel(
|
||||
displayName = profile.profileName?.takeIf { it.isNotBlank() } ?: profile.email,
|
||||
avatarUrl = profile.avatarUrl,
|
||||
isGuest = profile.isGuest,
|
||||
hasTrakt = !profile.traktAccessToken.isNullOrBlank(),
|
||||
hasMal = !profile.malAccessToken.isNullOrBlank(),
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ fun FluxaAppHost(
|
|||
onConnectSimklRequested: () -> Unit = {},
|
||||
onConnectAnilistRequested: () -> Unit = {},
|
||||
onCheckForUpdateRequested: () -> Unit = {},
|
||||
onRestartRequested: () -> Unit = {},
|
||||
onDownloadOpened: (String) -> Unit = {},
|
||||
onSettingsBackRequested: () -> Unit = {},
|
||||
modifier: Modifier = Modifier
|
||||
|
|
@ -121,7 +120,6 @@ fun FluxaAppHost(
|
|||
onConnectSimklRequested = onConnectSimklRequested,
|
||||
onConnectAnilistRequested = onConnectAnilistRequested,
|
||||
onCheckForUpdateRequested = onCheckForUpdateRequested,
|
||||
onRestartRequested = onRestartRequested,
|
||||
onDownloadOpened = onDownloadOpened,
|
||||
onSettingsBackRequested = onSettingsBackRequested,
|
||||
modifier = modifier
|
||||
|
|
@ -163,7 +161,6 @@ fun FluxaAppHost(
|
|||
onConnectSimklRequested: () -> Unit = {},
|
||||
onConnectAnilistRequested: () -> Unit = {},
|
||||
onCheckForUpdateRequested: () -> Unit = {},
|
||||
onRestartRequested: () -> Unit = {},
|
||||
onDownloadOpened: (String) -> Unit = {},
|
||||
onSettingsBackRequested: () -> Unit = {},
|
||||
modifier: Modifier = Modifier
|
||||
|
|
@ -349,7 +346,6 @@ fun FluxaAppHost(
|
|||
SettingsAction.ConnectSimklRequested -> onConnectSimklRequested()
|
||||
SettingsAction.ConnectAnilistRequested -> onConnectAnilistRequested()
|
||||
SettingsAction.CheckForUpdateRequested -> onCheckForUpdateRequested()
|
||||
SettingsAction.RestartRequested -> onRestartRequested()
|
||||
is SettingsAction.DownloadOpened -> onDownloadOpened(action.id)
|
||||
else -> scope.launch { settingsStore?.dispatch(action) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ enum class SettingsCategory {
|
|||
|
||||
data class SettingsAccountUiModel(
|
||||
val displayName: String = "",
|
||||
val avatarUrl: String? = null,
|
||||
val isGuest: Boolean = true,
|
||||
val hasTrakt: Boolean = false,
|
||||
val hasMal: Boolean = false,
|
||||
|
|
@ -210,7 +211,6 @@ sealed interface SettingsAction {
|
|||
data object DisconnectSyncRequested : SettingsAction
|
||||
data object SwitchProfilesRequested : SettingsAction
|
||||
data object CheckForUpdateRequested : SettingsAction
|
||||
data object RestartRequested : SettingsAction
|
||||
data class DownloadOpened(val id: String) : SettingsAction
|
||||
data class DownloadCancelled(val id: String) : SettingsAction
|
||||
}
|
||||
|
|
|
|||
|
|
@ -293,13 +293,32 @@ fun SettingsInfoRow(label: String, value: String) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun SettingsNavRow(label: String, onClick: () -> Unit) {
|
||||
fun SettingsNavRow(label: String, icon: androidx.compose.ui.graphics.vector.ImageVector? = null, onClick: () -> Unit) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().clickable(onClick = onClick).padding(vertical = 14.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(label, color = Color.White, fontWeight = FontWeight.Medium)
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
if (icon != null) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(32.dp)
|
||||
.clip(RoundedCornerShape(9.dp))
|
||||
.background(Color.White.copy(alpha = 0.08f)),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
androidx.compose.material3.Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = Color.White.copy(alpha = 0.85f),
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.width(14.dp))
|
||||
}
|
||||
Text(label, color = Color.White, fontWeight = FontWeight.Medium)
|
||||
}
|
||||
Text("›", color = Color.White.copy(alpha = 0.4f), fontSize = 18.sp)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,15 @@ import androidx.compose.foundation.layout.width
|
|||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.AccountCircle
|
||||
import androidx.compose.material.icons.filled.Code
|
||||
import androidx.compose.material.icons.filled.Download
|
||||
import androidx.compose.material.icons.filled.Extension
|
||||
import androidx.compose.material.icons.filled.MenuBook
|
||||
import androidx.compose.material.icons.filled.Palette
|
||||
import androidx.compose.material.icons.filled.PlayCircle
|
||||
import androidx.compose.material.icons.filled.Tune
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
|
|
@ -112,18 +121,37 @@ private fun SettingsHubContent(
|
|||
onSwitchProfiles: () -> Unit,
|
||||
onAction: (SettingsAction) -> Unit
|
||||
) {
|
||||
Text(state.account.displayName, color = Color.White, fontWeight = FontWeight.Bold, fontSize = 18.sp, modifier = Modifier.padding(vertical = 8.dp))
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.account")) { onNavigate(SettingsCategory.Account) }
|
||||
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
Box(
|
||||
modifier = Modifier.size(44.dp).clip(CircleShape).background(Color.White.copy(alpha = 0.1f)),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
if (!state.account.avatarUrl.isNullOrBlank()) {
|
||||
com.fluxa.app.shared.image.FluxaRemoteImage(
|
||||
imageUrl = state.account.avatarUrl,
|
||||
cacheKey = "settings-avatar:${state.account.avatarUrl}",
|
||||
contentDescription = null,
|
||||
modifier = Modifier.fillMaxSize().clip(CircleShape),
|
||||
contentScale = androidx.compose.ui.layout.ContentScale.Crop
|
||||
)
|
||||
} else {
|
||||
com.fluxa.app.shared.feature.profile.ProfileDefaultAvatar(modifier = Modifier.size(26.dp))
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.width(12.dp))
|
||||
Text(state.account.displayName, color = Color.White, fontWeight = FontWeight.Bold, fontSize = 18.sp)
|
||||
}
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.account"), icon = Icons.Filled.AccountCircle) { onNavigate(SettingsCategory.Account) }
|
||||
|
||||
SettingsSectionHeader(AppStrings.t(lang, "settings.section_preferences"))
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.general")) { onNavigate(SettingsCategory.General) }
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.appearance")) { onNavigate(SettingsCategory.Appearance) }
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.playback")) { onNavigate(SettingsCategory.Playback) }
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.general"), icon = Icons.Filled.Tune) { onNavigate(SettingsCategory.General) }
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.appearance"), icon = Icons.Filled.Palette) { onNavigate(SettingsCategory.Appearance) }
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.playback"), icon = Icons.Filled.PlayCircle) { onNavigate(SettingsCategory.Playback) }
|
||||
|
||||
SettingsSectionHeader(AppStrings.t(lang, "settings.section_content"))
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.catalogs")) { onNavigate(SettingsCategory.Content) }
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.add_ons")) { onNavigate(SettingsCategory.Addons) }
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.downloads")) { onNavigate(SettingsCategory.Downloads) }
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.catalogs"), icon = Icons.Filled.MenuBook) { onNavigate(SettingsCategory.Content) }
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.add_ons"), icon = Icons.Filled.Extension) { onNavigate(SettingsCategory.Addons) }
|
||||
SettingsNavRow(AppStrings.t(lang, "auto.downloads"), icon = Icons.Filled.Download) { onNavigate(SettingsCategory.Downloads) }
|
||||
|
||||
SettingsSectionHeader(AppStrings.t(lang, "settings.section_system"))
|
||||
SettingsToggleRow(
|
||||
|
|
@ -133,8 +161,7 @@ private fun SettingsHubContent(
|
|||
onValueChanged = { onAction(SettingsAction.SystemChanged(state.system.copy(automaticUpdates = it))) }
|
||||
)
|
||||
SettingsActionRow(AppStrings.t(lang, "settings.check_for_updates")) { onAction(SettingsAction.CheckForUpdateRequested) }
|
||||
SettingsNavRow(AppStrings.t(lang, "settings.developer")) { onNavigate(SettingsCategory.Developer) }
|
||||
SettingsActionRow(AppStrings.t(lang, "auto.restart"), destructive = true) { onAction(SettingsAction.RestartRequested) }
|
||||
SettingsNavRow(AppStrings.t(lang, "settings.developer"), icon = Icons.Filled.Code) { onNavigate(SettingsCategory.Developer) }
|
||||
|
||||
Spacer(Modifier.height(12.dp))
|
||||
Text(state.system.appVersionLabel, color = Color.White.copy(alpha = 0.35f), fontSize = 11.sp)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ class SettingsStore(
|
|||
SettingsAction.DisconnectSyncRequested -> dataSource.disconnectSync()
|
||||
SettingsAction.SwitchProfilesRequested -> Unit
|
||||
SettingsAction.CheckForUpdateRequested -> Unit
|
||||
SettingsAction.RestartRequested -> Unit
|
||||
is SettingsAction.DownloadOpened -> Unit
|
||||
is SettingsAction.DownloadCancelled -> dataSource.cancelDownload(action.id)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue