Last commit for the settings pages.
This commit is contained in:
parent
f60a58f71e
commit
84515e6d57
20 changed files with 450 additions and 71 deletions
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:pathData="M480,880 L340,740l56,-56 44,43v-247h80v247l44,-43 56,56L480,880ZM240,720 L100,580l56,-56 44,43v-247h80v247l44,-43 56,56 -140,140ZM720,720L580,580l56,-56 44,43v-247h80v247l44,-43 56,56 -140,140ZM80,440v-240q0,-33 23.5,-56.5T160,120h640q33,0 56.5,23.5T880,200v240h-80v-240L160,200v240L80,440Z"
|
||||
android:fillColor="#5f6368"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:pathData="M640,700q25,0 42.5,-17.5T700,640q0,-25 -17.5,-42.5T640,580q-25,0 -42.5,17.5T580,640q0,25 17.5,42.5T640,700ZM480,540q25,0 42.5,-17.5T540,480q0,-25 -17.5,-42.5T480,420q-25,0 -42.5,17.5T420,480q0,25 17.5,42.5T480,540ZM320,380q25,0 42.5,-17.5T380,320q0,-25 -17.5,-42.5T320,260q-25,0 -42.5,17.5T260,320q0,25 17.5,42.5T320,380ZM200,840q-33,0 -56.5,-23.5T120,760v-560q0,-33 23.5,-56.5T200,120h560q33,0 56.5,23.5T840,200v560q0,33 -23.5,56.5T760,840L200,840ZM200,760h560v-560L200,200v560ZM200,200v560,-560Z"
|
||||
android:fillColor="#5f6368"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:pathData="M360,120v-80h240v80L360,120ZM440,560h80v-240h-80v240ZM480,880q-74,0 -139.5,-28.5T226,774q-49,-49 -77.5,-114.5T120,520q0,-74 28.5,-139.5T226,266q49,-49 114.5,-77.5T480,160q62,0 119,20t107,58l56,-56 56,56 -56,56q38,50 58,107t20,119q0,74 -28.5,139.5T734,774q-49,49 -114.5,77.5T480,880ZM480,800q116,0 198,-82t82,-198q0,-116 -82,-198t-198,-82q-116,0 -198,82t-82,198q0,116 82,198t198,82ZM480,520Z"
|
||||
android:fillColor="#5f6368"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:pathData="M480,640q75,0 127.5,-52.5T660,460q0,-75 -52.5,-127.5T480,280q-75,0 -127.5,52.5T300,460q0,75 52.5,127.5T480,640ZM480,568q-45,0 -76.5,-31.5T372,460q0,-45 31.5,-76.5T480,352q45,0 76.5,31.5T588,460q0,45 -31.5,76.5T480,568ZM480,760q-146,0 -266,-81.5T40,460q54,-137 174,-218.5T480,160q146,0 266,81.5T920,460q-54,137 -174,218.5T480,760ZM480,460ZM480,680q113,0 207.5,-59.5T832,460q-50,-101 -144.5,-160.5T480,240q-113,0 -207.5,59.5T128,460q50,101 144.5,160.5T480,680Z"
|
||||
android:fillColor="#5f6368"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:pathData="m644,532 l-58,-58q9,-47 -27,-88t-93,-32l-58,-58q17,-8 34.5,-12t37.5,-4q75,0 127.5,52.5T660,460q0,20 -4,37.5T644,532ZM772,658 L714,602q38,-29 67.5,-63.5T832,460q-50,-101 -143.5,-160.5T480,240q-29,0 -57,4t-55,12l-62,-62q41,-17 84,-25.5t90,-8.5q151,0 269,83.5T920,460q-23,59 -60.5,109.5T772,658ZM792,904L624,738q-35,11 -70.5,16.5T480,760q-151,0 -269,-83.5T40,460q21,-53 53,-98.5t73,-81.5L56,168l56,-56 736,736 -56,56ZM222,336q-29,26 -53,57t-41,67q50,101 143.5,160.5T480,680q20,0 39,-2.5t39,-5.5l-36,-38q-11,3 -21,4.5t-21,1.5q-75,0 -127.5,-52.5T300,460q0,-11 1.5,-21t4.5,-21l-84,-82ZM541,429ZM390,504Z"
|
||||
android:fillColor="#5f6368"/>
|
||||
</vector>
|
||||
|
|
@ -158,8 +158,24 @@
|
|||
<string name="roll_history__item__throw">lance</string>
|
||||
<string name="roll_history__item__difficulty">Difficulté</string>
|
||||
|
||||
<string name="chat__diminished_change">%1$s passe à %2$d d\'état diminuée</string>
|
||||
<string name="chat__diminished_change">%1$s passe à %2$d d'état diminuée</string>
|
||||
<string name="chat__characteristic_change">%1$s passe à %2$d %3$s</string>
|
||||
<string name="chat__characteristic__hp">Hp</string>
|
||||
<string name="chat__characteristic__pp">Pp</string>
|
||||
|
||||
<string name="settings__title">Paramètres de l'application</string>
|
||||
<string name="settings__reset_action">Paramètres par défault</string>
|
||||
<string name="settings__player_portrait__section">Portrait joueur</string>
|
||||
<string name="settings__player_portrait__dyn_dice_tile">Dés dynamiques</string>
|
||||
<string name="settings__player_portrait__dyn_dice_description">Affiche un dé à côté du portrait d'un personnage lorsqu'un jet est fait par ce dernier.</string>
|
||||
<string name="settings__chat_log__section">Chatlog options</string>
|
||||
<string name="settings__chat_log__auto_show_title">Afficher automatiquement le chat</string>
|
||||
<string name="settings__chat_log__auto_show_description">Affiche automatiquement le chat lors de la réception d'un message</string>
|
||||
<string name="settings__chat_log__auto_hide_title">Cacher automatiquement le chat</string>
|
||||
<string name="settings__chat_log__auto_hide_description">Cache automatiquement le chat au bout d'un certain temps</string>
|
||||
<string name="settings__chat_log__auto_hide_delay_title">Délai pour cacher le chat</string>
|
||||
<string name="settings__chat_log__auto_hide_delay_description">Délai après lequel le chat disparaît</string>
|
||||
<string name="settings__chat_log__auto_scroll_title">Défilement automatique</string>
|
||||
<string name="settings__chat_log__auto_scroll_description">Défilement automatique du chat vers le dernier message reçu lors de la réception de ce dernier.</string>
|
||||
|
||||
</resources>
|
||||
|
|
@ -18,6 +18,7 @@ class SettingsFactory(
|
|||
playerName = settings.playerName,
|
||||
dynamicDice = settings.dynamicDice,
|
||||
autoHideChat = settings.autoHideChat,
|
||||
autoHideDelay = settings.autoHideDelay,
|
||||
autoShowChat = settings.autoShowChat,
|
||||
autoScrollChat = settings.autoScrollChat,
|
||||
)
|
||||
|
|
@ -41,6 +42,7 @@ class SettingsFactory(
|
|||
playerName = json.playerName ?: default.playerName,
|
||||
dynamicDice = json.dynamicDice ?: default.dynamicDice,
|
||||
autoHideChat = json.autoHideChat ?: default.autoHideChat,
|
||||
autoHideDelay = json.autoHideDelay ?: default.autoHideDelay,
|
||||
autoShowChat = json.autoShowChat ?: default.autoShowChat,
|
||||
autoScrollChat = json.autoScrollChat ?: default.autoScrollChat,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ data class Settings(
|
|||
val playerName: String,
|
||||
val dynamicDice: Boolean,
|
||||
val autoHideChat: Boolean,
|
||||
val autoHideDelay: Int,
|
||||
val autoShowChat: Boolean,
|
||||
val autoScrollChat: Boolean,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ data class SettingsJsonV1(
|
|||
val playerName: String?,
|
||||
val dynamicDice: Boolean?,
|
||||
val autoHideChat: Boolean?,
|
||||
val autoHideDelay: Int?,
|
||||
val autoShowChat: Boolean?,
|
||||
val autoScrollChat: Boolean?,
|
||||
) : SettingsJson
|
||||
|
|
@ -42,10 +42,18 @@ class CampaignChatViewModel(
|
|||
)
|
||||
|
||||
suspend fun displayChat() {
|
||||
chatAnimatedVisibility.animateTo(1f)
|
||||
chatAnimatedVisibility.animateTo(
|
||||
targetValue = 1f,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun hideChat() {
|
||||
chatAnimatedVisibility.animateTo(0f, animationSpec = tween(2000, delayMillis = 8000))
|
||||
chatAnimatedVisibility.animateTo(
|
||||
targetValue = 0f,
|
||||
animationSpec = tween(
|
||||
durationMillis = 2000,
|
||||
delayMillis = settings.value.autoHideDelay * 1000,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
|
|||
import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
||||
import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository
|
||||
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -24,6 +25,7 @@ import java.text.Collator
|
|||
|
||||
class PlayerRibbonViewModel(
|
||||
private val rollHistoryRepository: RollHistoryRepository,
|
||||
private val settingsRepository: SettingsRepository,
|
||||
characterRepository: CharacterSheetRepository,
|
||||
alterationRepository: AlterationRepository,
|
||||
private val ribbonFactory: PlayerRibbonFactory,
|
||||
|
|
@ -68,6 +70,7 @@ class PlayerRibbonViewModel(
|
|||
val state = rolls.getOrPut(characterSheetId) { mutableStateOf(null) }
|
||||
LaunchedEffect(characterSheetId) {
|
||||
rollHistoryRepository.rolls.collect { roll ->
|
||||
if (settingsRepository.settings().dynamicDice) {
|
||||
if (roll.characterId == characterSheetId) {
|
||||
state.value = PlayerPortraitRollUio(
|
||||
characterId = characterSheetId,
|
||||
|
|
@ -77,6 +80,7 @@ class PlayerRibbonViewModel(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.pixelized.desktop.lwa.ui.screen.settings
|
|||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
|
|
@ -12,21 +13,38 @@ import androidx.compose.material.IconButton
|
|||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.material.TopAppBar
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.key.Key
|
||||
import androidx.compose.ui.input.key.KeyEventType
|
||||
import androidx.compose.ui.input.key.key
|
||||
import androidx.compose.ui.input.key.type
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.composable.key.KeyHandler
|
||||
import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController
|
||||
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.SettingsDestination
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingItemUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingNumberItem
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingNumberItemUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingSection
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingSectionUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingToggleItem
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingToggleItemUio
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__reset_action
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__title
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.koin.compose.viewmodel.koinViewModel
|
||||
|
||||
object SettingsScreenDefault {
|
||||
val margin: PaddingValues = PaddingValues(horizontal = 16.dp)
|
||||
val padding: PaddingValues = PaddingValues(start = 16.dp, top = 8.dp, end = 8.dp, bottom = 8.dp)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SettingsScreen(
|
||||
|
|
@ -34,13 +52,25 @@ fun SettingsScreen(
|
|||
) {
|
||||
val screen = LocalScreenController.current
|
||||
|
||||
KeyHandler {
|
||||
when {
|
||||
it.type == KeyEventType.KeyUp && it.key == Key.Escape -> {
|
||||
screen.popBackStack(route = SettingsDestination.baseRoute(), inclusive = true)
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
Surface {
|
||||
SettingsContent(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
items = viewModel.items,
|
||||
onBack = {
|
||||
screen.popBackStack()
|
||||
screen.popBackStack(route = SettingsDestination.baseRoute(), inclusive = true)
|
||||
},
|
||||
onReset = viewModel::onReset
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -52,13 +82,14 @@ private fun SettingsContent(
|
|||
spacing: Dp = 8.dp,
|
||||
items: List<SettingItemUio>,
|
||||
onBack: () -> Unit,
|
||||
onReset: () -> Unit,
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = {
|
||||
Text(text = "Paramètres de l\'application")
|
||||
Text(text = stringResource(Res.string.settings__title))
|
||||
},
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
|
|
@ -69,7 +100,14 @@ private fun SettingsContent(
|
|||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
TextButton(
|
||||
onClick = onReset,
|
||||
) {
|
||||
Text(text = stringResource(Res.string.settings__reset_action))
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
content = { paddingValues ->
|
||||
|
|
@ -81,17 +119,12 @@ private fun SettingsContent(
|
|||
) {
|
||||
items.forEach {
|
||||
when (it) {
|
||||
is SettingSectionUio -> {
|
||||
SettingSection(item = it)
|
||||
}
|
||||
|
||||
is SettingToggleItemUio -> {
|
||||
SettingToggleItem(item = it)
|
||||
}
|
||||
is SettingSectionUio -> SettingSection(item = it)
|
||||
is SettingToggleItemUio -> SettingToggleItem(item = it)
|
||||
is SettingNumberItemUio -> SettingNumberItem(item = it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,51 +5,90 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingNumberItemUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingSectionUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingToggleItemUio
|
||||
import com.pixelized.desktop.lwa.usecase.SettingsUseCase
|
||||
import kotlinx.coroutines.launch
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_fan_focus_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_ifl_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_timer_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_visibility_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_visibility_off_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_hide_delay_description
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_hide_delay_title
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_hide_description
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_hide_title
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_scroll_description
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_scroll_title
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_show_description
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_show_title
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__section
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__dyn_dice_description
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__dyn_dice_tile
|
||||
import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__section
|
||||
|
||||
|
||||
class SettingsViewModel(
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val settingsUseCase: SettingsUseCase,
|
||||
) : ViewModel() {
|
||||
private val settings = settingsRepository.settingsFlow()
|
||||
private val states = hashMapOf<String, MutableState<Boolean>>()
|
||||
private val booleanStates = hashMapOf<String, MutableState<Boolean>>()
|
||||
private val intStates = hashMapOf<String, MutableState<Int>>()
|
||||
|
||||
val items = listOf(
|
||||
SettingSectionUio(
|
||||
title = "Portrait joueurs."
|
||||
title = Res.string.settings__player_portrait__section,
|
||||
),
|
||||
SettingToggleItemUio(
|
||||
title = "Dés dynamiques",
|
||||
description = "Affiche un dés à côté du portrait d'un personnage lorsqu\'un jet est fait par ce dernier.",
|
||||
checked = states.dynamicDice,
|
||||
icon = Res.drawable.ic_ifl_24dp,
|
||||
title = Res.string.settings__player_portrait__dyn_dice_tile,
|
||||
description = Res.string.settings__player_portrait__dyn_dice_description,
|
||||
checked = booleanStates.dynamicDice,
|
||||
onToggle = {
|
||||
settingsRepository.update(settings = settings.value.copy(dynamicDice = it))
|
||||
},
|
||||
),
|
||||
SettingSectionUio(
|
||||
title = "Chatlog options."
|
||||
title = Res.string.settings__chat_log__section,
|
||||
),
|
||||
SettingToggleItemUio(
|
||||
title = "Afficher automatiquement",
|
||||
description = "Affiche automatiquement le chat lors de la réception d'un message.",
|
||||
checked = states.autoShowChat,
|
||||
icon = Res.drawable.ic_visibility_24dp,
|
||||
title = Res.string.settings__chat_log__auto_show_title,
|
||||
description = Res.string.settings__chat_log__auto_show_description,
|
||||
checked = booleanStates.autoShowChat,
|
||||
onToggle = {
|
||||
settingsRepository.update(settings = settings.value.copy(autoShowChat = it))
|
||||
},
|
||||
),
|
||||
SettingToggleItemUio(
|
||||
title = "Cacher automatiquement",
|
||||
description = "Cache automatiquement le chat au bout d'un certain temps.",
|
||||
checked = states.autoHideChat,
|
||||
icon = Res.drawable.ic_visibility_off_24dp,
|
||||
title = Res.string.settings__chat_log__auto_hide_title,
|
||||
description = Res.string.settings__chat_log__auto_hide_description,
|
||||
checked = booleanStates.autoHideChat,
|
||||
onToggle = {
|
||||
settingsRepository.update(settings = settings.value.copy(autoHideChat = it))
|
||||
},
|
||||
),
|
||||
SettingNumberItemUio(
|
||||
icon = Res.drawable.ic_timer_24dp,
|
||||
title = Res.string.settings__chat_log__auto_hide_delay_title,
|
||||
description = Res.string.settings__chat_log__auto_hide_delay_description,
|
||||
enable = booleanStates.autoHideChat,
|
||||
value = intStates.autoHideDelay,
|
||||
onValueChange = {
|
||||
if (it in 0..999) {
|
||||
settingsRepository.update(settings = settings.value.copy(autoHideDelay = it))
|
||||
}
|
||||
}
|
||||
),
|
||||
SettingToggleItemUio(
|
||||
title = "Défilement automatique",
|
||||
description = "Défilement automatique de chat vers le dernier message reçu lors de la réception de ce dernier.",
|
||||
checked = states.autoScrollChat,
|
||||
icon = Res.drawable.ic_fan_focus_24dp,
|
||||
title = Res.string.settings__chat_log__auto_scroll_title,
|
||||
description = Res.string.settings__chat_log__auto_scroll_description,
|
||||
checked = booleanStates.autoScrollChat,
|
||||
onToggle = {
|
||||
settingsRepository.update(settings = settings.value.copy(autoScrollChat = it))
|
||||
},
|
||||
|
|
@ -59,14 +98,19 @@ class SettingsViewModel(
|
|||
init {
|
||||
viewModelScope.launch {
|
||||
settingsRepository.settingsFlow().collect { settings ->
|
||||
states.dynamicDice.value = settings.dynamicDice
|
||||
states.autoShowChat.value = settings.autoShowChat
|
||||
states.autoHideChat.value = settings.autoHideChat
|
||||
states.autoScrollChat.value = settings.autoScrollChat
|
||||
booleanStates.dynamicDice.value = settings.dynamicDice
|
||||
booleanStates.autoShowChat.value = settings.autoShowChat
|
||||
booleanStates.autoHideChat.value = settings.autoHideChat
|
||||
intStates.autoHideDelay.value = settings.autoHideDelay
|
||||
booleanStates.autoScrollChat.value = settings.autoScrollChat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onReset() {
|
||||
settingsRepository.update(settings = settingsUseCase.defaultSettings())
|
||||
}
|
||||
|
||||
private val HashMap<String, MutableState<Boolean>>.dynamicDice
|
||||
get() = getOrPut("DYNAMIC_DICE") { mutableStateOf(settings.value.dynamicDice) }
|
||||
|
||||
|
|
@ -76,6 +120,9 @@ class SettingsViewModel(
|
|||
private val HashMap<String, MutableState<Boolean>>.autoHideChat
|
||||
get() = getOrPut("AUTO_HIDE_CHAT") { mutableStateOf(settings.value.autoHideChat) }
|
||||
|
||||
private val HashMap<String, MutableState<Int>>.autoHideDelay
|
||||
get() = getOrPut("AUTO_HIDE_DELAY") { mutableStateOf(settings.value.autoHideDelay) }
|
||||
|
||||
private val HashMap<String, MutableState<Boolean>>.autoScrollChat
|
||||
get() = getOrPut("AUTO_SCROLL_CHAT") { mutableStateOf(settings.value.autoScrollChat) }
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
package com.pixelized.desktop.lwa.ui.screen.settings.composable
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.SettingsScreenDefault
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import org.jetbrains.compose.resources.DrawableResource
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
||||
@Stable
|
||||
data class SettingNumberItemUio(
|
||||
val icon: DrawableResource,
|
||||
val title: StringResource,
|
||||
val description: StringResource,
|
||||
val enable: State<Boolean>,
|
||||
val value: State<Int>,
|
||||
val onValueChange: (Int) -> Unit,
|
||||
) : SettingItemUio
|
||||
|
||||
@Composable
|
||||
fun SettingNumberItem(
|
||||
modifier: Modifier = Modifier,
|
||||
margin: PaddingValues = SettingsScreenDefault.margin,
|
||||
padding: PaddingValues = SettingsScreenDefault.padding,
|
||||
spacing: DpSize = DpSize(width = 16.dp, height = 8.dp),
|
||||
item: SettingNumberItemUio,
|
||||
) {
|
||||
val colorScheme = MaterialTheme.lwa.colorScheme
|
||||
|
||||
Surface(
|
||||
modifier = modifier.padding(paddingValues = margin),
|
||||
shape = MaterialTheme.lwa.shapes.settings,
|
||||
elevation = 1.dp,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(paddingValues = padding),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = spacing.width),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(size = 24.dp),
|
||||
painter = painterResource(item.icon),
|
||||
contentDescription = null,
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
verticalArrangement = Arrangement.spacedBy(space = spacing.height),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.settings.title,
|
||||
maxLines = 1,
|
||||
text = stringResource(resource = item.title),
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.settings.description,
|
||||
fontStyle = FontStyle.Italic,
|
||||
text = stringResource(resource = item.description),
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
val focused = remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
val textColor = remember(item) {
|
||||
derivedStateOf {
|
||||
when (item.enable.value) {
|
||||
true -> colorScheme.base.primary
|
||||
else -> colorScheme.base.onSurface.copy(alpha = 0.3f)
|
||||
}
|
||||
}
|
||||
}
|
||||
val borderColor = remember(item, focused) {
|
||||
derivedStateOf {
|
||||
when (focused.value) {
|
||||
true -> colorScheme.base.primary
|
||||
else -> colorScheme.base.onSurface.copy(alpha = 0.3f)
|
||||
}
|
||||
}
|
||||
}
|
||||
BasicTextField(
|
||||
modifier = Modifier
|
||||
.onFocusChanged { focused.value = it.isFocused }
|
||||
.width(width = 44.dp)
|
||||
.padding(horizontal = 2.dp),
|
||||
textStyle = MaterialTheme.lwa.typography.settings.input.copy(
|
||||
color = textColor.value,
|
||||
),
|
||||
cursorBrush = SolidColor(MaterialTheme.colors.primary),
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
singleLine = true,
|
||||
enabled = item.enable.value,
|
||||
value = "${item.value.value}",
|
||||
onValueChange = { item.onValueChange(it.toIntOrNull() ?: 0) },
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.background(color = borderColor.value)
|
||||
.size(width = 48.dp, height = 2.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,23 +8,26 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.SettingsScreenDefault
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
||||
@Stable
|
||||
data class SettingSectionUio(
|
||||
val title: String,
|
||||
val title: StringResource,
|
||||
) : SettingItemUio
|
||||
|
||||
@Composable
|
||||
fun SettingSection(
|
||||
modifier: Modifier = Modifier,
|
||||
padding: PaddingValues = PaddingValues(start = 16.dp, top = 32.dp, end = 16.dp),
|
||||
padding: PaddingValues = PaddingValues(start = 16.dp, top = 32.dp, end = 16.dp, bottom = 16.dp),
|
||||
item: SettingSectionUio,
|
||||
) {
|
||||
Text(
|
||||
modifier = modifier.padding(paddingValues = padding),
|
||||
style = MaterialTheme.lwa.typography.base.h6,
|
||||
style = MaterialTheme.lwa.typography.settings.section,
|
||||
maxLines = 1,
|
||||
text = item.title,
|
||||
text = stringResource(resource = item.title),
|
||||
)
|
||||
}
|
||||
|
|
@ -5,23 +5,34 @@ import androidx.compose.foundation.layout.Column
|
|||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Switch
|
||||
import androidx.compose.material.SwitchDefaults
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.SettingsScreenDefault
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import org.jetbrains.compose.resources.DrawableResource
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
||||
@Stable
|
||||
data class SettingToggleItemUio(
|
||||
val title: String,
|
||||
val description: String,
|
||||
val icon: DrawableResource,
|
||||
val title: StringResource,
|
||||
val description: StringResource,
|
||||
val checked: State<Boolean>,
|
||||
val onToggle: (Boolean) -> Unit,
|
||||
) : SettingItemUio
|
||||
|
|
@ -29,27 +40,39 @@ data class SettingToggleItemUio(
|
|||
@Composable
|
||||
fun SettingToggleItem(
|
||||
modifier: Modifier = Modifier,
|
||||
padding: PaddingValues = PaddingValues(start = 16.dp, top = 8.dp, end = 16.dp),
|
||||
spacing: Dp = 8.dp,
|
||||
margin: PaddingValues = SettingsScreenDefault.margin,
|
||||
padding: PaddingValues = SettingsScreenDefault.padding,
|
||||
spacing: DpSize = DpSize(width = 16.dp, height = 8.dp),
|
||||
item: SettingToggleItemUio,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier.padding(paddingValues = padding),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = spacing),
|
||||
Surface(
|
||||
modifier = modifier.padding(paddingValues = margin),
|
||||
shape = MaterialTheme.lwa.shapes.settings,
|
||||
elevation = 1.dp,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(paddingValues = padding),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = spacing.width),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(size = 24.dp),
|
||||
painter = painterResource(item.icon),
|
||||
contentDescription = null,
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
verticalArrangement = Arrangement.spacedBy(space = spacing),
|
||||
verticalArrangement = Arrangement.spacedBy(space = spacing.height),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.base.body1,
|
||||
style = MaterialTheme.lwa.typography.settings.title,
|
||||
maxLines = 1,
|
||||
text = item.title,
|
||||
text = stringResource(resource = item.title),
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.base.caption,
|
||||
style = MaterialTheme.lwa.typography.settings.description,
|
||||
fontStyle = FontStyle.Italic,
|
||||
text = item.description,
|
||||
text = stringResource(resource = item.description),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -62,3 +85,4 @@ fun SettingToggleItem(
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@ import androidx.compose.runtime.compositionLocalOf
|
|||
import androidx.compose.runtime.remember
|
||||
import com.pixelized.desktop.lwa.ui.theme.color.LwaColors
|
||||
import com.pixelized.desktop.lwa.ui.theme.color.darkLwaColorTheme
|
||||
import com.pixelized.desktop.lwa.ui.theme.shapes.LwaShapes
|
||||
import com.pixelized.desktop.lwa.ui.theme.shapes.lwaShapes
|
||||
import com.pixelized.desktop.lwa.ui.theme.typography.LwaTypography
|
||||
import com.pixelized.desktop.lwa.ui.theme.typography.lwaTypography
|
||||
|
||||
|
|
@ -24,6 +26,7 @@ val MaterialTheme.lwa: LwaTheme
|
|||
data class LwaTheme(
|
||||
val colorScheme: LwaColors,
|
||||
val typography: LwaTypography,
|
||||
val shapes: LwaShapes,
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
|
@ -32,11 +35,13 @@ fun LwaTheme(
|
|||
) {
|
||||
val lwaColors = darkLwaColorTheme()
|
||||
val lwaTypography = lwaTypography(colors = lwaColors)
|
||||
val lwaShapes = lwaShapes()
|
||||
|
||||
val theme = remember {
|
||||
LwaTheme(
|
||||
colorScheme = lwaColors,
|
||||
typography = lwaTypography,
|
||||
shapes = lwaShapes,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package com.pixelized.desktop.lwa.ui.theme.shapes
|
||||
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Stable
|
||||
data class LwaShapes(
|
||||
val settings: Shape,
|
||||
)
|
||||
|
||||
@Stable
|
||||
@Composable
|
||||
fun lwaShapes(
|
||||
settings: Shape = RoundedCornerShape(8.dp),
|
||||
): LwaShapes = remember {
|
||||
LwaShapes(
|
||||
settings = settings,
|
||||
)
|
||||
}
|
||||
|
|
@ -6,9 +6,12 @@ import androidx.compose.runtime.Stable
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.pixelized.desktop.lwa.ui.theme.color.LwaColors
|
||||
import com.pixelized.desktop.lwa.ui.theme.typography.LwaTypography.Settings
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.consola_mono_bold
|
||||
import lwacharactersheet.composeapp.generated.resources.consola_mono_book
|
||||
|
|
@ -18,12 +21,21 @@ import org.jetbrains.compose.resources.Font
|
|||
data class LwaTypography(
|
||||
val base: Typography,
|
||||
val chat: Chat,
|
||||
val settings: Settings,
|
||||
) {
|
||||
@Stable
|
||||
data class Chat(
|
||||
val timestamp: TextStyle,
|
||||
val text: TextStyle,
|
||||
)
|
||||
|
||||
@Stable
|
||||
data class Settings(
|
||||
val section: TextStyle,
|
||||
val title: TextStyle,
|
||||
val input: TextStyle,
|
||||
val description: TextStyle,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -62,6 +74,22 @@ fun lwaTypography(
|
|||
letterSpacing = 0.4.sp,
|
||||
color = colors.chat.text,
|
||||
),
|
||||
),
|
||||
settings = Settings(
|
||||
section = base.h6,
|
||||
title = base.body1.copy(
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
),
|
||||
input = base.body1.copy(
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 18.sp,
|
||||
lineHeight = 26.sp,
|
||||
textAlign = TextAlign.End,
|
||||
),
|
||||
description = base.caption.copy(
|
||||
fontStyle = FontStyle.Italic,
|
||||
color = colors.base.onSurface.copy(alpha = 0.7f),
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ class SettingsUseCase {
|
|||
playerName = "",
|
||||
dynamicDice = true,
|
||||
autoHideChat = true,
|
||||
autoHideDelay = 8,
|
||||
autoShowChat = true,
|
||||
autoScrollChat = true,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue