diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml index 0de75f5..164a914 100644 --- a/composeApp/src/commonMain/composeResources/values/strings.xml +++ b/composeApp/src/commonMain/composeResources/values/strings.xml @@ -284,6 +284,9 @@ Passage du niveau %1$d ▸ %2$d niv : %1$d - + Lien vers l'image + Fermer + Admin GameMaster Sauvegarder diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt index 74b9ec4..9e7ab9a 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetRepository.kt @@ -27,8 +27,8 @@ class CharacterSheetRepository( store.updateCharacterSheetDetailFlow(characterSheetId = characterSheetId) } - fun characterPreview(characterId: String?): CharacterSheetPreview? { - return store.previewFlow.value.firstOrNull { it.characterSheetId == characterId } + fun characterPreview(characterSheetId: String?): CharacterSheetPreview? { + return store.previewFlow.value.firstOrNull { it.characterSheetId == characterSheetId } } fun characterDetail( diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/portrait/PortraitOverlay.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/portrait/PortraitOverlay.kt index 39586d3..4d4f2ce 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/portrait/PortraitOverlay.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/portrait/PortraitOverlay.kt @@ -6,12 +6,18 @@ import androidx.compose.animation.animateContentSize import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.togetherWith +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.Button import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.State @@ -21,13 +27,19 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.FilterQuality +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage +import com.pixelized.desktop.lwa.ui.theme.color.component.LwaButtonColors 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.ic_link_24dp +import lwacharactersheet.composeapp.generated.resources.portrait_overlay__close +import lwacharactersheet.composeapp.generated.resources.portrait_overlay__external_link import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel @Stable @@ -79,30 +91,35 @@ private fun PortraitContent( ) { when (it) { null -> Box( - modifier = Modifier.size(size = MaterialTheme.lwa.size.portrait.maximized) + modifier = Modifier.fillMaxSize(), ) else -> Box( - modifier = Modifier.size(size = MaterialTheme.lwa.size.portrait.maximized) + modifier = Modifier.fillMaxSize(), ) { AsyncImage( modifier = Modifier.matchParentSize(), model = it, filterQuality = FilterQuality.High, + contentScale = ContentScale.Inside, + alignment = Alignment.Center, contentDescription = null ) Row( modifier = Modifier - .align(alignment = Alignment.TopEnd) + .align(alignment = Alignment.BottomCenter) .animateContentSize(), + horizontalArrangement = Arrangement.spacedBy(space = 8.dp), ) { AnimatedVisibility( visible = options.value.isBrowserAvailable, enter = fadeIn(), exit = fadeOut(), ) { - IconButton( + Button( + colors = LwaButtonColors(), + shape = CircleShape, onClick = { onDownload(it) }, ) { Icon( @@ -110,6 +127,10 @@ private fun PortraitContent( tint = MaterialTheme.lwa.colorScheme.base.primary, contentDescription = null ) + Text( + modifier = Modifier.padding(start = 4.dp), + text = stringResource(Res.string.portrait_overlay__external_link), + ) } } AnimatedVisibility( @@ -117,7 +138,9 @@ private fun PortraitContent( enter = fadeIn(), exit = fadeOut(), ) { - IconButton( + Button( + colors = LwaButtonColors(), + shape = CircleShape, onClick = onClose, ) { Icon( @@ -125,6 +148,10 @@ private fun PortraitContent( tint = MaterialTheme.lwa.colorScheme.base.primary, contentDescription = null ) + Text( + modifier = Modifier.padding(start = 4.dp), + text = stringResource(Res.string.portrait_overlay__close), + ) } } } diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/portrait/PortraitOverlayViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/portrait/PortraitOverlayViewModel.kt index e5e75b4..8ced0d1 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/portrait/PortraitOverlayViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/portrait/PortraitOverlayViewModel.kt @@ -25,9 +25,13 @@ class PortraitOverlayViewModel( @OptIn(ExperimentalCoroutinesApi::class) val portrait = networkRepository.data .mapNotNull { it as? GameMasterEvent.DisplayPortrait } - .flatMapLatest { characterSheetRepository.characterDetailFlow(characterSheetId = it.characterSheetId) } - .map { it?.portrait } + .flatMapLatest { portrait -> + characterSheetRepository.characterSheetPreviewFlow().map { previews -> + previews.firstOrNull { it.characterSheetId == portrait.characterSheetId } + } + } .distinctUntilChanged() + .map { it?.portrait } .stateIn( scope = viewModelScope, started = SharingStarted.Eagerly, @@ -37,7 +41,7 @@ class PortraitOverlayViewModel( val options = settingsRepository.settingsFlow() .map { settings -> PortraitOptionUio( - isGameMaster = settings.isGameMaster ?: false, + isGameMaster = settings.isGameMaster == true, isBrowserAvailable = Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE) ) diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/text/TextMessageFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/text/TextMessageFactory.kt index 0148b95..cbb6ece 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/text/TextMessageFactory.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/text/TextMessageFactory.kt @@ -38,7 +38,7 @@ class TextMessageFactory( return when (message) { is RollEvent -> { val sheetPreview = characterSheetRepository - .characterPreview(characterId = message.characterSheetId) + .characterPreview(characterSheetId = message.characterSheetId) ?: return null val isGm = settings.isGameMaster ?: false @@ -72,7 +72,7 @@ class TextMessageFactory( if ((isInParty || isInNpcs).not()) return null // get the character sheet val sheetPreview = characterSheetRepository - .characterPreview(characterId = message.characterSheetId) + .characterPreview(characterSheetId = message.characterSheetId) ?: return null DiminishedTextMessageUio( diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/size/LwaSize.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/size/LwaSize.kt index 9650cc7..57dd396 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/size/LwaSize.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/size/LwaSize.kt @@ -14,7 +14,6 @@ data class LwaSize( ) { @Stable data class Portrait( - val maximized: DpSize, val minimized: DpSize, ) @@ -30,7 +29,6 @@ data class LwaSize( fun lwaSize( portrait: LwaSize.Portrait = LwaSize.Portrait( minimized = DpSize(width = 96.dp, height = 128.dp), - maximized = DpSize(width = 512.dp, height = 512.dp), ), sheet: LwaSize.Sheet = LwaSize.Sheet( subCategory = 14.dp, diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/characterSheet/CharacterSheetPreview.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/characterSheet/CharacterSheetPreview.kt index 3c2c27c..eb4a32a 100644 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/characterSheet/CharacterSheetPreview.kt +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/characterSheet/CharacterSheetPreview.kt @@ -3,6 +3,8 @@ package com.pixelized.shared.lwa.model.characterSheet data class CharacterSheetPreview( val characterSheetId: String, val name: String, + val portrait: String?, + val thumbnail: String?, val job: String, val level: Int, val externalLink: String?, diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/characterSheet/factory/CharacterSheetJsonFactory.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/characterSheet/factory/CharacterSheetJsonFactory.kt index 40bb456..400e53a 100644 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/characterSheet/factory/CharacterSheetJsonFactory.kt +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/characterSheet/factory/CharacterSheetJsonFactory.kt @@ -101,6 +101,8 @@ class CharacterSheetJsonFactory( return CharacterSheetPreview( characterSheetId = sheet.id, name = sheet.name, + portrait = sheet.portrait, + thumbnail = sheet.thumbnail, job = sheet.job, level = sheet.level, externalLink = sheet.externalLink, @@ -114,6 +116,8 @@ class CharacterSheetJsonFactory( return CharacterSheetPreview( characterSheetId = json.id, name = json.name, + portrait = json.portrait, + thumbnail = json.thumbnail, job = json.job ?: "", level = json.level, externalLink = json.externalLink,