Rework a bit the dice throw animation.
This commit is contained in:
parent
248a51f396
commit
aeb8eaf9ff
7 changed files with 192 additions and 163 deletions
|
|
@ -68,7 +68,7 @@ class AlterationRepository @Inject constructor(
|
|||
* get all [Alteration] for a character
|
||||
* @return a list of alterations.
|
||||
*/
|
||||
fun getAssignedAlterations(character: String): Flow<List<Alteration>> {
|
||||
fun getAssignedAlterations(character: String?): Flow<List<Alteration>> {
|
||||
return assignedAlterations.map { alterations ->
|
||||
alterations[character] ?: emptyList()
|
||||
}
|
||||
|
|
@ -81,8 +81,8 @@ class AlterationRepository @Inject constructor(
|
|||
* @return a list of alterations.
|
||||
*/
|
||||
fun getAssignedAlterations(
|
||||
character: String,
|
||||
vararg properties: Property
|
||||
character: String?,
|
||||
properties: List<Property>,
|
||||
): Flow<List<Alteration>> {
|
||||
return getAssignedAlterations(character = character).map { alterations ->
|
||||
alterations.filter { it.status.keys.any { key -> properties.contains(key) } }
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDice
|
|||
import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDiceUio
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCard
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.rememberSlideInOutAnimation
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.slideInOutAnimation
|
||||
import com.pixelized.rplexicon.ui.screens.rolls.preview.rememberRollAlterations
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
|
||||
|
|
@ -167,13 +169,9 @@ private fun RollOverlayContent(
|
|||
onAlteration: (id: String) -> Unit,
|
||||
onThrowVisibilityChange: (Boolean) -> Unit,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
val enableDrawer = remember {
|
||||
derivedStateOf {
|
||||
groups.value.isNotEmpty()
|
||||
}
|
||||
derivedStateOf { groups.value.isNotEmpty() }
|
||||
}
|
||||
|
||||
ModalNavigationDrawer(
|
||||
modifier = modifier,
|
||||
drawerState = drawer,
|
||||
|
|
@ -279,9 +277,9 @@ private fun RollOverlayContent(
|
|||
Box(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
onClick = onClose,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
onClick = onClose,
|
||||
)
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues),
|
||||
|
|
@ -298,6 +296,17 @@ private fun RollOverlayContent(
|
|||
criticalFailure = stringResource(id = R.string.roll_overlay__critical_failure),
|
||||
)
|
||||
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(bottom = if (enableDrawer.value) 32.dp else 0.dp),
|
||||
card = card,
|
||||
isDarkTheme = isDarkTheme,
|
||||
showDetail = showDetail,
|
||||
onCard = onCard
|
||||
)
|
||||
|
||||
AnimatedVisibility(
|
||||
modifier = Modifier.align(alignment = Alignment.BottomEnd),
|
||||
visible = enableDrawer.value,
|
||||
|
|
@ -309,33 +318,6 @@ private fun RollOverlayContent(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedContent(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.align(Alignment.BottomCenter),
|
||||
targetState = card.value,
|
||||
transitionSpec = {
|
||||
animation(density = density) using SizeTransform(clip = false)
|
||||
},
|
||||
label = "RollOverlayDisplay",
|
||||
) {
|
||||
when (it) {
|
||||
null -> Box(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
|
||||
else -> ThrowsCard(
|
||||
modifier = Modifier
|
||||
.padding(bottom = if (enableDrawer.value) 32.dp else 0.dp)
|
||||
.padding(all = 16.dp),
|
||||
isDarkTheme = isDarkTheme,
|
||||
throws = it,
|
||||
showDetail = showDetail,
|
||||
onClick = onCard,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
@ -343,6 +325,33 @@ private fun RollOverlayContent(
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Card(
|
||||
modifier: Modifier = Modifier,
|
||||
card: State<ThrowsCardUio?>,
|
||||
isDarkTheme: Boolean,
|
||||
showDetail: State<Boolean>,
|
||||
onCard: () -> Unit
|
||||
) {
|
||||
AnimatedContent(
|
||||
modifier = modifier,
|
||||
targetState = card.value,
|
||||
transitionSpec = rememberSlideInOutAnimation(),
|
||||
label = "RollOverlayDisplay",
|
||||
) {
|
||||
when (it) {
|
||||
null -> Box(modifier = Modifier.fillMaxWidth())
|
||||
else -> ThrowsCard(
|
||||
modifier = Modifier.padding(all = 16.dp),
|
||||
isDarkTheme = isDarkTheme,
|
||||
throws = it,
|
||||
showDetail = showDetail,
|
||||
onClick = onCard,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Modifier.detailPaddingBottom(
|
||||
showDetail: State<Boolean>,
|
||||
bottom: Dp = 128.dp,
|
||||
|
|
@ -459,12 +468,6 @@ private class RollOverlayPreviewProvider : PreviewParameterProvider<RollOverlayP
|
|||
)
|
||||
}
|
||||
|
||||
private fun animation(density: Density): ContentTransform {
|
||||
val enter = fadeIn() + slideInVertically { with(density) { 64.dp.roundToPx() } }
|
||||
val exit = fadeOut() + slideOutVertically { with(density) { -64.dp.roundToPx() } }
|
||||
return enter togetherWith exit
|
||||
}
|
||||
|
||||
@Stable
|
||||
interface BlurredRollOverlayHostState : BlurredOverlayHostState {
|
||||
suspend fun prepareRoll(diceThrow: DiceThrow)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import androidx.compose.animation.core.Animatable
|
|||
import androidx.compose.animation.core.AnimationVector1D
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
|
@ -14,7 +15,6 @@ import com.pixelized.rplexicon.R
|
|||
import com.pixelized.rplexicon.business.AlterationSortUseCase
|
||||
import com.pixelized.rplexicon.business.DiceThrowUseCase
|
||||
import com.pixelized.rplexicon.data.model.CharacterSheet
|
||||
import com.pixelized.rplexicon.data.model.Description
|
||||
import com.pixelized.rplexicon.data.model.DiceThrow
|
||||
import com.pixelized.rplexicon.data.model.alteration.AlterationStatus
|
||||
import com.pixelized.rplexicon.data.repository.character.ActiveAlterationRepository
|
||||
|
|
@ -39,8 +39,10 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
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 kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -48,9 +50,7 @@ import javax.inject.Inject
|
|||
|
||||
@HiltViewModel
|
||||
class RollOverlayViewModel @Inject constructor(
|
||||
private val characterSheetRepository: CharacterSheetRepository,
|
||||
private val alterationRepository: AlterationRepository,
|
||||
private val activeAlterationRepository: ActiveAlterationRepository,
|
||||
private val descriptionRepository: DescriptionRepository,
|
||||
private val rollUseCase: DiceThrowUseCase,
|
||||
private val diceFactory: DiceFactory,
|
||||
|
|
@ -58,19 +58,47 @@ class RollOverlayViewModel @Inject constructor(
|
|||
private val firebaseRepository: CharacterFireSheetRepository,
|
||||
private val throwRepository: NetworkThrowFireRepository,
|
||||
private val throwCardFactory: ThrowCardFactory,
|
||||
characterSheetRepository: CharacterSheetRepository,
|
||||
activeAlterationRepository: ActiveAlterationRepository,
|
||||
application: Application,
|
||||
) : AndroidViewModel(application) {
|
||||
private var sheet: CharacterSheet? = null
|
||||
private var rollJob: Job? = null
|
||||
private var alterationJob: Job? = null
|
||||
private lateinit var diceThrow: DiceThrow
|
||||
private val _diceThrow = MutableStateFlow<DiceThrow?>(null)
|
||||
|
||||
private val _alterationsOverride = MutableStateFlow<Map<String, Boolean>>(emptyMap())
|
||||
private val _alterations: StateFlow<List<AlterationItemUio>> = combine(
|
||||
_diceThrow,
|
||||
descriptionRepository.data,
|
||||
activeAlterationRepository.getActiveAlterations(),
|
||||
_alterationsOverride,
|
||||
) { diceThrow, descriptions, actives, override ->
|
||||
alterationFactory.convertThrowAlterationItem(
|
||||
diceThrow = diceThrow,
|
||||
description = descriptions,
|
||||
checked = actives[diceThrow?.character]?.associate { it.name to true } ?: emptyMap(),
|
||||
override = override,
|
||||
)
|
||||
}.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.Lazily,
|
||||
initialValue = emptyList(),
|
||||
)
|
||||
|
||||
private val _characterSheet: StateFlow<CharacterSheet?> = combine(
|
||||
characterSheetRepository.data,
|
||||
_diceThrow,
|
||||
) { sheets, diceThrow ->
|
||||
sheets[diceThrow?.character]
|
||||
}.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.Lazily,
|
||||
initialValue = null,
|
||||
)
|
||||
|
||||
private val _alterations = MutableStateFlow<List<AlterationItemUio>>(emptyList())
|
||||
private val _alterationStatusOverride = MutableStateFlow<Map<String, Boolean>>(emptyMap())
|
||||
val alterations: State<List<AlterationGroupUio>>
|
||||
@Composable
|
||||
get() = _alterations.map { data ->
|
||||
data.groupBy { it.source }
|
||||
@Stable
|
||||
get() = combine(_characterSheet, _alterations) { sheet, alterations ->
|
||||
alterations.groupBy { it.source }
|
||||
.toSortedMap(AlterationSortUseCase.sort(sheet = sheet))
|
||||
.map { entry ->
|
||||
AlterationGroupUio(
|
||||
|
|
@ -80,7 +108,8 @@ class RollOverlayViewModel @Inject constructor(
|
|||
}
|
||||
}.collectAsState(initial = emptyList())
|
||||
|
||||
private var targetRoll = 0f
|
||||
private var _rollJob: Job? = null
|
||||
private var _targetRoll = 0f
|
||||
private val _dice = mutableStateOf<RollDiceUio?>(null)
|
||||
val dice: State<RollDiceUio?> get() = _dice
|
||||
val diceRotation: Animatable<Float, AnimationVector1D> = Animatable(0f)
|
||||
|
|
@ -98,83 +127,56 @@ class RollOverlayViewModel @Inject constructor(
|
|||
val alterationDetailDialog: State<AlterationDialogDetailUio?> get() = _alterationDetailDialog
|
||||
|
||||
suspend fun prepareRoll(diceThrow: DiceThrow) {
|
||||
this.targetRoll = 0f
|
||||
this.diceThrow = diceThrow
|
||||
// save the dice throw.
|
||||
_diceThrow.value = diceThrow
|
||||
// reinitialise the roll parameter
|
||||
_targetRoll = 0f
|
||||
_rollJob?.cancel()
|
||||
diceRotation.snapTo(_targetRoll)
|
||||
// hide the throw for other player.
|
||||
_isThrowHidden.value = diceThrow is DiceThrow.DeathSavingThrow
|
||||
// hide the detail throw card.
|
||||
_card.value = null
|
||||
// reset the override status
|
||||
_alterationStatusOverride.value = emptyMap()
|
||||
// get the character sheet.
|
||||
sheet = characterSheetRepository.find(
|
||||
name = diceThrow.character,
|
||||
)
|
||||
_alterationsOverride.value = emptyMap()
|
||||
// build the dice UIO.
|
||||
_dice.value = diceFactory.convertDiceThrow(
|
||||
diceThrow = diceThrow,
|
||||
)
|
||||
// listen to alteration + active to build the list of applicable alteration.
|
||||
alterationJob?.cancel()
|
||||
alterationJob = viewModelScope.launch(Dispatchers.Default) {
|
||||
val character = diceThrow.character
|
||||
val struct = AlterationStruct()
|
||||
descriptionRepository.data
|
||||
.combine(activeAlterationRepository.getActiveAssignedAlterations(character = character)) { descriptions, actives ->
|
||||
struct.descriptions = descriptions
|
||||
struct.actives = actives.associate { it.name to true }
|
||||
}
|
||||
.combine(_alterationStatusOverride) { _, override ->
|
||||
struct.override = override
|
||||
}
|
||||
.collect {
|
||||
val (description, actives, override) = struct
|
||||
val alterations = alterationFactory.convertThrowAlterationItem(
|
||||
diceThrow = diceThrow,
|
||||
description = description,
|
||||
checked = actives,
|
||||
override = override,
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
_alterations.value = alterations
|
||||
}
|
||||
}
|
||||
_dice.value = withContext(Dispatchers.Default) {
|
||||
diceFactory.convertDiceThrow(diceThrow = diceThrow)
|
||||
}
|
||||
}
|
||||
|
||||
fun onAlteration(id: String) {
|
||||
val override = _alterationStatusOverride.value.toMutableMap().also {
|
||||
it[id] = it[id]?.not() ?: firebaseRepository.getAlterationStatusSnapshot(
|
||||
key = AlterationStatus.Key(character = diceThrow.character, alteration = id)
|
||||
).value.not()
|
||||
}
|
||||
_alterationStatusOverride.value = override
|
||||
}
|
||||
|
||||
fun roll(uiScope: CoroutineScope) {
|
||||
rollJob?.cancel()
|
||||
rollJob = uiScope.launch {
|
||||
_rollJob?.cancel()
|
||||
_rollJob = uiScope.launch {
|
||||
// roll the dice ;)
|
||||
val result = rollUseCase.roll(
|
||||
diceThrow = diceThrow,
|
||||
isThrowHidden = _isThrowHidden.value,
|
||||
alterationId = _alterations.value.mapNotNull { if (it.checked) it.label else null },
|
||||
)
|
||||
val result = withContext(Dispatchers.Default) {
|
||||
_diceThrow.value?.let {
|
||||
rollUseCase.roll(
|
||||
diceThrow = it,
|
||||
isThrowHidden = _isThrowHidden.value,
|
||||
alterationId = _alterations.value.mapNotNull { alteration ->
|
||||
if (alteration.checked) alteration.label else null
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
if (result != null) {
|
||||
// reset the displayed dice value
|
||||
_dice.value = result.dice.copy(
|
||||
result = null,
|
||||
isCriticalSuccess = false,
|
||||
isCriticalFailure = false,
|
||||
)
|
||||
_dice.value = withContext(Dispatchers.Default) {
|
||||
result.dice.copy(
|
||||
result = null,
|
||||
isCriticalSuccess = false,
|
||||
isCriticalFailure = false,
|
||||
)
|
||||
}
|
||||
// play the roll animation
|
||||
_targetRoll += 720f
|
||||
launch {
|
||||
targetRoll += 360f * 4
|
||||
diceRotation.animateTo(
|
||||
targetValue = targetRoll,
|
||||
targetValue = _targetRoll,
|
||||
animationSpec = spring(
|
||||
dampingRatio = 0.9f,
|
||||
stiffness = 105f,
|
||||
dampingRatio = 0.8f,
|
||||
stiffness = 15f,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -184,9 +186,17 @@ class RollOverlayViewModel @Inject constructor(
|
|||
if (isActive) {
|
||||
_dice.value = result.dice
|
||||
// share the result
|
||||
throwRepository.sendThrow(sheet?.name, result.throws)
|
||||
// Display the roll card.
|
||||
_card.value = throwCardFactory.convert(result.throws)
|
||||
withContext(Dispatchers.IO) {
|
||||
throwRepository.sendThrow(_characterSheet.value?.name, result.throws)
|
||||
}
|
||||
}
|
||||
// Wait a fix amount of time then
|
||||
delay(RollDiceUio.ROLL_DURATION.toLong() + 250L)
|
||||
// Display the roll card.
|
||||
if (isActive) {
|
||||
_card.value = withContext(Dispatchers.Default) {
|
||||
throwCardFactory.convert(result.throws)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -200,9 +210,21 @@ class RollOverlayViewModel @Inject constructor(
|
|||
_isThrowHidden.value = hidden
|
||||
}
|
||||
|
||||
suspend fun showAlterationDetail(id: String) {
|
||||
fun onAlteration(id: String) {
|
||||
val override = _alterationsOverride.value.toMutableMap().also {
|
||||
it[id] = it[id]?.not() ?: firebaseRepository.getAlterationStatusSnapshot(
|
||||
key = AlterationStatus.Key(
|
||||
character = _diceThrow.value?.character ?: "",
|
||||
alteration = id
|
||||
)
|
||||
).value.not()
|
||||
}
|
||||
_alterationsOverride.value = override
|
||||
}
|
||||
|
||||
fun showAlterationDetail(id: String) {
|
||||
val alteration = alterationRepository.getAssignedAlterationSnapshot(
|
||||
character = diceThrow.character,
|
||||
character = _diceThrow.value?.character,
|
||||
alteration = id,
|
||||
)
|
||||
val description = descriptionRepository.getDescription(
|
||||
|
|
@ -224,10 +246,4 @@ class RollOverlayViewModel @Inject constructor(
|
|||
fun hideAlterationDetail() {
|
||||
_alterationDetailDialog.value = null
|
||||
}
|
||||
|
||||
private data class AlterationStruct(
|
||||
var descriptions: Map<String, Description> = emptyMap(),
|
||||
var actives: Map<String, Boolean> = emptyMap(),
|
||||
var override: Map<String, Boolean> = emptyMap(),
|
||||
)
|
||||
}
|
||||
|
|
@ -1,18 +1,14 @@
|
|||
package com.pixelized.rplexicon.ui.screens.rolls.composable
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.SizeTransform
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.AnimationVector1D
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.expandIn
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.shrinkOut
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
|
|
@ -43,7 +39,6 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.agsl.dancingColor
|
||||
|
|
@ -59,7 +54,7 @@ data class RollDiceUio(
|
|||
val isCriticalFailure: Boolean = false,
|
||||
val result: String? = null,
|
||||
) {
|
||||
companion object{
|
||||
companion object {
|
||||
const val ROLL_DURATION = 500
|
||||
}
|
||||
}
|
||||
|
|
@ -146,33 +141,18 @@ private fun Result(
|
|||
dice: State<RollDiceUio?>,
|
||||
) {
|
||||
AnimatedContent(
|
||||
modifier = modifier,
|
||||
targetState = dice.value?.result,
|
||||
transitionSpec = {
|
||||
val enter = fadeIn() +
|
||||
expandIn(expandFrom = Alignment.Center) { it } +
|
||||
slideInVertically { it / 5 }
|
||||
val exit = fadeOut() +
|
||||
shrinkOut(shrinkTowards = Alignment.Center) { IntSize.Zero } +
|
||||
slideOutVertically { -it / 5 }
|
||||
enter togetherWith exit using SizeTransform(clip = false)
|
||||
},
|
||||
transitionSpec = rememberSlideInOutAnimation(),
|
||||
label = "ResultAnimation"
|
||||
) {
|
||||
when (it) {
|
||||
null -> Box(
|
||||
modifier = Modifier,
|
||||
Box(
|
||||
modifier = modifier,
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lexicon.typography.diceRoll,
|
||||
text = it ?: "",
|
||||
)
|
||||
|
||||
else -> Box(
|
||||
modifier = Modifier,
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lexicon.typography.diceRoll,
|
||||
text = it,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -221,7 +201,8 @@ private fun Critical(
|
|||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun SkillRollPreview(
|
||||
@PreviewParameter(SkillRollPreviewProvider::class) preview: Int,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
package com.pixelized.rplexicon.ui.screens.rolls.composable
|
||||
|
||||
import androidx.compose.animation.AnimatedContentTransitionScope
|
||||
import androidx.compose.animation.ContentTransform
|
||||
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.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun <S> rememberSlideInOutAnimation(): AnimatedContentTransitionScope<S>.() -> ContentTransform {
|
||||
val density = LocalDensity.current
|
||||
return remember(density) {
|
||||
{ slideInOutAnimation(density = density) }
|
||||
}
|
||||
}
|
||||
|
||||
fun slideInOutAnimation(density: Density): ContentTransform {
|
||||
val enter = fadeIn() + slideInVertically { with(density) { 64.dp.roundToPx() } }
|
||||
val exit = fadeOut() + slideOutVertically { with(density) { -64.dp.roundToPx() } }
|
||||
return enter togetherWith exit
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ class AlterationFactory @Inject constructor(
|
|||
}
|
||||
|
||||
suspend fun convertThrowAlterationItem(
|
||||
diceThrow: DiceThrow,
|
||||
diceThrow: DiceThrow?,
|
||||
description: Map<String, Description>,
|
||||
checked: Map<String, Boolean>,
|
||||
override: Map<String, Boolean>,
|
||||
|
|
@ -139,10 +139,12 @@ class AlterationFactory @Inject constructor(
|
|||
}
|
||||
|
||||
is DiceThrow.Object -> listOf(Property.OBJECT_EFFECT)
|
||||
|
||||
null -> emptyList()
|
||||
}
|
||||
|
||||
return alterationRepository
|
||||
.getAssignedAlterations(character = diceThrow.character, *properties.toTypedArray())
|
||||
.getAssignedAlterations(character = diceThrow?.character, properties)
|
||||
.firstOrNull()
|
||||
?.map { alteration ->
|
||||
AlterationItemUio(
|
||||
|
|
|
|||
|
|
@ -187,10 +187,7 @@ fun lexiconTypography(
|
|||
),
|
||||
diceRoll: TextStyle = base.displayMedium.copy(
|
||||
shadow = when (isDarkTheme) {
|
||||
true -> Shadow(
|
||||
offset = Offset(4f, 4f),
|
||||
blurRadius = 8f,
|
||||
)
|
||||
true -> Shadow(blurRadius = 12f)
|
||||
else -> null
|
||||
}
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue