Some small UI adjustment to the level UP screen & RollOverlay.
This commit is contained in:
parent
fce085f70d
commit
35396b6069
23 changed files with 530 additions and 166 deletions
|
|
@ -32,9 +32,6 @@ import androidx.compose.ui.unit.min
|
|||
import androidx.compose.ui.window.ApplicationScope
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.rememberWindowState
|
||||
import coil3.ImageLoader
|
||||
import coil3.compose.setSingletonImageLoaderFactory
|
||||
import coil3.request.crossfade
|
||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository.Status
|
||||
import com.pixelized.desktop.lwa.ui.composable.blur.BlurContent
|
||||
|
|
@ -53,17 +50,18 @@ import com.pixelized.desktop.lwa.ui.navigation.window.destination.CharacterSheet
|
|||
import com.pixelized.desktop.lwa.ui.navigation.window.destination.NetworkWindows
|
||||
import com.pixelized.desktop.lwa.ui.navigation.window.destination.RollHistoryWindow
|
||||
import com.pixelized.desktop.lwa.ui.navigation.window.rememberMaxWindowHeight
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollHostState
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollOverlay
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.CampaignViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.chat.CampaignChatViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon.PlayerRibbon
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.CharacterSheetMainNavHost
|
||||
import com.pixelized.desktop.lwa.ui.screen.network.NetworkPage
|
||||
import com.pixelized.desktop.lwa.ui.screen.network.NetworkViewModel
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollHostState
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollOverlay
|
||||
import com.pixelized.desktop.lwa.ui.screen.rollhistory.RollHistoryPage
|
||||
import com.pixelized.desktop.lwa.ui.screen.rollhistory.RollHistoryViewModel
|
||||
import com.pixelized.desktop.lwa.ui.theme.LwaTheme
|
||||
import com.pixelized.desktop.lwa.utils.InstallCoil
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
|
|
@ -102,7 +100,7 @@ val LocalBlurController = compositionLocalOf<BlurContentController> {
|
|||
|
||||
@Composable
|
||||
@Preview
|
||||
fun ApplicationScope.App() {
|
||||
fun ApplicationScope.LwaApplication() {
|
||||
val maxWindowHeight = rememberMaxWindowHeight()
|
||||
val snackHostState = remember { SnackbarHostState() }
|
||||
val errorSnackHostState = remember { SnackbarHostState() }
|
||||
|
|
@ -120,12 +118,13 @@ fun ApplicationScope.App() {
|
|||
),
|
||||
)
|
||||
|
||||
// Coil configuration
|
||||
setSingletonImageLoaderFactory { context ->
|
||||
ImageLoader.Builder(context)
|
||||
.crossfade(enable = false)
|
||||
.build()
|
||||
}
|
||||
// Coil configuration.
|
||||
InstallCoil(
|
||||
crossfade = false,
|
||||
diskCachePath = { provider ->
|
||||
provider.imagesStorePath()
|
||||
}
|
||||
)
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalApplicationScope provides this,
|
||||
|
|
@ -150,16 +149,18 @@ fun ApplicationScope.App() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
private fun MainWindowScreen(
|
||||
campaignViewModel: CampaignViewModel = koinViewModel(),
|
||||
dataSyncViewModel: DataSyncViewModel = koinViewModel(),
|
||||
networkViewModel: NetworkViewModel = koinViewModel(),
|
||||
campaignViewModel: CampaignViewModel = koinViewModel(),
|
||||
campaignChatViewModel: CampaignChatViewModel = koinViewModel(),
|
||||
rollViewModel: RollHistoryViewModel = koinViewModel(),
|
||||
) {
|
||||
LaunchedEffect(Unit) {
|
||||
networkViewModel.connect()
|
||||
campaignViewModel.init()
|
||||
dataSyncViewModel.autoConnect()
|
||||
dataSyncViewModel.synchronise()
|
||||
}
|
||||
|
||||
val snackHostState = LocalSnackHost.current
|
||||
|
|
@ -205,15 +206,12 @@ private fun MainWindowScreen(
|
|||
content = {
|
||||
BlurContent(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
controller = blurController
|
||||
controller = blurController,
|
||||
) {
|
||||
MainNavHost(
|
||||
campaignViewModel = campaignViewModel,
|
||||
networkViewModel = networkViewModel,
|
||||
campaignChatViewModel = campaignChatViewModel,
|
||||
)
|
||||
MainNavHost()
|
||||
}
|
||||
RollOverlay(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
hostState = rollHostState,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
package com.pixelized.desktop.lwa
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
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.network.NetworkRepository
|
||||
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
class DataSyncViewModel(
|
||||
private val characterRepository: CharacterSheetRepository,
|
||||
private val alterationRepository: AlterationRepository,
|
||||
private val campaignRepository: CampaignRepository,
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val networkRepository: NetworkRepository,
|
||||
) : ViewModel() {
|
||||
|
||||
fun autoConnect() {
|
||||
val settings = settingsRepository.settings()
|
||||
|
||||
if (settings.playerName.isEmpty()) return
|
||||
|
||||
networkRepository.connect(
|
||||
host = settings.host,
|
||||
port = settings.port,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun synchronise() = coroutineScope {
|
||||
|
||||
networkRepository.status
|
||||
.filter { status -> status == NetworkRepository.Status.CONNECTED }
|
||||
.onEach { campaignRepository.update() }
|
||||
.launchIn(this)
|
||||
|
||||
networkRepository.status
|
||||
.filter { status -> status == NetworkRepository.Status.CONNECTED }
|
||||
.combine(campaignRepository.campaignFlow) { _, campaign: Campaign -> campaign }
|
||||
.onEach { campaign ->
|
||||
campaign.characters.keys.forEach { id ->
|
||||
characterRepository.characterDetail(
|
||||
characterSheetId = id.characterSheetId,
|
||||
forceUpdate = true,
|
||||
)
|
||||
alterationRepository.updateActiveAlterations(
|
||||
characterInstanceId = id,
|
||||
)
|
||||
}
|
||||
}
|
||||
.launchIn(this)
|
||||
}
|
||||
}
|
||||
|
|
@ -15,8 +15,8 @@ import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
|||
import com.pixelized.desktop.lwa.repository.settings.SettingsStore
|
||||
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterDetailCharacteristicDialogViewModel
|
||||
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialogFactory
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.CampaignViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.LevelUpViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.chat.CampaignChatViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.chat.TextMessageFactory
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDetailFactory
|
||||
|
|
@ -30,10 +30,10 @@ import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.CharacterSheetEdi
|
|||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.CharacterSheetEditViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.SkillFieldFactory
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.LevelUpFactory
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.LevelUpViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.main.MainPageViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.network.NetworkFactory
|
||||
import com.pixelized.desktop.lwa.ui.screen.network.NetworkViewModel
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.rollhistory.RollHistoryViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.settings.SettingsViewModel
|
||||
import com.pixelized.desktop.lwa.usecase.SettingsUseCase
|
||||
|
|
@ -116,6 +116,7 @@ val factoryDependencies
|
|||
|
||||
val viewModelDependencies
|
||||
get() = module {
|
||||
viewModelOf(::DataSyncViewModel)
|
||||
viewModelOf(::CampaignViewModel)
|
||||
viewModelOf(::MainPageViewModel)
|
||||
viewModelOf(::CharacterSheetViewModel)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Arrangement
|
|||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Surface
|
||||
|
|
@ -40,7 +41,12 @@ fun TooltipLayout(
|
|||
|
||||
else -> TooltipArea(
|
||||
modifier = modifier,
|
||||
tooltip = { Tooltip(tooltip = tooltip) },
|
||||
tooltip = {
|
||||
Tooltip(
|
||||
modifier = Modifier.width(width = 448.dp),
|
||||
tooltip = tooltip,
|
||||
)
|
||||
},
|
||||
content = content,
|
||||
delayMillis = delayMillis,
|
||||
tooltipPlacement = tooltipPlacement,
|
||||
|
|
|
|||
|
|
@ -23,9 +23,6 @@ val LocalScreenController = compositionLocalOf<NavHostController> {
|
|||
@Composable
|
||||
fun MainNavHost(
|
||||
controller: NavHostController = rememberNavController(),
|
||||
campaignViewModel: CampaignViewModel,
|
||||
networkViewModel: NetworkViewModel,
|
||||
campaignChatViewModel: CampaignChatViewModel,
|
||||
startDestination: String = MainDestination.navigationRoute(),
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
|
|
@ -35,11 +32,7 @@ fun MainNavHost(
|
|||
navController = controller,
|
||||
startDestination = startDestination,
|
||||
) {
|
||||
composableMainPage(
|
||||
campaignViewModel = campaignViewModel,
|
||||
networkViewModel = networkViewModel,
|
||||
campaignChatViewModel = campaignChatViewModel,
|
||||
)
|
||||
composableMainPage()
|
||||
composableSettingsPage()
|
||||
composableLevelUp()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,7 @@ package com.pixelized.desktop.lwa.ui.navigation.screen.destination
|
|||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.composable
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.CampaignViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.CampaignScreen
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.chat.CampaignChatViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.network.NetworkViewModel
|
||||
|
||||
object MainDestination {
|
||||
private const val ROUTE = "main"
|
||||
|
|
@ -15,19 +12,11 @@ object MainDestination {
|
|||
fun navigationRoute() = ROUTE
|
||||
}
|
||||
|
||||
fun NavGraphBuilder.composableMainPage(
|
||||
campaignViewModel: CampaignViewModel,
|
||||
networkViewModel: NetworkViewModel,
|
||||
campaignChatViewModel: CampaignChatViewModel,
|
||||
) {
|
||||
fun NavGraphBuilder.composableMainPage() {
|
||||
composable(
|
||||
route = MainDestination.baseRoute(),
|
||||
) {
|
||||
CampaignScreen(
|
||||
campaignViewModel = campaignViewModel,
|
||||
networkViewModel = networkViewModel,
|
||||
campaignChatViewModel = campaignChatViewModel,
|
||||
)
|
||||
CampaignScreen()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.koin.compose.viewmodel.koinViewModel
|
|||
@Composable
|
||||
fun RollOverlay(
|
||||
viewModel: RollViewModel = koinViewModel(),
|
||||
modifier: Modifier = Modifier,
|
||||
hostState: RollHostState,
|
||||
) {
|
||||
val blur = LocalBlurController.current
|
||||
|
|
@ -43,7 +44,7 @@ fun RollOverlay(
|
|||
}
|
||||
|
||||
AnimatedContent(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = modifier,
|
||||
targetState = hostState.rollAction.value,
|
||||
transitionSpec = {
|
||||
val enter = fadeIn() + slideInVertically { 64 }
|
||||
|
|
|
|||
|
|
@ -61,13 +61,11 @@ fun CampaignScreen(
|
|||
campaignViewModel: CampaignViewModel = koinViewModel(),
|
||||
networkViewModel: NetworkViewModel = koinViewModel(),
|
||||
campaignChatViewModel: CampaignChatViewModel = koinViewModel(),
|
||||
rollViewModel: RollViewModel = koinViewModel(),
|
||||
) {
|
||||
val screen = LocalScreenController.current
|
||||
val blurController = rememberBlurContentController()
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
|
||||
KeyHandler {
|
||||
when {
|
||||
it.type == KeyEventType.KeyUp && it.key == Key.Escape -> {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ data class CharacterDetailHeaderUio(
|
|||
@Composable
|
||||
fun CharacterDetailHeader(
|
||||
modifier: Modifier = Modifier,
|
||||
iconSize: Dp = 14.dp,
|
||||
iconSize: Dp = MaterialTheme.lwa.size.sheet.subCategory,
|
||||
header: State<CharacterDetailHeaderUio?>,
|
||||
onDismissRequest: () -> Unit,
|
||||
onDiminished: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ fun CharacterDetailSheet(
|
|||
) {
|
||||
sheet.value?.characteristics?.forEach {
|
||||
CharacterDetailSheetCharacteristic(
|
||||
modifier = Modifier.size(size = MaterialTheme.lwa.size.characteristic),
|
||||
modifier = Modifier.size(size = MaterialTheme.lwa.size.sheet.characteristic),
|
||||
characteristic = it,
|
||||
onClick = { onCharacteristic(it) },
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import androidx.compose.foundation.layout.Box
|
|||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
|
|
@ -55,6 +57,7 @@ import androidx.compose.ui.input.key.key
|
|||
import androidx.compose.ui.input.key.type
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavHostController
|
||||
import coil3.compose.AsyncImage
|
||||
|
|
@ -68,6 +71,8 @@ import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpCharacteristic
|
|||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpCharacteristicUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpSkill
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpSkillUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpSubCharacteristic
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpSubCharacteristicUio
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import kotlinx.coroutines.launch
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
|
|
@ -75,7 +80,7 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet__skills_
|
|||
import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__magic_title
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__special_title
|
||||
import lwacharactersheet.composeapp.generated.resources.level_up__action
|
||||
import lwacharactersheet.composeapp.generated.resources.level_up__character_level_description
|
||||
import lwacharactersheet.composeapp.generated.resources.level_up__character__label
|
||||
import lwacharactersheet.composeapp.generated.resources.level_up__title
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
|
@ -86,6 +91,11 @@ data class LevelUpHeaderUio(
|
|||
val name: String,
|
||||
val level: Int,
|
||||
val portrait: String?,
|
||||
val hp: LevelUpSubCharacteristicUio,
|
||||
val pp: LevelUpSubCharacteristicUio,
|
||||
val bonus: LevelUpSubCharacteristicUio,
|
||||
val grow: LevelUpSubCharacteristicUio,
|
||||
val learn: LevelUpSubCharacteristicUio,
|
||||
)
|
||||
|
||||
@Stable
|
||||
|
|
@ -217,18 +227,49 @@ private fun LevelUpContent(
|
|||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.base.h5,
|
||||
text = header.value?.name ?: ""
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.base.body1,
|
||||
text = (header.value?.level ?: 0).let {
|
||||
stringResource(
|
||||
Res.string.level_up__character_level_description, it, it + 1
|
||||
)
|
||||
},
|
||||
)
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.h5,
|
||||
text = header.value?.name ?: "",
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.lwa.typography.base.caption,
|
||||
text = (header.value?.level ?: 0).let { level ->
|
||||
stringResource(
|
||||
resource = Res.string.level_up__character__label,
|
||||
level, level + 1
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 16.dp),
|
||||
) {
|
||||
LevelUpSubCharacteristic(
|
||||
characteristic = header.value?.hp,
|
||||
)
|
||||
LevelUpSubCharacteristic(
|
||||
characteristic = header.value?.pp,
|
||||
)
|
||||
Spacer(
|
||||
modifier = Modifier.weight(weight = 1f)
|
||||
)
|
||||
LevelUpSubCharacteristic(
|
||||
characteristic = header.value?.bonus,
|
||||
)
|
||||
LevelUpSubCharacteristic(
|
||||
characteristic = header.value?.grow,
|
||||
)
|
||||
LevelUpSubCharacteristic(
|
||||
characteristic = header.value?.learn,
|
||||
)
|
||||
}
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.verticalScroll(state = scrollState),
|
||||
|
|
@ -251,7 +292,7 @@ private fun LevelUpContent(
|
|||
key = { it.characteristicId }
|
||||
) {
|
||||
LevelUpCharacteristic(
|
||||
modifier = Modifier.size(size = MaterialTheme.lwa.size.characteristic),
|
||||
modifier = Modifier.size(size = MaterialTheme.lwa.size.sheet.characteristic),
|
||||
characteristic = it,
|
||||
onClick = { onCharacteristic(it) },
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,10 +5,14 @@ import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
|||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollResult
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpCharacteristicUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpSkillUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpSubCharacteristicUio
|
||||
import com.pixelized.shared.lwa.model.AlteredCharacterSheet
|
||||
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
|
||||
import com.pixelized.shared.lwa.model.alteration.Alteration
|
||||
import com.pixelized.shared.lwa.model.alteration.FieldAlteration
|
||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||
import com.pixelized.shared.lwa.parser.expression.Expression
|
||||
import com.pixelized.shared.lwa.usecase.ExpressionUseCase
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__cha
|
||||
|
|
@ -18,6 +22,20 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet__charact
|
|||
import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__int
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__pow
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__str
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__armor
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__damage_bonus
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__hit_point
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__hp_grow
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__learning
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__movement
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__power_point
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_cognition_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_heart_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_heart_plus_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_near_me
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_shield_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_swords_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_water_drop_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__charisma
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__constitution
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__dexterity
|
||||
|
|
@ -25,6 +43,13 @@ import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics
|
|||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__intelligence
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__power
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__strength
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__armor
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__bonus_damage
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__hit_point
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__hp_grow
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__learning
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__movement
|
||||
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__power_point
|
||||
import org.jetbrains.compose.resources.getString
|
||||
|
||||
class LevelUpFactory(
|
||||
|
|
@ -32,14 +57,96 @@ class LevelUpFactory(
|
|||
private val expressionUseCase: ExpressionUseCase,
|
||||
) {
|
||||
|
||||
fun convertToLevelUpHeaderUio(
|
||||
suspend fun convertToLevelUpHeaderUio(
|
||||
characterSheet: CharacterSheet?,
|
||||
selectedCharacteristicId: String?,
|
||||
): LevelUpHeaderUio? {
|
||||
if (characterSheet == null) return null
|
||||
|
||||
val levelAlteration = FieldAlteration(
|
||||
alterationId = CharacterSheet.CharacteristicId.LVL,
|
||||
metadata = Alteration.MetaData(
|
||||
name = "LevelUp-${CharacterSheet.CharacteristicId.LVL}",
|
||||
description = "Fake alteration for a levelUp simulation. Alter the ${CharacterSheet.CharacteristicId.LVL} stat."
|
||||
),
|
||||
expression = Expression.Flat(1),
|
||||
)
|
||||
|
||||
val alteredCharacterSheet = alteredCharacterSheetFactory.sheet(
|
||||
characterSheet = characterSheet,
|
||||
alterations = emptyMap(),
|
||||
)
|
||||
val levelUpCharacterSheet = alteredCharacterSheetFactory.sheet(
|
||||
characterSheet = characterSheet,
|
||||
alterations = selectedCharacteristicId
|
||||
?.let {
|
||||
val characteristic = FieldAlteration(
|
||||
alterationId = it,
|
||||
metadata = Alteration.MetaData(
|
||||
name = "LevelUp-$it",
|
||||
description = "Fake alteration for a levelUp simulation. Alter the $it stat."
|
||||
),
|
||||
expression = Expression.Flat(1),
|
||||
)
|
||||
mapOf(
|
||||
CharacterSheet.CharacteristicId.LVL to listOf(levelAlteration),
|
||||
it to listOf(characteristic),
|
||||
)
|
||||
}
|
||||
?: mapOf(
|
||||
CharacterSheet.CharacteristicId.LVL to listOf(levelAlteration),
|
||||
),
|
||||
)
|
||||
|
||||
return LevelUpHeaderUio(
|
||||
name = characterSheet.name,
|
||||
portrait = characterSheet.portrait,
|
||||
level = characterSheet.level,
|
||||
hp = LevelUpSubCharacteristicUio(
|
||||
icon = Res.drawable.ic_heart_24dp,
|
||||
base = "${alteredCharacterSheet.maxHp}",
|
||||
levelUp = "${levelUpCharacterSheet.maxHp}",
|
||||
tooltip = TooltipUio(
|
||||
title = getString(Res.string.character_sheet__sub_characteristics__hit_point),
|
||||
description = getString(Res.string.tooltip__sub_characteristics__hit_point)
|
||||
),
|
||||
),
|
||||
pp = LevelUpSubCharacteristicUio(
|
||||
icon = Res.drawable.ic_water_drop_24dp,
|
||||
base = "${alteredCharacterSheet.maxPp}",
|
||||
levelUp = "${levelUpCharacterSheet.maxPp}",
|
||||
tooltip = TooltipUio(
|
||||
title = getString(Res.string.character_sheet__sub_characteristics__power_point),
|
||||
description = getString(Res.string.tooltip__sub_characteristics__power_point)
|
||||
)
|
||||
),
|
||||
bonus = LevelUpSubCharacteristicUio(
|
||||
icon = Res.drawable.ic_swords_24dp,
|
||||
base = alteredCharacterSheet.damageBonus,
|
||||
levelUp = levelUpCharacterSheet.damageBonus,
|
||||
tooltip = TooltipUio(
|
||||
title = getString(Res.string.character_sheet__sub_characteristics__damage_bonus),
|
||||
description = getString(Res.string.tooltip__sub_characteristics__bonus_damage)
|
||||
),
|
||||
),
|
||||
grow = LevelUpSubCharacteristicUio(
|
||||
icon = Res.drawable.ic_heart_plus_24dp,
|
||||
base = "${alteredCharacterSheet.hpGrow}",
|
||||
levelUp = "${levelUpCharacterSheet.hpGrow}",
|
||||
tooltip = TooltipUio(
|
||||
title = getString(Res.string.character_sheet__sub_characteristics__hp_grow),
|
||||
description = getString(Res.string.tooltip__sub_characteristics__hp_grow)
|
||||
),
|
||||
),
|
||||
learn = LevelUpSubCharacteristicUio(
|
||||
icon = Res.drawable.ic_cognition_24dp,
|
||||
base = "${alteredCharacterSheet.learning}",
|
||||
levelUp = "${levelUpCharacterSheet.learning}",
|
||||
tooltip = TooltipUio(
|
||||
title = getString(Res.string.character_sheet__sub_characteristics__learning),
|
||||
description = getString(Res.string.tooltip__sub_characteristics__learning)
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -204,6 +311,12 @@ class LevelUpFactory(
|
|||
level = skill.level,
|
||||
levelUp = results.isSkillLeveledUp(skillId = skill.id),
|
||||
occupation = skill.occupation,
|
||||
tooltips = skill.description?.let {
|
||||
TooltipUio(
|
||||
title = skill.label,
|
||||
description = it,
|
||||
)
|
||||
},
|
||||
roll = when (results[skill.id]) {
|
||||
null -> RollActionUio(
|
||||
characterInstanceId = characterInstanceId,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import kotlinx.coroutines.flow.SharedFlow
|
|||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.error__default__action
|
||||
|
|
@ -35,14 +34,15 @@ class LevelUpViewModel(
|
|||
private val results = MutableStateFlow<Map<String, RollResult>>(emptyMap())
|
||||
private val selectedCharacteristicId = MutableStateFlow<String?>(null)
|
||||
|
||||
val header: StateFlow<LevelUpHeaderUio?> = characterSheetRepository
|
||||
.characterDetailFlow(characterSheetId = argument.characterInstanceId.characterSheetId)
|
||||
.map(levelUpFactory::convertToLevelUpHeaderUio)
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.Lazily,
|
||||
initialValue = null,
|
||||
)
|
||||
val header = combine(
|
||||
characterSheetRepository.characterDetailFlow(characterSheetId = argument.characterInstanceId.characterSheetId),
|
||||
selectedCharacteristicId,
|
||||
levelUpFactory::convertToLevelUpHeaderUio
|
||||
).stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.Lazily,
|
||||
initialValue = null,
|
||||
)
|
||||
|
||||
val characteristics = combine(
|
||||
characterSheetRepository.characterDetailFlow(characterSheetId = argument.characterInstanceId.characterSheetId),
|
||||
|
|
|
|||
|
|
@ -64,11 +64,7 @@ fun LevelUpCharacteristic(
|
|||
.fillMaxWidth()
|
||||
.align(alignment = Alignment.Center),
|
||||
targetState = characteristic.selected,
|
||||
transitionSpec = {
|
||||
val enter = fadeIn() + slideInVertically { -16 }
|
||||
val exit = fadeOut() + slideOutVertically { 16 }
|
||||
enter togetherWith exit using SizeTransform(clip = false)
|
||||
},
|
||||
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import androidx.compose.animation.fadeOut
|
|||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
|
|
@ -23,6 +24,8 @@ import androidx.compose.ui.text.font.FontWeight
|
|||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.composable.shapes.MasteryShape
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipLayout
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
|
|
@ -37,9 +40,11 @@ data class LevelUpSkillUio(
|
|||
val level: Int,
|
||||
val levelUp: Boolean,
|
||||
val occupation: Boolean,
|
||||
val tooltips: TooltipUio?,
|
||||
val roll: RollActionUio?,
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun LevelUpSkill(
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
@ -53,7 +58,7 @@ fun LevelUpSkill(
|
|||
else -> MaterialTheme.lwa.colorScheme.base.primary
|
||||
}
|
||||
)
|
||||
Row(
|
||||
TooltipLayout(
|
||||
modifier = Modifier
|
||||
.let {
|
||||
when (skill.roll) {
|
||||
|
|
@ -63,60 +68,65 @@ fun LevelUpSkill(
|
|||
}
|
||||
.padding(paddingValues = paddingValues)
|
||||
.then(other = modifier),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
tooltip = skill.tooltips,
|
||||
) {
|
||||
MasteryShape(
|
||||
modifier = Modifier.padding(top = 4.dp),
|
||||
multiplier = if (skill.occupation) 1 else 0,
|
||||
)
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline().weight(1f),
|
||||
style = MaterialTheme.typography.body1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = skill.label
|
||||
MasteryShape(
|
||||
modifier = Modifier.padding(top = 4.dp),
|
||||
multiplier = if (skill.occupation) 1 else 0,
|
||||
)
|
||||
AnimatedContent(
|
||||
targetState = skill.levelUp,
|
||||
transitionSpec = {
|
||||
val enter = fadeIn() + slideInVertically { -16 }
|
||||
val exit = fadeOut() + slideOutVertically { 16 }
|
||||
enter togetherWith exit using SizeTransform(clip = false)
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline().weight(1f),
|
||||
style = MaterialTheme.typography.body1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = skill.label
|
||||
)
|
||||
AnimatedContent(
|
||||
targetState = skill.levelUp,
|
||||
transitionSpec = {
|
||||
val enter = fadeIn() + slideInVertically { -16 }
|
||||
val exit = fadeOut() + slideOutVertically { 16 }
|
||||
enter togetherWith exit using SizeTransform(clip = false)
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.caption,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = stringResource(
|
||||
resource = Res.string.level_up__skill_level,
|
||||
when (it) {
|
||||
true -> skill.level + 1
|
||||
else -> skill.level
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.caption,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = stringResource(
|
||||
resource = Res.string.level_up__skill_level,
|
||||
when (it) {
|
||||
true -> skill.level + 1
|
||||
else -> skill.level
|
||||
},
|
||||
)
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.body1,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = when (it) {
|
||||
true -> MaterialTheme.lwa.colorScheme.base.secondary
|
||||
else -> valueColor.value
|
||||
},
|
||||
text = when (it) {
|
||||
true -> "${skill.value + 5}"
|
||||
else -> "${skill.value}"
|
||||
},
|
||||
)
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.body1,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = when (it) {
|
||||
true -> MaterialTheme.lwa.colorScheme.base.secondary
|
||||
else -> valueColor.value
|
||||
},
|
||||
text = when (it) {
|
||||
true -> "${skill.value + 5}"
|
||||
else -> "${skill.value}"
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
package com.pixelized.desktop.lwa.ui.screen.levelup.items
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.SizeTransform
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Box
|
||||
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.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipLayout
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.generic__arrow
|
||||
import org.jetbrains.compose.resources.DrawableResource
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
||||
|
||||
@Stable
|
||||
data class LevelUpSubCharacteristicUio(
|
||||
val icon: DrawableResource,
|
||||
val base: String,
|
||||
val levelUp: String,
|
||||
val tooltip: TooltipUio,
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun LevelUpSubCharacteristic(
|
||||
modifier: Modifier = Modifier,
|
||||
characteristic: LevelUpSubCharacteristicUio?,
|
||||
) {
|
||||
TooltipLayout(
|
||||
modifier = modifier,
|
||||
tooltip = characteristic?.tooltip,
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.Bottom,
|
||||
) {
|
||||
if (characteristic?.icon != null) {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 4.dp, end = 2.dp)
|
||||
.size(size = MaterialTheme.lwa.size.sheet.subCategory),
|
||||
painter = painterResource(characteristic.icon),
|
||||
contentDescription = null
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 4.dp, end = 2.dp)
|
||||
.size(size = MaterialTheme.lwa.size.sheet.subCategory),
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.padding(bottom = 3.dp),
|
||||
style = MaterialTheme.typography.caption,
|
||||
fontWeight = FontWeight.Thin,
|
||||
text = characteristic?.base ?: "",
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(bottom = 3.dp),
|
||||
style = MaterialTheme.typography.caption,
|
||||
fontWeight = FontWeight.Thin,
|
||||
text = stringResource(Res.string.generic__arrow),
|
||||
)
|
||||
AnimatedContent(
|
||||
targetState = characteristic?.levelUp ?: "",
|
||||
transitionSpec = {
|
||||
val enter = fadeIn() + slideInVertically { -16 }
|
||||
val exit = fadeOut() + slideOutVertically { 16 }
|
||||
enter togetherWith exit using SizeTransform(clip = false)
|
||||
},
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.h6,
|
||||
color = MaterialTheme.lwa.colorScheme.base.secondary,
|
||||
fontWeight = FontWeight.Bold,
|
||||
text = it,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ import androidx.compose.runtime.LaunchedEffect
|
|||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
|
|
@ -50,6 +51,7 @@ import com.pixelized.desktop.lwa.ui.composable.blur.BlurContent
|
|||
import com.pixelized.desktop.lwa.ui.composable.error.ErrorSnack
|
||||
import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import kotlinx.coroutines.launch
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_cancel_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.network__host__label
|
||||
|
|
@ -103,6 +105,7 @@ fun NetworkScreen(
|
|||
) {
|
||||
val screen = LocalScreenController.current
|
||||
val snack = LocalSnackHost.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
|
|
@ -148,7 +151,7 @@ fun NetworkScreen(
|
|||
onResetPortChange = viewModel::onResetPortChange,
|
||||
onPortChange = viewModel::onPortChange,
|
||||
onResetHostChange = viewModel::onResetHostChange,
|
||||
onConnect = viewModel::connect,
|
||||
onConnect = { scope.launch { viewModel.connect() } },
|
||||
onDisconnect = viewModel::disconnect,
|
||||
)
|
||||
}
|
||||
|
|
@ -188,6 +191,7 @@ fun NetworkPage(
|
|||
viewModel: NetworkViewModel = koinViewModel(),
|
||||
) {
|
||||
val snack = LocalSnackHost.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Box(
|
||||
modifier = modifier,
|
||||
|
|
@ -205,7 +209,7 @@ fun NetworkPage(
|
|||
onResetHostChange = viewModel::onResetHostChange,
|
||||
onPortChange = viewModel::onPortChange,
|
||||
onResetPortChange = viewModel::onResetPortChange,
|
||||
onConnect = viewModel::connect,
|
||||
onConnect = { scope.launch { viewModel.connect() } },
|
||||
onDisconnect = viewModel::disconnect,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.pixelized.desktop.lwa.ui.screen.network
|
||||
|
||||
import androidx.compose.material.SnackbarDuration
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
|
@ -9,7 +10,6 @@ import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
|
|||
import com.pixelized.desktop.lwa.ui.composable.blur.BlurContentController
|
||||
import com.pixelized.desktop.lwa.ui.composable.error.ErrorSnackUio
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
|
|
@ -20,6 +20,10 @@ import kotlinx.coroutines.flow.launchIn
|
|||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.network__message__action
|
||||
import lwacharactersheet.composeapp.generated.resources.network__require__player_name
|
||||
import org.jetbrains.compose.resources.getString
|
||||
|
||||
class NetworkViewModel(
|
||||
private val settingsRepository: SettingsRepository,
|
||||
|
|
@ -64,11 +68,13 @@ class NetworkViewModel(
|
|||
)
|
||||
|
||||
init {
|
||||
settingsRepository.settingsFlow().onEach {
|
||||
nameFlow.value = it.playerName
|
||||
hostFlow.value = it.host
|
||||
portFlow.value = it.port
|
||||
}.launchIn(viewModelScope)
|
||||
settingsRepository.settingsFlow()
|
||||
.onEach {
|
||||
nameFlow.value = it.playerName
|
||||
hostFlow.value = it.host
|
||||
portFlow.value = it.port
|
||||
}
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
fun onPlayerNameChange(player: String) {
|
||||
|
|
@ -91,7 +97,7 @@ class NetworkViewModel(
|
|||
hostFlow.value = settings.host
|
||||
}
|
||||
|
||||
fun connect() {
|
||||
suspend fun connect() {
|
||||
blurController.show()
|
||||
_isLoading.value = true
|
||||
|
||||
|
|
@ -109,6 +115,19 @@ class NetworkViewModel(
|
|||
)
|
||||
}
|
||||
|
||||
if (nameFlow.value.isBlank()) {
|
||||
_networkError.emit(
|
||||
ErrorSnackUio(
|
||||
message = getString(Res.string.network__require__player_name),
|
||||
action = getString(Res.string.network__message__action),
|
||||
duration = SnackbarDuration.Short,
|
||||
)
|
||||
)
|
||||
blurController.hide()
|
||||
_isLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
networkRepository.connect(
|
||||
host = hostFlow.value,
|
||||
port = portFlow.value,
|
||||
|
|
|
|||
|
|
@ -3,20 +3,30 @@ package com.pixelized.desktop.lwa.ui.theme.size
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Stable
|
||||
|
||||
data class LwaSize(
|
||||
val characteristic: DpSize,
|
||||
)
|
||||
val sheet: Sheet,
|
||||
) {
|
||||
@Stable
|
||||
data class Sheet(
|
||||
val subCategory: Dp,
|
||||
val characteristic: DpSize,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun lwaSize(
|
||||
characteristic: DpSize = DpSize(width = 76.dp, height = 110.dp),
|
||||
sheet: LwaSize.Sheet = LwaSize.Sheet(
|
||||
subCategory = 14.dp,
|
||||
characteristic = DpSize(width = 76.dp, height = 110.dp),
|
||||
),
|
||||
) = remember {
|
||||
LwaSize(
|
||||
characteristic = characteristic,
|
||||
sheet = sheet,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.pixelized.desktop.lwa.utils
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import coil3.ImageLoader
|
||||
import coil3.compose.setSingletonImageLoaderFactory
|
||||
import coil3.disk.DiskCache
|
||||
import coil3.request.crossfade
|
||||
import com.pixelized.shared.lwa.utils.PathProvider
|
||||
import okio.Path.Companion.toPath
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
@Composable
|
||||
fun InstallCoil(
|
||||
pathProvider: PathProvider = koinInject(),
|
||||
crossfade: Boolean,
|
||||
diskCachePath: (PathProvider) -> String,
|
||||
) {
|
||||
setSingletonImageLoaderFactory { context ->
|
||||
ImageLoader.Builder(context)
|
||||
.crossfade(enable = crossfade)
|
||||
.diskCache {
|
||||
DiskCache.Builder()
|
||||
.directory(directory = diskCachePath(pathProvider).toPath())
|
||||
.build()
|
||||
}
|
||||
.build()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue