Refactor the setting data class + change the roll text message
This commit is contained in:
parent
353183f0f5
commit
07ed4ce579
15 changed files with 216 additions and 93 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="M120,880v-60h100v-30h-60v-60h60v-30L120,700v-60h120q17,0 28.5,11.5T280,680v40q0,17 -11.5,28.5T240,760q17,0 28.5,11.5T280,800v40q0,17 -11.5,28.5T240,880L120,880ZM120,600v-110q0,-17 11.5,-28.5T160,450h60v-30L120,420v-60h120q17,0 28.5,11.5T280,400v70q0,17 -11.5,28.5T240,510h-60v30h100v60L120,600ZM180,320v-180h-60v-60h120v240h-60ZM360,760v-80h480v80L360,760ZM360,520v-80h480v80L360,520ZM360,280v-80h480v80L360,280Z"
|
||||||
|
android:fillColor="#5f6368"/>
|
||||||
|
</vector>
|
||||||
|
|
@ -207,6 +207,8 @@
|
||||||
<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_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_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>
|
<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>
|
||||||
|
<string name="settings__chat_log__line_count_title">Nombre de lignes de textes visibles</string>
|
||||||
|
<string name="settings__chat_log__line_count_description">Limite le nombre maximale de messages affichés par le chat.</string>
|
||||||
|
|
||||||
<string name="level_up__title">Montée de niveau</string>
|
<string name="level_up__title">Montée de niveau</string>
|
||||||
<string name="level_up__action">Level Up !</string>
|
<string name="level_up__action">Level Up !</string>
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ class DataSyncViewModel(
|
||||||
if (settings.playerName.isEmpty()) return
|
if (settings.playerName.isEmpty()) return
|
||||||
|
|
||||||
networkRepository.connect(
|
networkRepository.connect(
|
||||||
host = settings.host,
|
host = settings.network.host,
|
||||||
port = settings.port,
|
port = settings.network.port,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class LwaClientImpl(
|
||||||
private val client: HttpClient,
|
private val client: HttpClient,
|
||||||
setting: SettingsRepository,
|
setting: SettingsRepository,
|
||||||
) : LwaClient {
|
) : LwaClient {
|
||||||
private val root = setting.settings().root
|
private val root = setting.settings().network.root
|
||||||
|
|
||||||
override suspend fun characters(): List<CharacterPreviewJson> = client
|
override suspend fun characters(): List<CharacterPreviewJson> = client
|
||||||
.get("$root/characters")
|
.get("$root/characters")
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,15 @@ class SettingsFactory(
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
): SettingsJson {
|
): SettingsJson {
|
||||||
return SettingsJsonV1(
|
return SettingsJsonV1(
|
||||||
host = settings.host,
|
host = settings.network.host,
|
||||||
port = settings.port,
|
port = settings.network.port,
|
||||||
playerName = settings.playerName,
|
playerName = settings.playerName,
|
||||||
dynamicDice = settings.dynamicDice,
|
dynamicDice = settings.portrait.dynamicDice,
|
||||||
autoHideChat = settings.autoHideChat,
|
autoHideChat = settings.chat.autoHideChat,
|
||||||
autoHideDelay = settings.autoHideDelay,
|
autoHideDelay = settings.chat.autoHideDelay,
|
||||||
autoShowChat = settings.autoShowChat,
|
autoShowChat = settings.chat.autoShowChat,
|
||||||
autoScrollChat = settings.autoScrollChat,
|
autoScrollChat = settings.chat.autoScrollChat,
|
||||||
|
maxLineCount = settings.chat.maxLineCount,
|
||||||
isAdmin = settings.isAdmin,
|
isAdmin = settings.isAdmin,
|
||||||
isGameMaster = settings.isGameMaster,
|
isGameMaster = settings.isGameMaster,
|
||||||
)
|
)
|
||||||
|
|
@ -39,14 +40,21 @@ class SettingsFactory(
|
||||||
): Settings {
|
): Settings {
|
||||||
val default = useCase.defaultSettings()
|
val default = useCase.defaultSettings()
|
||||||
return Settings(
|
return Settings(
|
||||||
host = json.host ?: default.host,
|
|
||||||
port = json.port ?: default.port,
|
|
||||||
playerName = json.playerName ?: default.playerName,
|
playerName = json.playerName ?: default.playerName,
|
||||||
dynamicDice = json.dynamicDice ?: default.dynamicDice,
|
network = Settings.Network(
|
||||||
autoHideChat = json.autoHideChat ?: default.autoHideChat,
|
host = json.host ?: default.network.host,
|
||||||
autoHideDelay = json.autoHideDelay ?: default.autoHideDelay,
|
port = json.port ?: default.network.port,
|
||||||
autoShowChat = json.autoShowChat ?: default.autoShowChat,
|
),
|
||||||
autoScrollChat = json.autoScrollChat ?: default.autoScrollChat,
|
portrait = Settings.Portrait(
|
||||||
|
dynamicDice = json.dynamicDice ?: default.portrait.dynamicDice,
|
||||||
|
),
|
||||||
|
chat = Settings.Chat(
|
||||||
|
autoHideChat = json.autoHideChat ?: default.chat.autoHideChat,
|
||||||
|
autoHideDelay = json.autoHideDelay ?: default.chat.autoHideDelay,
|
||||||
|
autoShowChat = json.autoShowChat ?: default.chat.autoShowChat,
|
||||||
|
autoScrollChat = json.autoScrollChat ?: default.chat.autoScrollChat,
|
||||||
|
maxLineCount = json.maxLineCount ?: default.chat.maxLineCount,
|
||||||
|
),
|
||||||
isAdmin = json.isAdmin ?: default.isAdmin,
|
isAdmin = json.isAdmin ?: default.isAdmin,
|
||||||
isGameMaster = json.isGameMaster ?: default.isGameMaster,
|
isGameMaster = json.isGameMaster ?: default.isGameMaster,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,29 @@
|
||||||
package com.pixelized.desktop.lwa.repository.settings.model
|
package com.pixelized.desktop.lwa.repository.settings.model
|
||||||
|
|
||||||
data class Settings(
|
data class Settings(
|
||||||
val host: String,
|
|
||||||
val port: Int,
|
|
||||||
val playerName: String,
|
val playerName: String,
|
||||||
|
val portrait: Portrait,
|
||||||
|
val chat: Chat,
|
||||||
|
val network: Network,
|
||||||
|
val isAdmin: Boolean? = null,
|
||||||
|
val isGameMaster: Boolean? = null,
|
||||||
|
) {
|
||||||
|
data class Portrait(
|
||||||
val dynamicDice: Boolean,
|
val dynamicDice: Boolean,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Chat(
|
||||||
val autoHideChat: Boolean,
|
val autoHideChat: Boolean,
|
||||||
val autoHideDelay: Int,
|
val autoHideDelay: Int,
|
||||||
val autoShowChat: Boolean,
|
val autoShowChat: Boolean,
|
||||||
val autoScrollChat: Boolean,
|
val autoScrollChat: Boolean,
|
||||||
val isAdmin: Boolean? = null,
|
val maxLineCount: Int,
|
||||||
val isGameMaster: Boolean? = null,
|
)
|
||||||
|
|
||||||
|
data class Network(
|
||||||
|
val host: String,
|
||||||
|
val port: Int,
|
||||||
) {
|
) {
|
||||||
val root: String get() = "http://${"${host}:${port}".removePrefix("http://")}"
|
val root: String get() = "http://${"${host}:${port}".removePrefix("http://")}"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,7 @@ data class SettingsJsonV1(
|
||||||
val autoHideDelay: Int?,
|
val autoHideDelay: Int?,
|
||||||
val autoShowChat: Boolean?,
|
val autoShowChat: Boolean?,
|
||||||
val autoScrollChat: Boolean?,
|
val autoScrollChat: Boolean?,
|
||||||
|
val maxLineCount: Int?,
|
||||||
val isGameMaster: Boolean?,
|
val isGameMaster: Boolean?,
|
||||||
val isAdmin: Boolean?,
|
val isAdmin: Boolean?,
|
||||||
) : SettingsJson
|
) : SettingsJson
|
||||||
|
|
@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||||
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
||||||
|
import com.pixelized.desktop.lwa.repository.settings.model.Settings
|
||||||
import com.pixelized.desktop.lwa.ui.composable.blur.BlurContentController
|
import com.pixelized.desktop.lwa.ui.composable.blur.BlurContentController
|
||||||
import com.pixelized.desktop.lwa.ui.composable.error.ErrorSnackUio
|
import com.pixelized.desktop.lwa.ui.composable.error.ErrorSnackUio
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
|
|
@ -32,8 +33,8 @@ class NetworkViewModel(
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
private val settings = settingsRepository.settings()
|
private val settings = settingsRepository.settings()
|
||||||
private val nameFlow = MutableStateFlow(settings.playerName)
|
private val nameFlow = MutableStateFlow(settings.playerName)
|
||||||
private val hostFlow = MutableStateFlow(settings.host)
|
private val hostFlow = MutableStateFlow(settings.network.host)
|
||||||
private val portFlow = MutableStateFlow(settings.port)
|
private val portFlow = MutableStateFlow(settings.network.port)
|
||||||
|
|
||||||
private val _networkError = MutableSharedFlow<ErrorSnackUio>()
|
private val _networkError = MutableSharedFlow<ErrorSnackUio>()
|
||||||
val networkError: SharedFlow<ErrorSnackUio> get() = _networkError
|
val networkError: SharedFlow<ErrorSnackUio> get() = _networkError
|
||||||
|
|
@ -57,9 +58,9 @@ class NetworkViewModel(
|
||||||
player = name,
|
player = name,
|
||||||
status = status,
|
status = status,
|
||||||
host = host,
|
host = host,
|
||||||
resetHost = settings.host != host,
|
resetHost = settings.network.host != host,
|
||||||
port = port,
|
port = port,
|
||||||
resetPort = settings.port != port,
|
resetPort = settings.network.port != port,
|
||||||
)
|
)
|
||||||
}.stateIn(
|
}.stateIn(
|
||||||
scope = viewModelScope,
|
scope = viewModelScope,
|
||||||
|
|
@ -71,8 +72,8 @@ class NetworkViewModel(
|
||||||
settingsRepository.settingsFlow()
|
settingsRepository.settingsFlow()
|
||||||
.onEach {
|
.onEach {
|
||||||
nameFlow.value = it.playerName
|
nameFlow.value = it.playerName
|
||||||
hostFlow.value = it.host
|
hostFlow.value = it.network.host
|
||||||
portFlow.value = it.port
|
portFlow.value = it.network.port
|
||||||
}
|
}
|
||||||
.launchIn(viewModelScope)
|
.launchIn(viewModelScope)
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +87,7 @@ class NetworkViewModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onResetPortChange() {
|
fun onResetPortChange() {
|
||||||
portFlow.value = settings.port
|
portFlow.value = settings.network.port
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onHostChange(host: String) {
|
fun onHostChange(host: String) {
|
||||||
|
|
@ -94,7 +95,7 @@ class NetworkViewModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onResetHostChange() {
|
fun onResetHostChange() {
|
||||||
hostFlow.value = settings.host
|
hostFlow.value = settings.network.host
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun connect() {
|
suspend fun connect() {
|
||||||
|
|
@ -103,14 +104,16 @@ class NetworkViewModel(
|
||||||
|
|
||||||
if (
|
if (
|
||||||
settings.playerName != nameFlow.value ||
|
settings.playerName != nameFlow.value ||
|
||||||
settings.host != hostFlow.value ||
|
settings.network.host != hostFlow.value ||
|
||||||
settings.port != portFlow.value
|
settings.network.port != portFlow.value
|
||||||
) {
|
) {
|
||||||
settingsRepository.update(
|
settingsRepository.update(
|
||||||
settings = settings.copy(
|
settings = settings.copy(
|
||||||
playerName = nameFlow.value,
|
playerName = nameFlow.value,
|
||||||
|
network = Settings.Network(
|
||||||
host = hostFlow.value,
|
host = hostFlow.value,
|
||||||
port = portFlow.value
|
port = portFlow.value,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ abstract class CharacterRibbonViewModel(
|
||||||
settingsRepository.settingsFlow(),
|
settingsRepository.settingsFlow(),
|
||||||
rollHistoryRepository.rolls,
|
rollHistoryRepository.rolls,
|
||||||
) { settings, roll ->
|
) { settings, roll ->
|
||||||
if (settings.dynamicDice &&
|
if (settings.portrait.dynamicDice &&
|
||||||
characterId.equals(roll.prefix, roll.characterSheetId, roll.instanceId)
|
characterId.equals(roll.prefix, roll.characterSheetId, roll.instanceId)
|
||||||
) {
|
) {
|
||||||
state.value = CharacterPortraitRollUio(
|
state.value = CharacterPortraitRollUio(
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.max
|
import androidx.compose.ui.unit.max
|
||||||
import androidx.compose.ui.unit.min
|
import androidx.compose.ui.unit.min
|
||||||
import androidx.compose.ui.window.WindowState
|
import androidx.compose.ui.window.WindowState
|
||||||
import com.pixelized.desktop.lwa.repository.settings.model.Settings
|
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.window.LocalWindowState
|
import com.pixelized.desktop.lwa.ui.navigation.window.LocalWindowState
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.CampaignLayoutScope
|
import com.pixelized.desktop.lwa.ui.screen.campaign.CampaignLayoutScope
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.LocalCampaignLayoutScope
|
import com.pixelized.desktop.lwa.ui.screen.campaign.LocalCampaignLayoutScope
|
||||||
|
|
@ -45,9 +44,27 @@ import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.RollTextMessag
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.RollTextMessageUio
|
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.RollTextMessageUio
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.TextMessage
|
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.TextMessage
|
||||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||||
|
import com.pixelized.desktop.lwa.usecase.SettingsUseCase
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.compose.viewmodel.koinViewModel
|
import org.koin.compose.viewmodel.koinViewModel
|
||||||
|
|
||||||
|
@Stable
|
||||||
|
data class ChatSettingsUio(
|
||||||
|
val autoShowChat: Boolean,
|
||||||
|
val autoScrollChat: Boolean,
|
||||||
|
val autoHideChat: Boolean,
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun default() = with(SettingsUseCase().defaultSettings()) {
|
||||||
|
ChatSettingsUio(
|
||||||
|
autoShowChat = chat.autoShowChat,
|
||||||
|
autoScrollChat = chat.autoScrollChat,
|
||||||
|
autoHideChat = chat.autoHideChat,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CampaignChat(
|
fun CampaignChat(
|
||||||
|
|
@ -119,7 +136,7 @@ fun CampaignChat(
|
||||||
private fun ChatScrollDownEffect(
|
private fun ChatScrollDownEffect(
|
||||||
lazyState: LazyListState,
|
lazyState: LazyListState,
|
||||||
messages: State<List<TextMessage>>,
|
messages: State<List<TextMessage>>,
|
||||||
settings: State<Settings>,
|
settings: State<ChatSettingsUio>,
|
||||||
displayChat: suspend () -> Unit,
|
displayChat: suspend () -> Unit,
|
||||||
hideChat: suspend () -> Unit,
|
hideChat: suspend () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -6,39 +6,53 @@ import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||||
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.TextMessage
|
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.mapNotNull
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.runningFold
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
|
|
||||||
class CampaignChatViewModel(
|
class CampaignChatViewModel(
|
||||||
|
private val settingsRepository: SettingsRepository,
|
||||||
networkRepository: NetworkRepository,
|
networkRepository: NetworkRepository,
|
||||||
textMessageFactory: TextMessageFactory,
|
textMessageFactory: TextMessageFactory,
|
||||||
settingsRepository: SettingsRepository,
|
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
val settings = settingsRepository.settingsFlow()
|
|
||||||
|
|
||||||
val chatAnimatedVisibility = Animatable(0f)
|
val chatAnimatedVisibility = Animatable(0f)
|
||||||
|
|
||||||
private var _messages = emptyList<TextMessage>()
|
val settings = settingsRepository.settingsFlow().map {
|
||||||
val messages: StateFlow<List<TextMessage>> = networkRepository.data
|
ChatSettingsUio(
|
||||||
.mapNotNull { message ->
|
autoShowChat = it.chat.autoShowChat,
|
||||||
val text = textMessageFactory
|
autoScrollChat = it.chat.autoScrollChat,
|
||||||
.convertToTextMessage(message = message)
|
autoHideChat = it.chat.autoHideChat,
|
||||||
?: return@mapNotNull _messages
|
)
|
||||||
|
}.stateIn(
|
||||||
_messages = _messages.toMutableList().also {
|
|
||||||
it.add(index = it.lastIndex + 1, element = text)
|
|
||||||
}
|
|
||||||
_messages
|
|
||||||
}
|
|
||||||
.stateIn(
|
|
||||||
scope = viewModelScope,
|
scope = viewModelScope,
|
||||||
started = SharingStarted.Eagerly,
|
started = SharingStarted.Eagerly,
|
||||||
initialValue = _messages,
|
initialValue = ChatSettingsUio.default(),
|
||||||
|
)
|
||||||
|
|
||||||
|
val messages = combine(
|
||||||
|
settingsRepository.settingsFlow(),
|
||||||
|
networkRepository.data.runningFold(
|
||||||
|
initial = mutableListOf(),
|
||||||
|
operation = List<SocketMessage>::plus
|
||||||
|
)
|
||||||
|
) { settings, messages ->
|
||||||
|
messages.mapNotNull { message ->
|
||||||
|
textMessageFactory.convertToTextMessage(
|
||||||
|
settings = settings,
|
||||||
|
message = message,
|
||||||
|
)
|
||||||
|
}.takeLast(
|
||||||
|
n = settings.chat.maxLineCount,
|
||||||
|
)
|
||||||
|
}.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.Eagerly,
|
||||||
|
initialValue = emptyList(),
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun displayChat() {
|
suspend fun displayChat() {
|
||||||
|
|
@ -48,11 +62,12 @@ class CampaignChatViewModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun hideChat() {
|
suspend fun hideChat() {
|
||||||
|
val settings = settingsRepository.settingsFlow().value
|
||||||
chatAnimatedVisibility.animateTo(
|
chatAnimatedVisibility.animateTo(
|
||||||
targetValue = 0f,
|
targetValue = 0f,
|
||||||
animationSpec = tween(
|
animationSpec = tween(
|
||||||
durationMillis = 2000,
|
durationMillis = 2000,
|
||||||
delayMillis = settings.value.autoHideDelay * 1000,
|
delayMillis = settings.chat.autoHideDelay * 1000,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
package com.pixelized.desktop.lwa.ui.screen.campaign.text
|
package com.pixelized.desktop.lwa.ui.screen.campaign.text
|
||||||
|
|
||||||
import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
|
|
||||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
||||||
|
import com.pixelized.desktop.lwa.repository.settings.model.Settings
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.CharacteristicTextMessageUio
|
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.CharacteristicTextMessageUio
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.DiminishedTextMessageUio
|
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.DiminishedTextMessageUio
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.RollTextMessageUio
|
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.RollTextMessageUio
|
||||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.TextMessage
|
import com.pixelized.desktop.lwa.ui.screen.campaign.text.messages.TextMessage
|
||||||
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
|
|
||||||
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Damage
|
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Damage
|
||||||
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Power
|
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Power
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
|
||||||
|
|
@ -26,13 +25,12 @@ import kotlin.math.abs
|
||||||
|
|
||||||
class TextMessageFactory(
|
class TextMessageFactory(
|
||||||
private val characterSheetRepository: CharacterSheetRepository,
|
private val characterSheetRepository: CharacterSheetRepository,
|
||||||
private val alterationRepository: AlterationRepository,
|
|
||||||
private val alteredCharacterSheetFactory: AlteredCharacterSheetFactory,
|
|
||||||
) {
|
) {
|
||||||
private val formatId = SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS")
|
private val formatId = SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS")
|
||||||
private val formatTime = SimpleDateFormat("HH:mm:ss")
|
private val formatTime = SimpleDateFormat("HH:mm:ss")
|
||||||
|
|
||||||
suspend fun convertToTextMessage(
|
suspend fun convertToTextMessage(
|
||||||
|
settings: Settings,
|
||||||
message: SocketMessage,
|
message: SocketMessage,
|
||||||
): TextMessage? {
|
): TextMessage? {
|
||||||
val time = message.timestamp
|
val time = message.timestamp
|
||||||
|
|
@ -44,6 +42,8 @@ class TextMessageFactory(
|
||||||
.characterPreview(characterId = message.characterSheetId)
|
.characterPreview(characterId = message.characterSheetId)
|
||||||
?: return null
|
?: return null
|
||||||
|
|
||||||
|
val isGm = settings.isGameMaster ?: false
|
||||||
|
|
||||||
RollTextMessageUio(
|
RollTextMessageUio(
|
||||||
id = "${message.uuid}-${message.timestamp}",
|
id = "${message.uuid}-${message.timestamp}",
|
||||||
timestamp = formatTime.format(time),
|
timestamp = formatTime.format(time),
|
||||||
|
|
@ -51,7 +51,7 @@ class TextMessageFactory(
|
||||||
skillLabel = message.skillLabel,
|
skillLabel = message.skillLabel,
|
||||||
rollDifficulty = message.rollDifficulty,
|
rollDifficulty = message.rollDifficulty,
|
||||||
rollValue = message.rollValue,
|
rollValue = message.rollValue,
|
||||||
rollSuccessLimit = message.rollSuccessLimit,
|
rollSuccessLimit = takeIf { isGm }?.let { message.rollSuccessLimit },
|
||||||
resultLabel = message.resultLabel,
|
resultLabel = message.resultLabel,
|
||||||
resultType = when (message.critical) {
|
resultType = when (message.critical) {
|
||||||
RollMessage.Critical.CRITICAL_SUCCESS -> RollTextMessageUio.Critical.CRITICAL_SUCCESS
|
RollMessage.Critical.CRITICAL_SUCCESS -> RollTextMessageUio.Critical.CRITICAL_SUCCESS
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||||
|
|
@ -72,7 +71,6 @@ fun RollTextMessage(
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.alignByBaseline(),
|
modifier = Modifier.alignByBaseline(),
|
||||||
style = MaterialTheme.lwa.typography.chat.text,
|
style = MaterialTheme.lwa.typography.chat.text,
|
||||||
fontWeight = FontWeight.ExtraLight,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
text = stringResource(Res.string.roll_history__item__throw),
|
text = stringResource(Res.string.roll_history__item__throw),
|
||||||
|
|
@ -114,7 +112,7 @@ fun RollTextMessage(
|
||||||
style = MaterialTheme.lwa.typography.chat.text,
|
style = MaterialTheme.lwa.typography.chat.text,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
text = "${message.rollValue}",
|
text = "(${message.rollValue}",
|
||||||
)
|
)
|
||||||
message.rollSuccessLimit?.let {
|
message.rollSuccessLimit?.let {
|
||||||
Text(
|
Text(
|
||||||
|
|
@ -125,6 +123,13 @@ fun RollTextMessage(
|
||||||
text = "/$it",
|
text = "/$it",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.alignByBaseline(),
|
||||||
|
style = MaterialTheme.lwa.typography.chat.text,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines = 1,
|
||||||
|
text = ")",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
message.rollDifficulty?.let {
|
message.rollDifficulty?.let {
|
||||||
Text(
|
Text(
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import com.pixelized.desktop.lwa.usecase.SettingsUseCase
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import lwacharactersheet.composeapp.generated.resources.Res
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
import lwacharactersheet.composeapp.generated.resources.ic_fan_focus_24dp
|
import lwacharactersheet.composeapp.generated.resources.ic_fan_focus_24dp
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.ic_format_list_numbered_24dp
|
||||||
import lwacharactersheet.composeapp.generated.resources.ic_ifl_24dp
|
import lwacharactersheet.composeapp.generated.resources.ic_ifl_24dp
|
||||||
import lwacharactersheet.composeapp.generated.resources.ic_timer_24dp
|
import lwacharactersheet.composeapp.generated.resources.ic_timer_24dp
|
||||||
import lwacharactersheet.composeapp.generated.resources.ic_visibility_24dp
|
import lwacharactersheet.composeapp.generated.resources.ic_visibility_24dp
|
||||||
|
|
@ -28,6 +29,8 @@ import lwacharactersheet.composeapp.generated.resources.settings__chat_log__sect
|
||||||
import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__dyn_dice_description
|
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__dyn_dice_tile
|
||||||
import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__section
|
import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__section
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__line_count_title
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.settings__chat_log__line_count_description
|
||||||
|
|
||||||
|
|
||||||
class SettingsViewModel(
|
class SettingsViewModel(
|
||||||
|
|
@ -48,7 +51,11 @@ class SettingsViewModel(
|
||||||
description = Res.string.settings__player_portrait__dyn_dice_description,
|
description = Res.string.settings__player_portrait__dyn_dice_description,
|
||||||
checked = booleanStates.dynamicDice,
|
checked = booleanStates.dynamicDice,
|
||||||
onToggle = {
|
onToggle = {
|
||||||
settingsRepository.update(settings = settings.value.copy(dynamicDice = it))
|
settingsRepository.update(
|
||||||
|
settings = settings.value.copy(
|
||||||
|
portrait = settings.value.portrait.copy(dynamicDice = it)
|
||||||
|
)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SettingSectionUio(
|
SettingSectionUio(
|
||||||
|
|
@ -60,7 +67,11 @@ class SettingsViewModel(
|
||||||
description = Res.string.settings__chat_log__auto_show_description,
|
description = Res.string.settings__chat_log__auto_show_description,
|
||||||
checked = booleanStates.autoShowChat,
|
checked = booleanStates.autoShowChat,
|
||||||
onToggle = {
|
onToggle = {
|
||||||
settingsRepository.update(settings = settings.value.copy(autoShowChat = it))
|
settingsRepository.update(
|
||||||
|
settings = settings.value.copy(
|
||||||
|
chat = settings.value.chat.copy(autoShowChat = it)
|
||||||
|
)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SettingToggleItemUio(
|
SettingToggleItemUio(
|
||||||
|
|
@ -69,7 +80,11 @@ class SettingsViewModel(
|
||||||
description = Res.string.settings__chat_log__auto_hide_description,
|
description = Res.string.settings__chat_log__auto_hide_description,
|
||||||
checked = booleanStates.autoHideChat,
|
checked = booleanStates.autoHideChat,
|
||||||
onToggle = {
|
onToggle = {
|
||||||
settingsRepository.update(settings = settings.value.copy(autoHideChat = it))
|
settingsRepository.update(
|
||||||
|
settings = settings.value.copy(
|
||||||
|
chat = settings.value.chat.copy(autoHideChat = it)
|
||||||
|
)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SettingNumberItemUio(
|
SettingNumberItemUio(
|
||||||
|
|
@ -80,7 +95,11 @@ class SettingsViewModel(
|
||||||
value = intStates.autoHideDelay,
|
value = intStates.autoHideDelay,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
if (it in 0..999) {
|
if (it in 0..999) {
|
||||||
settingsRepository.update(settings = settings.value.copy(autoHideDelay = it))
|
settingsRepository.update(
|
||||||
|
settings = settings.value.copy(
|
||||||
|
chat = settings.value.chat.copy(autoHideDelay = it)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
@ -90,19 +109,40 @@ class SettingsViewModel(
|
||||||
description = Res.string.settings__chat_log__auto_scroll_description,
|
description = Res.string.settings__chat_log__auto_scroll_description,
|
||||||
checked = booleanStates.autoScrollChat,
|
checked = booleanStates.autoScrollChat,
|
||||||
onToggle = {
|
onToggle = {
|
||||||
settingsRepository.update(settings = settings.value.copy(autoScrollChat = it))
|
settingsRepository.update(
|
||||||
|
settings = settings.value.copy(
|
||||||
|
chat = settings.value.chat.copy(autoScrollChat = it)
|
||||||
|
)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
SettingNumberItemUio(
|
||||||
|
icon = Res.drawable.ic_format_list_numbered_24dp,
|
||||||
|
title = Res.string.settings__chat_log__line_count_title,
|
||||||
|
description = Res.string.settings__chat_log__line_count_description,
|
||||||
|
enable = mutableStateOf(true),
|
||||||
|
value = intStates.maxLineCount,
|
||||||
|
onValueChange = {
|
||||||
|
if (it in 0..999) {
|
||||||
|
settingsRepository.update(
|
||||||
|
settings = settings.value.copy(
|
||||||
|
chat = settings.value.chat.copy(maxLineCount = it)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
settingsRepository.settingsFlow().collect { settings ->
|
settingsRepository.settingsFlow().collect { settings ->
|
||||||
booleanStates.dynamicDice.value = settings.dynamicDice
|
booleanStates.dynamicDice.value = settings.portrait.dynamicDice
|
||||||
booleanStates.autoShowChat.value = settings.autoShowChat
|
booleanStates.autoShowChat.value = settings.chat.autoShowChat
|
||||||
booleanStates.autoHideChat.value = settings.autoHideChat
|
booleanStates.autoHideChat.value = settings.chat.autoHideChat
|
||||||
intStates.autoHideDelay.value = settings.autoHideDelay
|
intStates.autoHideDelay.value = settings.chat.autoHideDelay
|
||||||
booleanStates.autoScrollChat.value = settings.autoScrollChat
|
booleanStates.autoScrollChat.value = settings.chat.autoScrollChat
|
||||||
|
intStates.maxLineCount.value = settings.chat.maxLineCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -120,17 +160,20 @@ class SettingsViewModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
private val HashMap<String, MutableState<Boolean>>.dynamicDice
|
private val HashMap<String, MutableState<Boolean>>.dynamicDice
|
||||||
get() = getOrPut("DYNAMIC_DICE") { mutableStateOf(settings.value.dynamicDice) }
|
get() = getOrPut("DYNAMIC_DICE") { mutableStateOf(settings.value.portrait.dynamicDice) }
|
||||||
|
|
||||||
private val HashMap<String, MutableState<Boolean>>.autoShowChat
|
private val HashMap<String, MutableState<Boolean>>.autoShowChat
|
||||||
get() = getOrPut("AUTO_SHOW_CHAT") { mutableStateOf(settings.value.autoShowChat) }
|
get() = getOrPut("AUTO_SHOW_CHAT") { mutableStateOf(settings.value.chat.autoShowChat) }
|
||||||
|
|
||||||
private val HashMap<String, MutableState<Boolean>>.autoHideChat
|
private val HashMap<String, MutableState<Boolean>>.autoHideChat
|
||||||
get() = getOrPut("AUTO_HIDE_CHAT") { mutableStateOf(settings.value.autoHideChat) }
|
get() = getOrPut("AUTO_HIDE_CHAT") { mutableStateOf(settings.value.chat.autoHideChat) }
|
||||||
|
|
||||||
private val HashMap<String, MutableState<Int>>.autoHideDelay
|
private val HashMap<String, MutableState<Int>>.autoHideDelay
|
||||||
get() = getOrPut("AUTO_HIDE_DELAY") { mutableStateOf(settings.value.autoHideDelay) }
|
get() = getOrPut("AUTO_HIDE_DELAY") { mutableStateOf(settings.value.chat.autoHideDelay) }
|
||||||
|
|
||||||
private val HashMap<String, MutableState<Boolean>>.autoScrollChat
|
private val HashMap<String, MutableState<Boolean>>.autoScrollChat
|
||||||
get() = getOrPut("AUTO_SCROLL_CHAT") { mutableStateOf(settings.value.autoScrollChat) }
|
get() = getOrPut("AUTO_SCROLL_CHAT") { mutableStateOf(settings.value.chat.autoScrollChat) }
|
||||||
|
|
||||||
|
private val HashMap<String, MutableState<Int>>.maxLineCount
|
||||||
|
get() = getOrPut("MAX_LINE_COUNT") { mutableStateOf(settings.value.chat.maxLineCount) }
|
||||||
}
|
}
|
||||||
|
|
@ -5,14 +5,21 @@ import com.pixelized.desktop.lwa.repository.settings.model.Settings
|
||||||
class SettingsUseCase {
|
class SettingsUseCase {
|
||||||
|
|
||||||
fun defaultSettings(): Settings = Settings(
|
fun defaultSettings(): Settings = Settings(
|
||||||
host = DEFAULT_HOST,
|
|
||||||
port = DEFAULT_PORT,
|
|
||||||
playerName = "",
|
playerName = "",
|
||||||
dynamicDice = true,
|
portrait = Settings.Portrait(
|
||||||
|
dynamicDice = true
|
||||||
|
),
|
||||||
|
chat = Settings.Chat(
|
||||||
autoHideChat = true,
|
autoHideChat = true,
|
||||||
autoHideDelay = 8,
|
autoHideDelay = 8,
|
||||||
autoShowChat = true,
|
autoShowChat = true,
|
||||||
autoScrollChat = true,
|
autoScrollChat = true,
|
||||||
|
maxLineCount = 200,
|
||||||
|
),
|
||||||
|
network = Settings.Network(
|
||||||
|
host = DEFAULT_HOST,
|
||||||
|
port = DEFAULT_PORT,
|
||||||
|
),
|
||||||
isAdmin = null,
|
isAdmin = null,
|
||||||
isGameMaster = null,
|
isGameMaster = null,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue