Update the alteration design.
This commit is contained in:
		
							parent
							
								
									9cbd33fd2e
								
							
						
					
					
						commit
						00267623ca
					
				
					 7 changed files with 171 additions and 110 deletions
				
			
		| 
						 | 
					@ -5,8 +5,6 @@ import android.content.res.Configuration.UI_MODE_NIGHT_YES
 | 
				
			||||||
import androidx.compose.foundation.clickable
 | 
					import androidx.compose.foundation.clickable
 | 
				
			||||||
import androidx.compose.foundation.layout.Arrangement
 | 
					import androidx.compose.foundation.layout.Arrangement
 | 
				
			||||||
import androidx.compose.foundation.layout.Column
 | 
					import androidx.compose.foundation.layout.Column
 | 
				
			||||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
 | 
					 | 
				
			||||||
import androidx.compose.foundation.layout.FlowRow
 | 
					 | 
				
			||||||
import androidx.compose.foundation.layout.PaddingValues
 | 
					import androidx.compose.foundation.layout.PaddingValues
 | 
				
			||||||
import androidx.compose.foundation.layout.Row
 | 
					import androidx.compose.foundation.layout.Row
 | 
				
			||||||
import androidx.compose.foundation.layout.fillMaxWidth
 | 
					import androidx.compose.foundation.layout.fillMaxWidth
 | 
				
			||||||
| 
						 | 
					@ -31,12 +29,11 @@ import com.pixelized.rplexicon.ui.theme.LexiconTheme
 | 
				
			||||||
@Stable
 | 
					@Stable
 | 
				
			||||||
data class AlterationItemUio(
 | 
					data class AlterationItemUio(
 | 
				
			||||||
    val label: String,
 | 
					    val label: String,
 | 
				
			||||||
    val original: String?,
 | 
					    val source: String,
 | 
				
			||||||
    val subLabel: String?,
 | 
					    val subLabel: String?,
 | 
				
			||||||
    val checked: Boolean,
 | 
					    val checked: Boolean,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@OptIn(ExperimentalLayoutApi::class)
 | 
					 | 
				
			||||||
@Composable
 | 
					@Composable
 | 
				
			||||||
fun AlterationItem(
 | 
					fun AlterationItem(
 | 
				
			||||||
    modifier: Modifier = Modifier,
 | 
					    modifier: Modifier = Modifier,
 | 
				
			||||||
| 
						 | 
					@ -58,37 +55,23 @@ fun AlterationItem(
 | 
				
			||||||
            modifier = Modifier.weight(weight = 1f),
 | 
					            modifier = Modifier.weight(weight = 1f),
 | 
				
			||||||
            verticalArrangement = Arrangement.spacedBy(space = 2.dp),
 | 
					            verticalArrangement = Arrangement.spacedBy(space = 2.dp),
 | 
				
			||||||
        ) {
 | 
					        ) {
 | 
				
			||||||
            FlowRow(
 | 
					            Text(
 | 
				
			||||||
                horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
 | 
					                style = MaterialTheme.typography.bodyMedium,
 | 
				
			||||||
            ) {
 | 
					                fontWeight = FontWeight.Bold,
 | 
				
			||||||
                Text(
 | 
					                overflow = TextOverflow.Ellipsis,
 | 
				
			||||||
                    modifier = Modifier.alignByBaseline(),
 | 
					                maxLines = 1,
 | 
				
			||||||
                    style = MaterialTheme.typography.bodyMedium,
 | 
					                text = alteration.label,
 | 
				
			||||||
                    fontWeight = FontWeight.Bold,
 | 
					            )
 | 
				
			||||||
                    overflow = TextOverflow.Ellipsis,
 | 
					 | 
				
			||||||
                    maxLines = 1,
 | 
					 | 
				
			||||||
                    text = alteration.label,
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                alteration.original?.let {
 | 
					 | 
				
			||||||
                    Text(
 | 
					 | 
				
			||||||
                        modifier = Modifier.alignByBaseline(),
 | 
					 | 
				
			||||||
                        style = MaterialTheme.typography.labelSmall,
 | 
					 | 
				
			||||||
                        fontWeight = FontWeight.Light,
 | 
					 | 
				
			||||||
                        overflow = TextOverflow.Ellipsis,
 | 
					 | 
				
			||||||
                        maxLines = 1,
 | 
					 | 
				
			||||||
                        text = it,
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            alteration.subLabel?.let {
 | 
					            alteration.subLabel?.let {
 | 
				
			||||||
                Text(
 | 
					                Text(
 | 
				
			||||||
                    style = MaterialTheme.typography.labelSmall,
 | 
					                    style = MaterialTheme.typography.labelSmall,
 | 
				
			||||||
                    fontWeight = FontWeight.Normal,
 | 
					                    fontWeight = FontWeight.Light,
 | 
				
			||||||
 | 
					                    overflow = TextOverflow.Ellipsis,
 | 
				
			||||||
 | 
					                    maxLines = 1,
 | 
				
			||||||
                    text = it,
 | 
					                    text = it,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        Switch(
 | 
					        Switch(
 | 
				
			||||||
            enabled = true,
 | 
					            enabled = true,
 | 
				
			||||||
            checked = alteration.checked,
 | 
					            checked = alteration.checked,
 | 
				
			||||||
| 
						 | 
					@ -117,23 +100,17 @@ private fun RollAlterationPreview(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private class RollAlterationPreviewProvider : PreviewParameterProvider<AlterationItemUio> {
 | 
					private class RollAlterationPreviewProvider : PreviewParameterProvider<AlterationItemUio> {
 | 
				
			||||||
    override val values: Sequence<AlterationItemUio> = sequenceOf(
 | 
					    override val values: Sequence<AlterationItemUio> = sequenceOf(
 | 
				
			||||||
        AlterationItemUio(
 | 
					 | 
				
			||||||
            label = "Critique",
 | 
					 | 
				
			||||||
            original = "Critical",
 | 
					 | 
				
			||||||
            checked = false,
 | 
					 | 
				
			||||||
            subLabel = null,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        AlterationItemUio(
 | 
					 | 
				
			||||||
            label = "Rage",
 | 
					 | 
				
			||||||
            original = "Rage",
 | 
					 | 
				
			||||||
            checked = true,
 | 
					 | 
				
			||||||
            subLabel = "Barbare",
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        AlterationItemUio(
 | 
					        AlterationItemUio(
 | 
				
			||||||
            label = "Bénédiction",
 | 
					            label = "Bénédiction",
 | 
				
			||||||
            original = "Bless",
 | 
					            subLabel = "Bless",
 | 
				
			||||||
 | 
					            source = "Clerc",
 | 
				
			||||||
            checked = false,
 | 
					            checked = false,
 | 
				
			||||||
            subLabel = "Clerc",
 | 
					        ),
 | 
				
			||||||
 | 
					        AlterationItemUio(
 | 
				
			||||||
 | 
					            label = "Assistance",
 | 
				
			||||||
 | 
					            subLabel = "Guidance",
 | 
				
			||||||
 | 
					            source = "Clerc",
 | 
				
			||||||
 | 
					            checked = true,
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2,14 +2,15 @@ package com.pixelized.rplexicon.ui.screens.character.pages.alteration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
 | 
					import android.content.res.Configuration.UI_MODE_NIGHT_NO
 | 
				
			||||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
 | 
					import android.content.res.Configuration.UI_MODE_NIGHT_YES
 | 
				
			||||||
import androidx.compose.foundation.ExperimentalFoundationApi
 | 
					 | 
				
			||||||
import androidx.compose.foundation.layout.PaddingValues
 | 
					import androidx.compose.foundation.layout.PaddingValues
 | 
				
			||||||
import androidx.compose.foundation.layout.fillMaxSize
 | 
					import androidx.compose.foundation.layout.fillMaxSize
 | 
				
			||||||
import androidx.compose.foundation.layout.fillMaxWidth
 | 
					import androidx.compose.foundation.layout.fillMaxWidth
 | 
				
			||||||
 | 
					import androidx.compose.foundation.layout.padding
 | 
				
			||||||
import androidx.compose.foundation.lazy.LazyColumn
 | 
					import androidx.compose.foundation.lazy.LazyColumn
 | 
				
			||||||
import androidx.compose.foundation.lazy.items
 | 
					import androidx.compose.foundation.lazy.items
 | 
				
			||||||
import androidx.compose.material3.Surface
 | 
					import androidx.compose.material3.Surface
 | 
				
			||||||
import androidx.compose.runtime.Composable
 | 
					import androidx.compose.runtime.Composable
 | 
				
			||||||
 | 
					import androidx.compose.runtime.Stable
 | 
				
			||||||
import androidx.compose.runtime.State
 | 
					import androidx.compose.runtime.State
 | 
				
			||||||
import androidx.compose.runtime.remember
 | 
					import androidx.compose.runtime.remember
 | 
				
			||||||
import androidx.compose.runtime.rememberCoroutineScope
 | 
					import androidx.compose.runtime.rememberCoroutineScope
 | 
				
			||||||
| 
						 | 
					@ -19,12 +20,18 @@ import androidx.compose.ui.unit.dp
 | 
				
			||||||
import androidx.compose.ui.window.Dialog
 | 
					import androidx.compose.ui.window.Dialog
 | 
				
			||||||
import androidx.compose.ui.window.DialogProperties
 | 
					import androidx.compose.ui.window.DialogProperties
 | 
				
			||||||
import androidx.hilt.navigation.compose.hiltViewModel
 | 
					import androidx.hilt.navigation.compose.hiltViewModel
 | 
				
			||||||
 | 
					import com.pixelized.rplexicon.ui.composable.CategoryHeader
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItem
 | 
					import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItem
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio
 | 
					import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.rolls.preview.rememberRollAlterations
 | 
					import com.pixelized.rplexicon.ui.screens.rolls.preview.rememberRollAlterations
 | 
				
			||||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
 | 
					import com.pixelized.rplexicon.ui.theme.LexiconTheme
 | 
				
			||||||
import kotlinx.coroutines.launch
 | 
					import kotlinx.coroutines.launch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Stable
 | 
				
			||||||
 | 
					data class AlterationGroupUio(
 | 
				
			||||||
 | 
					    val name: String,
 | 
				
			||||||
 | 
					    val alterations: List<AlterationItemUio>,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Composable
 | 
					@Composable
 | 
				
			||||||
fun AlterationPage(
 | 
					fun AlterationPage(
 | 
				
			||||||
| 
						 | 
					@ -34,7 +41,7 @@ fun AlterationPage(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    AlterationPageContent(
 | 
					    AlterationPageContent(
 | 
				
			||||||
        modifier = Modifier.fillMaxSize(),
 | 
					        modifier = Modifier.fillMaxSize(),
 | 
				
			||||||
        alterations = viewModel.alterations,
 | 
					        groups = viewModel.alterations,
 | 
				
			||||||
        onAlterationInfo = {
 | 
					        onAlterationInfo = {
 | 
				
			||||||
            viewModel.showAlterationDetail(id = it)
 | 
					            viewModel.showAlterationDetail(id = it)
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
| 
						 | 
					@ -51,11 +58,10 @@ fun AlterationPage(
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@OptIn(ExperimentalFoundationApi::class)
 | 
					 | 
				
			||||||
@Composable
 | 
					@Composable
 | 
				
			||||||
fun AlterationPageContent(
 | 
					fun AlterationPageContent(
 | 
				
			||||||
    modifier: Modifier = Modifier,
 | 
					    modifier: Modifier = Modifier,
 | 
				
			||||||
    alterations: State<List<AlterationItemUio>>,
 | 
					    groups: State<List<AlterationGroupUio>>,
 | 
				
			||||||
    onAlterationInfo: (String) -> Unit,
 | 
					    onAlterationInfo: (String) -> Unit,
 | 
				
			||||||
    onAlterationClick: (String) -> Unit,
 | 
					    onAlterationClick: (String) -> Unit,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
| 
						 | 
					@ -63,13 +69,24 @@ fun AlterationPageContent(
 | 
				
			||||||
        modifier = modifier,
 | 
					        modifier = modifier,
 | 
				
			||||||
        contentPadding = PaddingValues(top = 8.dp, bottom = 16.dp),
 | 
					        contentPadding = PaddingValues(top = 8.dp, bottom = 16.dp),
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        items(items = alterations.value) {
 | 
					        groups.value.forEachIndexed { index, group ->
 | 
				
			||||||
            AlterationItem(
 | 
					            item {
 | 
				
			||||||
                modifier = Modifier.fillMaxWidth(),
 | 
					                CategoryHeader(
 | 
				
			||||||
                alteration = it,
 | 
					                    modifier = Modifier
 | 
				
			||||||
                onInfo = onAlterationInfo,
 | 
					                        .padding(top = if (index == 0) 0.dp else 16.dp)
 | 
				
			||||||
                onClick = onAlterationClick,
 | 
					                        .padding(horizontal = 16.dp),
 | 
				
			||||||
            )
 | 
					                    text = group.name,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            items(items = group.alterations) { alteration ->
 | 
				
			||||||
 | 
					                AlterationItem(
 | 
				
			||||||
 | 
					                    modifier = Modifier.fillMaxWidth(),
 | 
				
			||||||
 | 
					                    alteration = alteration,
 | 
				
			||||||
 | 
					                    onInfo = onAlterationInfo,
 | 
				
			||||||
 | 
					                    onClick = onAlterationClick,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -99,7 +116,7 @@ fun AlterationPagePreview() {
 | 
				
			||||||
    LexiconTheme {
 | 
					    LexiconTheme {
 | 
				
			||||||
        Surface {
 | 
					        Surface {
 | 
				
			||||||
            AlterationPageContent(
 | 
					            AlterationPageContent(
 | 
				
			||||||
                alterations = rememberRollAlterations(),
 | 
					                groups = rememberRollAlterations(),
 | 
				
			||||||
                onAlterationInfo = { },
 | 
					                onAlterationInfo = { },
 | 
				
			||||||
                onAlterationClick = { },
 | 
					                onAlterationClick = { },
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,6 @@ import com.pixelized.rplexicon.R
 | 
				
			||||||
import com.pixelized.rplexicon.data.repository.character.AlterationRepository
 | 
					import com.pixelized.rplexicon.data.repository.character.AlterationRepository
 | 
				
			||||||
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
 | 
					import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
 | 
				
			||||||
import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument
 | 
					import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio
 | 
					 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.rolls.factory.AlterationFactory
 | 
					import com.pixelized.rplexicon.ui.screens.rolls.factory.AlterationFactory
 | 
				
			||||||
import com.pixelized.rplexicon.utilitary.extentions.context
 | 
					import com.pixelized.rplexicon.utilitary.extentions.context
 | 
				
			||||||
import dagger.hilt.android.lifecycle.HiltViewModel
 | 
					import dagger.hilt.android.lifecycle.HiltViewModel
 | 
				
			||||||
| 
						 | 
					@ -29,8 +28,8 @@ class AlterationViewModel @Inject constructor(
 | 
				
			||||||
) : AndroidViewModel(application) {
 | 
					) : AndroidViewModel(application) {
 | 
				
			||||||
    private val character = savedStateHandle.characterSheetArgument.name
 | 
					    private val character = savedStateHandle.characterSheetArgument.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private val _alterations = mutableStateOf<List<AlterationItemUio>>(emptyList())
 | 
					    private val _alterations = mutableStateOf<List<AlterationGroupUio>>(emptyList())
 | 
				
			||||||
    val alterations: State<List<AlterationItemUio>> get() = _alterations
 | 
					    val alterations: State<List<AlterationGroupUio>> get() = _alterations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private val _alterationDetail = mutableStateOf<AlterationDetailUio?>(null)
 | 
					    private val _alterationDetail = mutableStateOf<AlterationDetailUio?>(null)
 | 
				
			||||||
    val alterationDetail: State<AlterationDetailUio?> get() = _alterationDetail
 | 
					    val alterationDetail: State<AlterationDetailUio?> get() = _alterationDetail
 | 
				
			||||||
| 
						 | 
					@ -38,11 +37,19 @@ class AlterationViewModel @Inject constructor(
 | 
				
			||||||
    init {
 | 
					    init {
 | 
				
			||||||
        viewModelScope.launch {
 | 
					        viewModelScope.launch {
 | 
				
			||||||
            launch(Dispatchers.IO) {
 | 
					            launch(Dispatchers.IO) {
 | 
				
			||||||
                alterationRepository.assignedAlterations.collect {
 | 
					                alterationRepository.assignedAlterations.collect { alterationMaps ->
 | 
				
			||||||
                    val alterations = it[character] ?: emptyList()
 | 
					                    val alterations = alterationMaps[character] ?: emptyList()
 | 
				
			||||||
                    val data = factory.convert(character = character, alterations = alterations)
 | 
					                    val data = alterations
 | 
				
			||||||
                        .sortedBy { alteration -> alteration.label }
 | 
					                        .groupBy { alteration -> alteration.source }
 | 
				
			||||||
                        .sortedBy { alteration -> alteration.subLabel }
 | 
					                        .map {
 | 
				
			||||||
 | 
					                            AlterationGroupUio(
 | 
				
			||||||
 | 
					                                name = it.key,
 | 
				
			||||||
 | 
					                                alterations = factory.convert(character = character, alterations = it.value)
 | 
				
			||||||
 | 
					                                    .sortedBy { alteration -> alteration.label }
 | 
				
			||||||
 | 
					                            )
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        .sortedBy { it.name }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    withContext(Dispatchers.Main) {
 | 
					                    withContext(Dispatchers.Main) {
 | 
				
			||||||
                        _alterations.value = data
 | 
					                        _alterations.value = data
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,11 +68,12 @@ import com.pixelized.rplexicon.NO_WINDOW_INSETS
 | 
				
			||||||
import com.pixelized.rplexicon.R
 | 
					import com.pixelized.rplexicon.R
 | 
				
			||||||
import com.pixelized.rplexicon.data.model.DiceThrow
 | 
					import com.pixelized.rplexicon.data.model.DiceThrow
 | 
				
			||||||
import com.pixelized.rplexicon.ui.composable.BlurredOverlayHostState
 | 
					import com.pixelized.rplexicon.ui.composable.BlurredOverlayHostState
 | 
				
			||||||
 | 
					import com.pixelized.rplexicon.ui.composable.CategoryHeader
 | 
				
			||||||
import com.pixelized.rplexicon.ui.composable.ModalNavigationDrawer
 | 
					import com.pixelized.rplexicon.ui.composable.ModalNavigationDrawer
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItem
 | 
					import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItem
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio
 | 
					 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetail
 | 
					import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetail
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetailUio
 | 
					import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetailUio
 | 
				
			||||||
 | 
					import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationGroupUio
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDice
 | 
					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.RollDiceUio
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCard
 | 
					import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCard
 | 
				
			||||||
| 
						 | 
					@ -95,7 +96,7 @@ fun RollOverlay(
 | 
				
			||||||
        drawer = drawer,
 | 
					        drawer = drawer,
 | 
				
			||||||
        dice = viewModel.dice,
 | 
					        dice = viewModel.dice,
 | 
				
			||||||
        card = viewModel.card,
 | 
					        card = viewModel.card,
 | 
				
			||||||
        alterations = viewModel.alterations,
 | 
					        groups = viewModel.alterations,
 | 
				
			||||||
        showDetail = viewModel.showDetail,
 | 
					        showDetail = viewModel.showDetail,
 | 
				
			||||||
        onMenu = {
 | 
					        onMenu = {
 | 
				
			||||||
            scope.launch { drawer.open() }
 | 
					            scope.launch { drawer.open() }
 | 
				
			||||||
| 
						 | 
					@ -138,7 +139,7 @@ private fun RollOverlayContent(
 | 
				
			||||||
    drawer: DrawerState,
 | 
					    drawer: DrawerState,
 | 
				
			||||||
    dice: State<RollDiceUio?>,
 | 
					    dice: State<RollDiceUio?>,
 | 
				
			||||||
    card: State<ThrowsCardUio?>,
 | 
					    card: State<ThrowsCardUio?>,
 | 
				
			||||||
    alterations: State<List<AlterationItemUio>>,
 | 
					    groups: State<List<AlterationGroupUio>>,
 | 
				
			||||||
    showDetail: State<Boolean>,
 | 
					    showDetail: State<Boolean>,
 | 
				
			||||||
    onMenu: () -> Unit,
 | 
					    onMenu: () -> Unit,
 | 
				
			||||||
    onMenuClose: () -> Unit,
 | 
					    onMenuClose: () -> Unit,
 | 
				
			||||||
| 
						 | 
					@ -151,7 +152,7 @@ private fun RollOverlayContent(
 | 
				
			||||||
    val density = LocalDensity.current
 | 
					    val density = LocalDensity.current
 | 
				
			||||||
    val enableDrawer = remember {
 | 
					    val enableDrawer = remember {
 | 
				
			||||||
        derivedStateOf {
 | 
					        derivedStateOf {
 | 
				
			||||||
            alterations.value.isNotEmpty()
 | 
					            groups.value.isNotEmpty()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -189,13 +190,24 @@ private fun RollOverlayContent(
 | 
				
			||||||
                            .fillMaxWidth(4f / 5f),
 | 
					                            .fillMaxWidth(4f / 5f),
 | 
				
			||||||
                        contentPadding = PaddingValues(vertical = 8.dp),
 | 
					                        contentPadding = PaddingValues(vertical = 8.dp),
 | 
				
			||||||
                    ) {
 | 
					                    ) {
 | 
				
			||||||
                        items(items = alterations.value) {
 | 
					                        groups.value.forEachIndexed { index, group ->
 | 
				
			||||||
                            AlterationItem(
 | 
					                            item {
 | 
				
			||||||
                                modifier = Modifier.fillMaxWidth(),
 | 
					                                CategoryHeader(
 | 
				
			||||||
                                alteration = it,
 | 
					                                    modifier = Modifier
 | 
				
			||||||
                                onInfo = onAlterationInfo,
 | 
					                                        .padding(top = if (index == 0) 0.dp else 16.dp)
 | 
				
			||||||
                                onClick = onAlteration,
 | 
					                                        .padding(horizontal = 16.dp),
 | 
				
			||||||
                            )
 | 
					                                    text = group.name,
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            items(items = group.alterations) { alteration ->
 | 
				
			||||||
 | 
					                                AlterationItem(
 | 
				
			||||||
 | 
					                                    modifier = Modifier.fillMaxWidth(),
 | 
				
			||||||
 | 
					                                    alteration = alteration,
 | 
				
			||||||
 | 
					                                    onInfo = onAlterationInfo,
 | 
				
			||||||
 | 
					                                    onClick = onAlteration,
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -319,7 +331,7 @@ private fun RollOverlayPreview(
 | 
				
			||||||
                drawer = rememberDrawerState(initialValue = preview.drawer),
 | 
					                drawer = rememberDrawerState(initialValue = preview.drawer),
 | 
				
			||||||
                dice = preview.dice,
 | 
					                dice = preview.dice,
 | 
				
			||||||
                card = preview.card,
 | 
					                card = preview.card,
 | 
				
			||||||
                alterations = rememberRollAlterations(),
 | 
					                groups = rememberRollAlterations(),
 | 
				
			||||||
                showDetail = remember { mutableStateOf(true) },
 | 
					                showDetail = remember { mutableStateOf(true) },
 | 
				
			||||||
                onMenu = { },
 | 
					                onMenu = { },
 | 
				
			||||||
                onMenuClose = { },
 | 
					                onMenuClose = { },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@ package com.pixelized.rplexicon.ui.screens.rolls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import android.app.Application
 | 
					import android.app.Application
 | 
				
			||||||
import androidx.compose.runtime.State
 | 
					import androidx.compose.runtime.State
 | 
				
			||||||
 | 
					import androidx.compose.runtime.derivedStateOf
 | 
				
			||||||
import androidx.compose.runtime.mutableStateOf
 | 
					import androidx.compose.runtime.mutableStateOf
 | 
				
			||||||
import androidx.lifecycle.AndroidViewModel
 | 
					import androidx.lifecycle.AndroidViewModel
 | 
				
			||||||
import androidx.lifecycle.viewModelScope
 | 
					import androidx.lifecycle.viewModelScope
 | 
				
			||||||
| 
						 | 
					@ -12,6 +13,7 @@ import com.pixelized.rplexicon.data.repository.character.AlterationRepository
 | 
				
			||||||
import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
 | 
					import com.pixelized.rplexicon.data.repository.character.DescriptionRepository
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio
 | 
					import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetailUio
 | 
					import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationDetailUio
 | 
				
			||||||
 | 
					import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationGroupUio
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDiceUio
 | 
					import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDiceUio
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio
 | 
					import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.rolls.factory.AlterationFactory
 | 
					import com.pixelized.rplexicon.ui.screens.rolls.factory.AlterationFactory
 | 
				
			||||||
| 
						 | 
					@ -37,7 +39,17 @@ class RollOverlayViewModel @Inject constructor(
 | 
				
			||||||
    private var rollJob: Job? = null
 | 
					    private var rollJob: Job? = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private val _alterations = mutableStateOf<List<AlterationItemUio>>(emptyList())
 | 
					    private val _alterations = mutableStateOf<List<AlterationItemUio>>(emptyList())
 | 
				
			||||||
    val alterations: State<List<AlterationItemUio>> get() = _alterations
 | 
					    val alterations: State<List<AlterationGroupUio>> = derivedStateOf {
 | 
				
			||||||
 | 
					        _alterations.value
 | 
				
			||||||
 | 
					            .groupBy { it.source }
 | 
				
			||||||
 | 
					            .map { entry ->
 | 
				
			||||||
 | 
					                AlterationGroupUio(
 | 
				
			||||||
 | 
					                    name = entry.key,
 | 
				
			||||||
 | 
					                    alterations = entry.value.sortedBy { it.label }
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            .sortedBy { it.name }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private val _dice = mutableStateOf<RollDiceUio?>(null)
 | 
					    private val _dice = mutableStateOf<RollDiceUio?>(null)
 | 
				
			||||||
    val dice: State<RollDiceUio?> get() = _dice
 | 
					    val dice: State<RollDiceUio?> get() = _dice
 | 
				
			||||||
| 
						 | 
					@ -56,8 +68,6 @@ class RollOverlayViewModel @Inject constructor(
 | 
				
			||||||
        _card.value = null
 | 
					        _card.value = null
 | 
				
			||||||
        _dice.value = diceFactory.convertDiceThrow(diceThrow)
 | 
					        _dice.value = diceFactory.convertDiceThrow(diceThrow)
 | 
				
			||||||
        _alterations.value = alterationFactory.convertDiceThrow(diceThrow)
 | 
					        _alterations.value = alterationFactory.convertDiceThrow(diceThrow)
 | 
				
			||||||
            .sortedBy { it.label }
 | 
					 | 
				
			||||||
            .sortedBy { it.subLabel }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun onAlteration(id: String) {
 | 
					    fun onAlteration(id: String) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,9 +23,9 @@ class AlterationFactory @Inject constructor(
 | 
				
			||||||
            val description = descriptionRepository.find(it.name)
 | 
					            val description = descriptionRepository.find(it.name)
 | 
				
			||||||
            AlterationItemUio(
 | 
					            AlterationItemUio(
 | 
				
			||||||
                label = it.name,
 | 
					                label = it.name,
 | 
				
			||||||
                original = description?.original,
 | 
					                source = it.source,
 | 
				
			||||||
                checked = alterationRepository.getStatus(character, it.name),
 | 
					                checked = alterationRepository.getStatus(character, it.name),
 | 
				
			||||||
                subLabel = it.source,
 | 
					                subLabel = description?.original,
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -65,44 +65,66 @@ class AlterationFactory @Inject constructor(
 | 
				
			||||||
            is DiceThrow.Stealth -> listOf(Property.STEALTH, Property.DEXTERITY)
 | 
					            is DiceThrow.Stealth -> listOf(Property.STEALTH, Property.DEXTERITY)
 | 
				
			||||||
            is DiceThrow.Survival -> listOf(Property.SURVIVAL, Property.WISDOM)
 | 
					            is DiceThrow.Survival -> listOf(Property.SURVIVAL, Property.WISDOM)
 | 
				
			||||||
            is DiceThrow.PhysicalMeleeAttack -> {
 | 
					            is DiceThrow.PhysicalMeleeAttack -> {
 | 
				
			||||||
                val action = actionRepository.find(diceThrow.character, action = diceThrow.weapon)
 | 
					                val action = actionRepository.find(
 | 
				
			||||||
 | 
					                    character = diceThrow.character,
 | 
				
			||||||
 | 
					                    action = diceThrow.weapon
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
                listOf(Property.PHYSICAL_MELEE_ATTACK) + (action?.hit?.modifier ?: emptyList())
 | 
					                listOf(Property.PHYSICAL_MELEE_ATTACK) + (action?.hit?.modifier ?: emptyList())
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            is DiceThrow.PhysicalMeleeDamage -> {
 | 
					            is DiceThrow.PhysicalMeleeDamage -> {
 | 
				
			||||||
                val action = actionRepository.find(diceThrow.character, action = diceThrow.weapon)
 | 
					                val action = actionRepository.find(
 | 
				
			||||||
 | 
					                    character = diceThrow.character,
 | 
				
			||||||
 | 
					                    action = diceThrow.weapon
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
                listOf(Property.PHYSICAL_MELEE_DAMAGE) + (action?.damage?.modifier ?: emptyList())
 | 
					                listOf(Property.PHYSICAL_MELEE_DAMAGE) + (action?.damage?.modifier ?: emptyList())
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            is DiceThrow.PhysicalRangeAttack -> {
 | 
					            is DiceThrow.PhysicalRangeAttack -> {
 | 
				
			||||||
                val action = actionRepository.find(diceThrow.character, action = diceThrow.weapon)
 | 
					                val action = actionRepository.find(
 | 
				
			||||||
 | 
					                    character = diceThrow.character,
 | 
				
			||||||
 | 
					                    action = diceThrow.weapon
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
                listOf(Property.PHYSICAL_RANGE_ATTACK) + (action?.hit?.modifier ?: emptyList())
 | 
					                listOf(Property.PHYSICAL_RANGE_ATTACK) + (action?.hit?.modifier ?: emptyList())
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            is DiceThrow.Object -> emptyList()
 | 
					            is DiceThrow.Object -> emptyList()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            is DiceThrow.PhysicalRangeDamage -> {
 | 
					            is DiceThrow.PhysicalRangeDamage -> {
 | 
				
			||||||
                val action = actionRepository.find(diceThrow.character, action = diceThrow.weapon)
 | 
					                val action = actionRepository.find(
 | 
				
			||||||
 | 
					                    character = diceThrow.character,
 | 
				
			||||||
 | 
					                    action = diceThrow.weapon
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
                listOf(Property.PHYSICAL_RANGE_DAMAGE) + (action?.damage?.modifier ?: emptyList())
 | 
					                listOf(Property.PHYSICAL_RANGE_DAMAGE) + (action?.damage?.modifier ?: emptyList())
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            is DiceThrow.SpellAttack -> {
 | 
					            is DiceThrow.SpellAttack -> {
 | 
				
			||||||
                val spell = spellRepository.findAssignedSpell(diceThrow.character, spell = diceThrow.spell)
 | 
					                val spell = spellRepository.findAssignedSpell(
 | 
				
			||||||
 | 
					                    character = diceThrow.character,
 | 
				
			||||||
 | 
					                    spell = diceThrow.spell
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
                listOf(Property.SPELL_ATTACK) + (spell?.hit?.modifier ?: emptyList())
 | 
					                listOf(Property.SPELL_ATTACK) + (spell?.hit?.modifier ?: emptyList())
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            is DiceThrow.SpellDamage -> {
 | 
					            is DiceThrow.SpellDamage -> {
 | 
				
			||||||
                val spell = spellRepository.findAssignedSpell(diceThrow.character, spell = diceThrow.spell)
 | 
					                val spell = spellRepository.findAssignedSpell(
 | 
				
			||||||
 | 
					                    character = diceThrow.character,
 | 
				
			||||||
 | 
					                    spell = diceThrow.spell
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
                listOf(Property.SPELL_DAMAGE) + (spell?.effect?.modifier ?: emptyList())
 | 
					                listOf(Property.SPELL_DAMAGE) + (spell?.effect?.modifier ?: emptyList())
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            is DiceThrow.SpellEffect -> {
 | 
					            is DiceThrow.SpellEffect -> {
 | 
				
			||||||
                val spell = spellRepository.findAssignedSpell(diceThrow.character, spell = diceThrow.spell)
 | 
					                val spell = spellRepository.findAssignedSpell(
 | 
				
			||||||
 | 
					                    character = diceThrow.character,
 | 
				
			||||||
 | 
					                    spell = diceThrow.spell
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
                spell?.effect?.modifier ?: emptyList()
 | 
					                spell?.effect?.modifier ?: emptyList()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            is DiceThrow.Skill -> {
 | 
					            is DiceThrow.Skill -> {
 | 
				
			||||||
                val skill = skillRepository.find(diceThrow.character, skill = diceThrow.skill)
 | 
					                val skill =
 | 
				
			||||||
 | 
					                    skillRepository.find(character = diceThrow.character, skill = diceThrow.skill)
 | 
				
			||||||
                listOf(Property.SKILL) + (skill?.effect?.modifier ?: emptyList())
 | 
					                listOf(Property.SKILL) + (skill?.effect?.modifier ?: emptyList())
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -113,9 +135,9 @@ class AlterationFactory @Inject constructor(
 | 
				
			||||||
                val description = descriptionRepository.find(it.name)
 | 
					                val description = descriptionRepository.find(it.name)
 | 
				
			||||||
                AlterationItemUio(
 | 
					                AlterationItemUio(
 | 
				
			||||||
                    label = it.name,
 | 
					                    label = it.name,
 | 
				
			||||||
                    original = description?.original,
 | 
					                    source = it.source,
 | 
				
			||||||
                    checked = alterationRepository.getStatus(diceThrow.character, it.name),
 | 
					                    checked = alterationRepository.getStatus(diceThrow.character, it.name),
 | 
				
			||||||
                    subLabel = it.source,
 | 
					                    subLabel = description?.original,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,35 +5,51 @@ import androidx.compose.runtime.Stable
 | 
				
			||||||
import androidx.compose.runtime.mutableStateOf
 | 
					import androidx.compose.runtime.mutableStateOf
 | 
				
			||||||
import androidx.compose.runtime.remember
 | 
					import androidx.compose.runtime.remember
 | 
				
			||||||
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio
 | 
					import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio
 | 
				
			||||||
 | 
					import com.pixelized.rplexicon.ui.screens.character.pages.alteration.AlterationGroupUio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Composable
 | 
					@Composable
 | 
				
			||||||
@Stable
 | 
					@Stable
 | 
				
			||||||
fun rememberRollAlterations() = remember {
 | 
					fun rememberRollAlterations() = remember {
 | 
				
			||||||
    mutableStateOf(
 | 
					    mutableStateOf(
 | 
				
			||||||
        listOf(
 | 
					        listOf(
 | 
				
			||||||
            AlterationItemUio(
 | 
					            AlterationGroupUio(
 | 
				
			||||||
                label = "Rage",
 | 
					                name = "Barbarian",
 | 
				
			||||||
                original = "Rage",
 | 
					                alterations = listOf(
 | 
				
			||||||
                subLabel = "Barbare",
 | 
					                    AlterationItemUio(
 | 
				
			||||||
                checked = false,
 | 
					                        label = "Rage",
 | 
				
			||||||
 | 
					                        subLabel = "Rage",
 | 
				
			||||||
 | 
					                        source = "Barbare",
 | 
				
			||||||
 | 
					                        checked = false,
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            AlterationItemUio(
 | 
					            AlterationGroupUio(
 | 
				
			||||||
                label = "Inspiration bardique",
 | 
					                name = "Barbarian",
 | 
				
			||||||
                original = "Bardic inspiration",
 | 
					                alterations = listOf(
 | 
				
			||||||
                subLabel = "Barde",
 | 
					                    AlterationItemUio(
 | 
				
			||||||
                checked = false
 | 
					                        label = "Inspiration bardique",
 | 
				
			||||||
 | 
					                        subLabel = "Bardic inspiration",
 | 
				
			||||||
 | 
					                        source = "Barde",
 | 
				
			||||||
 | 
					                        checked = false
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    AlterationItemUio(
 | 
				
			||||||
 | 
					                        label = "Bénédiction",
 | 
				
			||||||
 | 
					                        subLabel = "Bless",
 | 
				
			||||||
 | 
					                        source = "Barde",
 | 
				
			||||||
 | 
					                        checked = false,
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            AlterationItemUio(
 | 
					            AlterationGroupUio(
 | 
				
			||||||
                label = "Bénédiction",
 | 
					                name = "Barbarian",
 | 
				
			||||||
                original = "Bless",
 | 
					                alterations = listOf(
 | 
				
			||||||
                subLabel = "Clerc",
 | 
					                    AlterationItemUio(
 | 
				
			||||||
                checked = false,
 | 
					                        label = "Cape de protection",
 | 
				
			||||||
            ),
 | 
					                        subLabel = "Cape of protection",
 | 
				
			||||||
            AlterationItemUio(
 | 
					                        source = "Equipement",
 | 
				
			||||||
                label = "Cape de protection",
 | 
					                        checked = true
 | 
				
			||||||
                original = "Cape of protection",
 | 
					                    ),
 | 
				
			||||||
                subLabel = "Équipement",
 | 
					                ),
 | 
				
			||||||
                checked = true
 | 
					 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue