Add splashscreen.

This commit is contained in:
Thomas Andres Gomez 2025-04-12 09:41:23 +02:00
parent 05cc533cbf
commit 7dd5ade1f5
9 changed files with 138 additions and 30 deletions

View file

@ -6,7 +6,8 @@
<string name="error__missing_character_sheet__label">La feuille de personnage est introuvable</string> <string name="error__missing_character_sheet__label">La feuille de personnage est introuvable</string>
<string name="error__default__action">Ok</string> <string name="error__default__action">Ok</string>
<string name="app_name">La table de Lwa</string> <string name="app_name">La Table de Lwa</string>
<string name="app_version">version : %1$s</string>
<string name="dialog__confirm_action">Confirmer</string> <string name="dialog__confirm_action">Confirmer</string>
<string name="dialog__cancel_action">Annuler</string> <string name="dialog__cancel_action">Annuler</string>
@ -231,7 +232,6 @@
<string name="level_up__skill_level">niv : %1$d -</string> <string name="level_up__skill_level">niv : %1$d -</string>
<string name="game_master__title">Admin</string> <string name="game_master__title">Admin</string>
<string name="game_master__version">version : %1$s</string>
<string name="game_master__action">GameMaster</string> <string name="game_master__action">GameMaster</string>
<string name="game_master__action__save">Sauvegarder</string> <string name="game_master__action__save">Sauvegarder</string>
<string name="game_master__character__filter">Filtrer par nom :</string> <string name="game_master__character__filter">Filtrer par nom :</string>

View file

@ -6,7 +6,8 @@ import androidx.compose.runtime.compositionLocalOf
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.MainDestination import com.pixelized.desktop.lwa.ui.navigation.screen.destination.SplashDestination
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.composableSplash
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.composableLevelUp import com.pixelized.desktop.lwa.ui.navigation.screen.destination.composableLevelUp
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.composableMainPage import com.pixelized.desktop.lwa.ui.navigation.screen.destination.composableMainPage
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.composableSettingsPage import com.pixelized.desktop.lwa.ui.navigation.screen.destination.composableSettingsPage
@ -18,7 +19,7 @@ val LocalScreenController = compositionLocalOf<NavHostController> {
@Composable @Composable
fun MainNavHost( fun MainNavHost(
controller: NavHostController = rememberNavController(), controller: NavHostController = rememberNavController(),
startDestination: String = MainDestination.navigationRoute(), startDestination: String = SplashDestination.navigationRoute(),
) { ) {
CompositionLocalProvider( CompositionLocalProvider(
LocalScreenController provides controller, LocalScreenController provides controller,
@ -27,6 +28,7 @@ fun MainNavHost(
navController = controller, navController = controller,
startDestination = startDestination, startDestination = startDestination,
) { ) {
composableSplash()
composableMainPage() composableMainPage()
composableSettingsPage() composableSettingsPage()
composableLevelUp() composableLevelUp()

View file

@ -0,0 +1,27 @@
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.splash.SplashScreen
object SplashDestination {
private const val ROUTE = "splash"
fun baseRoute() = ROUTE
fun navigationRoute() = ROUTE
}
fun NavGraphBuilder.composableSplash() {
composable(
route = SplashDestination.baseRoute(),
) {
SplashScreen()
}
}
fun NavHostController.navigateToSplash() {
val route = SplashDestination.navigationRoute()
navigate(route = route)
}

View file

@ -90,14 +90,7 @@ fun CampaignScreen(
}, },
main = { main = {
Box(
modifier = Modifier.matchParentSize(),
contentAlignment = Alignment.BottomCenter,
) {
PortraitOverlay(
modifier = Modifier.padding(all = 8.dp)
)
}
}, },
chat = { chat = {
CampaignChat( CampaignChat(
@ -105,6 +98,16 @@ fun CampaignScreen(
chatViewModel = campaignChatViewModel, chatViewModel = campaignChatViewModel,
) )
}, },
overlay = {
Box(
modifier = Modifier.matchParentSize(),
contentAlignment = Alignment.Center,
) {
PortraitOverlay(
modifier = Modifier.padding(all = 8.dp),
)
}
},
leftPanel = { leftPanel = {
PlayerRibbon( PlayerRibbon(
modifier = Modifier.fillMaxHeight(), modifier = Modifier.fillMaxHeight(),
@ -239,6 +242,7 @@ private fun CampaignLayout(
bottom: @Composable () -> Unit, bottom: @Composable () -> Unit,
main: @Composable () -> Unit, main: @Composable () -> Unit,
chat: @Composable () -> Unit, chat: @Composable () -> Unit,
overlay: @Composable () -> Unit,
leftPanel: @Composable () -> Unit, leftPanel: @Composable () -> Unit,
rightPanel: @Composable () -> Unit, rightPanel: @Composable () -> Unit,
leftOverlay: @Composable () -> Unit, leftOverlay: @Composable () -> Unit,
@ -281,7 +285,7 @@ private fun CampaignLayout(
Box( Box(
modifier = Modifier modifier = Modifier
.align(alignment = Alignment.BottomEnd) .align(alignment = Alignment.BottomEnd)
.onSizeChanged { } .onSizeChanged { chatOverlayState.value = it.toDp(density) },
) { ) {
chat() chat()
} }
@ -292,13 +296,6 @@ private fun CampaignLayout(
) { ) {
leftPanel() leftPanel()
} }
Box(
modifier = Modifier
.align(alignment = Alignment.CenterStart)
.onSizeChanged { leftOverlayState.value = it.toDp(density) },
) {
leftOverlay()
}
Box( Box(
modifier = Modifier modifier = Modifier
.align(alignment = Alignment.CenterEnd) .align(alignment = Alignment.CenterEnd)
@ -306,6 +303,20 @@ private fun CampaignLayout(
) { ) {
rightPanel() rightPanel()
} }
Box(
modifier = Modifier
.align(alignment = Alignment.Center)
.fillMaxSize(),
) {
overlay()
}
Box(
modifier = Modifier
.align(alignment = Alignment.CenterStart)
.onSizeChanged { leftOverlayState.value = it.toDp(density) },
) {
leftOverlay()
}
Box( Box(
modifier = Modifier modifier = Modifier
.align(alignment = Alignment.CenterEnd) .align(alignment = Alignment.CenterEnd)

View file

@ -50,9 +50,13 @@ abstract class CharacterRibbonViewModel(
settings: Settings, settings: Settings,
): Boolean ): Boolean
abstract val enableCharacterSheet: Boolean abstract fun enableCharacterSheet(
settings: Settings,
): Boolean
abstract val enableCharacterStats: Boolean abstract fun enableCharacterStats(
settings: Settings,
): Boolean
/** /**
* This flow is a tad complex so there is an explanation of wtf it's about : * This flow is a tad complex so there is an explanation of wtf it's about :
@ -82,8 +86,8 @@ abstract class CharacterRibbonViewModel(
characterSheet = sheet, characterSheet = sheet,
alterations = alterations, alterations = alterations,
hideOverruled = hideOverruled, hideOverruled = hideOverruled,
enableCharacterSheet = enableCharacterSheet || settings.isGameMaster ?: false, enableCharacterSheet = enableCharacterSheet(settings = settings),
enableCharacterStats = enableCharacterStats || settings.isGameMaster ?: false, enableCharacterStats = enableCharacterStats(settings = settings),
) )
} }
}, },

View file

@ -36,7 +36,11 @@ class NpcRibbonViewModel(
return !campaign.options.showNpcs && settings.isGameMaster == true return !campaign.options.showNpcs && settings.isGameMaster == true
} }
override val enableCharacterSheet = false override fun enableCharacterSheet(settings: Settings) : Boolean {
return settings.isGameMaster ?: false
}
override val enableCharacterStats = false override fun enableCharacterStats(settings: Settings) : Boolean {
return settings.isGameMaster ?: false
}
} }

View file

@ -36,7 +36,7 @@ class PlayerRibbonViewModel(
return !campaign.options.showParty && settings.isGameMaster == true return !campaign.options.showParty && settings.isGameMaster == true
} }
override val enableCharacterSheet = true override fun enableCharacterSheet(settings: Settings) = true
override val enableCharacterStats = true override fun enableCharacterStats(settings: Settings) = true
} }

View file

@ -45,7 +45,7 @@ import com.pixelized.desktop.lwa.ui.theme.lwa
import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.game_master__action import lwacharactersheet.composeapp.generated.resources.game_master__action
import lwacharactersheet.composeapp.generated.resources.game_master__title import lwacharactersheet.composeapp.generated.resources.game_master__title
import lwacharactersheet.composeapp.generated.resources.game_master__version import lwacharactersheet.composeapp.generated.resources.app_version
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel
@ -95,7 +95,7 @@ private fun GameMasterContent(
Text( Text(
modifier = Modifier.alignByBaseline(), modifier = Modifier.alignByBaseline(),
style = MaterialTheme.lwa.typography.base.caption, style = MaterialTheme.lwa.typography.base.caption,
text = stringResource(Res.string.game_master__version, BuildKonfig.version), text = stringResource(Res.string.app_version, BuildKonfig.version),
) )
} }
}, },

View file

@ -0,0 +1,60 @@
package com.pixelized.desktop.lwa.ui.screen.splash
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.pixelized.desktop.lwa.BuildKonfig
import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.navigateToMainPage
import com.pixelized.desktop.lwa.ui.theme.lwa
import kotlinx.coroutines.delay
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.app_name
import lwacharactersheet.composeapp.generated.resources.app_version
import org.jetbrains.compose.resources.stringResource
@Composable
fun SplashScreen() {
val screen = LocalScreenController.current
Surface {
SplashContent(
modifier = Modifier
.fillMaxSize()
.padding(all = 16.dp),
)
}
LaunchedEffect(Unit) {
delay(3000)
screen.navigateToMainPage()
}
}
@Composable
private fun SplashContent(
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier,
) {
Text(
modifier = Modifier.align(Alignment.Center),
style = MaterialTheme.lwa.typography.base.h3,
text = stringResource(Res.string.app_name)
)
Text(
modifier = Modifier.align(Alignment.BottomEnd),
style = MaterialTheme.lwa.typography.base.caption,
text = stringResource(Res.string.app_version, BuildKonfig.version)
)
}
}