Fix portrait display to use the preview instead of the character Detail.
This avoid to fetch the character detail just to get the portrait.
This commit is contained in:
parent
a84c170396
commit
50697ceb93
8 changed files with 53 additions and 15 deletions
|
|
@ -284,6 +284,9 @@
|
||||||
<string name="level_up__character_level_description">Passage du niveau %1$d ▸ %2$d</string>
|
<string name="level_up__character_level_description">Passage du niveau %1$d ▸ %2$d</string>
|
||||||
<string name="level_up__skill_level">niv : %1$d -</string>
|
<string name="level_up__skill_level">niv : %1$d -</string>
|
||||||
|
|
||||||
|
<string name="portrait_overlay__external_link">Lien vers l'image</string>
|
||||||
|
<string name="portrait_overlay__close">Fermer</string>
|
||||||
|
|
||||||
<string name="game_master__title">Admin</string>
|
<string name="game_master__title">Admin</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>
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@ class CharacterSheetRepository(
|
||||||
store.updateCharacterSheetDetailFlow(characterSheetId = characterSheetId)
|
store.updateCharacterSheetDetailFlow(characterSheetId = characterSheetId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun characterPreview(characterId: String?): CharacterSheetPreview? {
|
fun characterPreview(characterSheetId: String?): CharacterSheetPreview? {
|
||||||
return store.previewFlow.value.firstOrNull { it.characterSheetId == characterId }
|
return store.previewFlow.value.firstOrNull { it.characterSheetId == characterSheetId }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun characterDetail(
|
fun characterDetail(
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,18 @@ import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.togetherWith
|
import androidx.compose.animation.togetherWith
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Row
|
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.Icon
|
||||||
import androidx.compose.material.IconButton
|
import androidx.compose.material.IconButton
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.material.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
|
|
@ -21,13 +27,19 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.FilterQuality
|
import androidx.compose.ui.graphics.FilterQuality
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
|
import com.pixelized.desktop.lwa.ui.theme.color.component.LwaButtonColors
|
||||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||||
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_cancel_24dp
|
import lwacharactersheet.composeapp.generated.resources.ic_cancel_24dp
|
||||||
import lwacharactersheet.composeapp.generated.resources.ic_link_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.painterResource
|
||||||
|
import org.jetbrains.compose.resources.stringResource
|
||||||
import org.koin.compose.viewmodel.koinViewModel
|
import org.koin.compose.viewmodel.koinViewModel
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
|
|
@ -79,30 +91,35 @@ private fun PortraitContent(
|
||||||
) {
|
) {
|
||||||
when (it) {
|
when (it) {
|
||||||
null -> Box(
|
null -> Box(
|
||||||
modifier = Modifier.size(size = MaterialTheme.lwa.size.portrait.maximized)
|
modifier = Modifier.fillMaxSize(),
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> Box(
|
else -> Box(
|
||||||
modifier = Modifier.size(size = MaterialTheme.lwa.size.portrait.maximized)
|
modifier = Modifier.fillMaxSize(),
|
||||||
) {
|
) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
modifier = Modifier.matchParentSize(),
|
modifier = Modifier.matchParentSize(),
|
||||||
model = it,
|
model = it,
|
||||||
filterQuality = FilterQuality.High,
|
filterQuality = FilterQuality.High,
|
||||||
|
contentScale = ContentScale.Inside,
|
||||||
|
alignment = Alignment.Center,
|
||||||
contentDescription = null
|
contentDescription = null
|
||||||
)
|
)
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(alignment = Alignment.TopEnd)
|
.align(alignment = Alignment.BottomCenter)
|
||||||
.animateContentSize(),
|
.animateContentSize(),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||||
) {
|
) {
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = options.value.isBrowserAvailable,
|
visible = options.value.isBrowserAvailable,
|
||||||
enter = fadeIn(),
|
enter = fadeIn(),
|
||||||
exit = fadeOut(),
|
exit = fadeOut(),
|
||||||
) {
|
) {
|
||||||
IconButton(
|
Button(
|
||||||
|
colors = LwaButtonColors(),
|
||||||
|
shape = CircleShape,
|
||||||
onClick = { onDownload(it) },
|
onClick = { onDownload(it) },
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -110,6 +127,10 @@ private fun PortraitContent(
|
||||||
tint = MaterialTheme.lwa.colorScheme.base.primary,
|
tint = MaterialTheme.lwa.colorScheme.base.primary,
|
||||||
contentDescription = null
|
contentDescription = null
|
||||||
)
|
)
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.padding(start = 4.dp),
|
||||||
|
text = stringResource(Res.string.portrait_overlay__external_link),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
|
|
@ -117,7 +138,9 @@ private fun PortraitContent(
|
||||||
enter = fadeIn(),
|
enter = fadeIn(),
|
||||||
exit = fadeOut(),
|
exit = fadeOut(),
|
||||||
) {
|
) {
|
||||||
IconButton(
|
Button(
|
||||||
|
colors = LwaButtonColors(),
|
||||||
|
shape = CircleShape,
|
||||||
onClick = onClose,
|
onClick = onClose,
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -125,6 +148,10 @@ private fun PortraitContent(
|
||||||
tint = MaterialTheme.lwa.colorScheme.base.primary,
|
tint = MaterialTheme.lwa.colorScheme.base.primary,
|
||||||
contentDescription = null
|
contentDescription = null
|
||||||
)
|
)
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.padding(start = 4.dp),
|
||||||
|
text = stringResource(Res.string.portrait_overlay__close),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,13 @@ class PortraitOverlayViewModel(
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
val portrait = networkRepository.data
|
val portrait = networkRepository.data
|
||||||
.mapNotNull { it as? GameMasterEvent.DisplayPortrait }
|
.mapNotNull { it as? GameMasterEvent.DisplayPortrait }
|
||||||
.flatMapLatest { characterSheetRepository.characterDetailFlow(characterSheetId = it.characterSheetId) }
|
.flatMapLatest { portrait ->
|
||||||
.map { it?.portrait }
|
characterSheetRepository.characterSheetPreviewFlow().map { previews ->
|
||||||
|
previews.firstOrNull { it.characterSheetId == portrait.characterSheetId }
|
||||||
|
}
|
||||||
|
}
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
|
.map { it?.portrait }
|
||||||
.stateIn(
|
.stateIn(
|
||||||
scope = viewModelScope,
|
scope = viewModelScope,
|
||||||
started = SharingStarted.Eagerly,
|
started = SharingStarted.Eagerly,
|
||||||
|
|
@ -37,7 +41,7 @@ class PortraitOverlayViewModel(
|
||||||
val options = settingsRepository.settingsFlow()
|
val options = settingsRepository.settingsFlow()
|
||||||
.map { settings ->
|
.map { settings ->
|
||||||
PortraitOptionUio(
|
PortraitOptionUio(
|
||||||
isGameMaster = settings.isGameMaster ?: false,
|
isGameMaster = settings.isGameMaster == true,
|
||||||
isBrowserAvailable = Desktop.isDesktopSupported()
|
isBrowserAvailable = Desktop.isDesktopSupported()
|
||||||
&& Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)
|
&& Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class TextMessageFactory(
|
||||||
return when (message) {
|
return when (message) {
|
||||||
is RollEvent -> {
|
is RollEvent -> {
|
||||||
val sheetPreview = characterSheetRepository
|
val sheetPreview = characterSheetRepository
|
||||||
.characterPreview(characterId = message.characterSheetId)
|
.characterPreview(characterSheetId = message.characterSheetId)
|
||||||
?: return null
|
?: return null
|
||||||
|
|
||||||
val isGm = settings.isGameMaster ?: false
|
val isGm = settings.isGameMaster ?: false
|
||||||
|
|
@ -72,7 +72,7 @@ class TextMessageFactory(
|
||||||
if ((isInParty || isInNpcs).not()) return null
|
if ((isInParty || isInNpcs).not()) return null
|
||||||
// get the character sheet
|
// get the character sheet
|
||||||
val sheetPreview = characterSheetRepository
|
val sheetPreview = characterSheetRepository
|
||||||
.characterPreview(characterId = message.characterSheetId)
|
.characterPreview(characterSheetId = message.characterSheetId)
|
||||||
?: return null
|
?: return null
|
||||||
|
|
||||||
DiminishedTextMessageUio(
|
DiminishedTextMessageUio(
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ data class LwaSize(
|
||||||
) {
|
) {
|
||||||
@Stable
|
@Stable
|
||||||
data class Portrait(
|
data class Portrait(
|
||||||
val maximized: DpSize,
|
|
||||||
val minimized: DpSize,
|
val minimized: DpSize,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -30,7 +29,6 @@ data class LwaSize(
|
||||||
fun lwaSize(
|
fun lwaSize(
|
||||||
portrait: LwaSize.Portrait = LwaSize.Portrait(
|
portrait: LwaSize.Portrait = LwaSize.Portrait(
|
||||||
minimized = DpSize(width = 96.dp, height = 128.dp),
|
minimized = DpSize(width = 96.dp, height = 128.dp),
|
||||||
maximized = DpSize(width = 512.dp, height = 512.dp),
|
|
||||||
),
|
),
|
||||||
sheet: LwaSize.Sheet = LwaSize.Sheet(
|
sheet: LwaSize.Sheet = LwaSize.Sheet(
|
||||||
subCategory = 14.dp,
|
subCategory = 14.dp,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ package com.pixelized.shared.lwa.model.characterSheet
|
||||||
data class CharacterSheetPreview(
|
data class CharacterSheetPreview(
|
||||||
val characterSheetId: String,
|
val characterSheetId: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
|
val portrait: String?,
|
||||||
|
val thumbnail: String?,
|
||||||
val job: String,
|
val job: String,
|
||||||
val level: Int,
|
val level: Int,
|
||||||
val externalLink: String?,
|
val externalLink: String?,
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,8 @@ class CharacterSheetJsonFactory(
|
||||||
return CharacterSheetPreview(
|
return CharacterSheetPreview(
|
||||||
characterSheetId = sheet.id,
|
characterSheetId = sheet.id,
|
||||||
name = sheet.name,
|
name = sheet.name,
|
||||||
|
portrait = sheet.portrait,
|
||||||
|
thumbnail = sheet.thumbnail,
|
||||||
job = sheet.job,
|
job = sheet.job,
|
||||||
level = sheet.level,
|
level = sheet.level,
|
||||||
externalLink = sheet.externalLink,
|
externalLink = sheet.externalLink,
|
||||||
|
|
@ -114,6 +116,8 @@ class CharacterSheetJsonFactory(
|
||||||
return CharacterSheetPreview(
|
return CharacterSheetPreview(
|
||||||
characterSheetId = json.id,
|
characterSheetId = json.id,
|
||||||
name = json.name,
|
name = json.name,
|
||||||
|
portrait = json.portrait,
|
||||||
|
thumbnail = json.thumbnail,
|
||||||
job = json.job ?: "",
|
job = json.job ?: "",
|
||||||
level = json.level,
|
level = json.level,
|
||||||
externalLink = json.externalLink,
|
externalLink = json.externalLink,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue