diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/composable/form/DropDownField.kt b/app/src/main/java/com/pixelized/rplexicon/ui/composable/form/DropDownField.kt index 868b47f..d7e8dba 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/composable/form/DropDownField.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/composable/form/DropDownField.kt @@ -39,22 +39,30 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import com.pixelized.rplexicon.R +import com.pixelized.rplexicon.model.Lexicon import com.pixelized.rplexicon.ui.theme.LexiconTheme +import com.pixelized.rplexicon.utilitary.composable.stringResource import com.pixelized.rplexicon.utilitary.extentions.lexicon @Stable data class DropDownFieldUio( @StringRes val label: Int, - val values: List>, - val value: State>, - val onValueChange: (T?, String) -> Unit, + val values: List, + val value: State, + val valueLabel: @Composable (T) -> String, + val onValueChange: (T?) -> Unit, ) { companion object { - fun preview(@StringRes label: Int, id: T?, value: String) = DropDownFieldUio( + fun preview( + @StringRes label: Int, + id: T?, + valueLabel: @Composable (T) -> String, + ) = DropDownFieldUio( label = label, values = emptyList(), - value = mutableStateOf(id to value), - onValueChange = { _, _ -> }, + value = mutableStateOf(id), + valueLabel = valueLabel, + onValueChange = { }, ) } } @@ -70,7 +78,7 @@ fun DropDownField( ExposedDropdownMenuBox( modifier = modifier, expanded = expended, - onExpandedChange = { expended = !expended && field.value.value.first == null }, + onExpandedChange = { expended = !expended && field.value.value == null }, ) { OutlinedTextField( modifier = Modifier.menuAnchor(), @@ -85,13 +93,13 @@ fun DropDownField( trailingIcon = { AnimatedContent( modifier = Modifier.size(size = 48.dp), - targetState = field.value.value.first != null, + targetState = field.value.value != null, transitionSpec = { fadeIn() with fadeOut() }, label = "DropDownFieldTrailingIconAnimation", ) { when (it) { true -> IconButton( - onClick = { field.onValueChange(null, "") }, + onClick = { field.onValueChange(null) }, ) { Icon( modifier = Modifier.size(size = 18.dp), @@ -116,7 +124,7 @@ fun DropDownField( focusedContainerColor = MaterialTheme.colorScheme.surface, unfocusedContainerColor = MaterialTheme.colorScheme.surface, ), - value = field.value.value.second, + value = field.value.value?.let { field.valueLabel(it) } ?: "", onValueChange = {}, ) @@ -125,14 +133,13 @@ fun DropDownField( onDismissRequest = { expended = false }, ) { field.values.forEach { - val label = stringResource(id = it.second) DropdownMenuItem( onClick = { expended = false - field.onValueChange(it.first, label) + field.onValueChange(it) }, text = { - Text(text = label) + Text(text = field.valueLabel(it)) }, ) } @@ -144,7 +151,7 @@ fun DropDownField( @Preview(uiMode = UI_MODE_NIGHT_NO) @Preview(uiMode = UI_MODE_NIGHT_YES) private fun DropDownFieldPreview( - @PreviewParameter(DropDownFieldPreviewProvider::class) preview: Pair, + @PreviewParameter(DropDownFieldPreviewProvider::class) preview: Lexicon.Race?, ) { LexiconTheme { Surface { @@ -153,16 +160,17 @@ private fun DropDownFieldPreview( .fillMaxWidth() .padding(all = 8.dp), field = DropDownFieldUio( - label = R.string.lexicon_search, + label = R.string.search_field_race, values = emptyList(), value = remember { mutableStateOf(preview) }, - onValueChange = { _, _ -> }, + valueLabel = { stringResource(id = it) }, + onValueChange = { }, ) ) } } } -private class DropDownFieldPreviewProvider : PreviewParameterProvider> { - override val values: Sequence> = sequenceOf(null to "", "" to "preview") +private class DropDownFieldPreviewProvider : PreviewParameterProvider { + override val values: Sequence = sequenceOf(null, Lexicon.Race.HALF_ORC) } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationScreen.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationScreen.kt index 8c58235..494223f 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationScreen.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationScreen.kt @@ -30,6 +30,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.State import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush @@ -145,7 +146,7 @@ private fun PartyBackground( Gyroscope { val balance = remember { derivedStateOf { - max(-1f, min(1f, this.gyroscope.value.roll)) + max(-1f, min(1f, this.gyroscope.value.roll * 2.5f)) } } val colorFilter = remember { @@ -263,13 +264,13 @@ private fun PartyBackground( } @Composable -private fun rememberPortrait(): List = remember { +private fun rememberPortrait(): List = rememberSaveable { listOf( R.drawable.im_tigrane, R.drawable.im_unathana, R.drawable.im_brulkhai, - R.drawable.im_nelia, R.drawable.im_leandre, + R.drawable.im_nelia, ) } @@ -279,14 +280,14 @@ private fun animatedWeight( amplitude: Float = E.toFloat(), divergence: Float = 0.95f, position: Float, - step: Float = .16f, + step: Float = .10f, ): Float { val animatedWeight = animateFloatAsState( targetValue = divergence * amplitude.pow(-(position - progress.value).pow(2f) / step) + (1f - divergence), label = "AnimatedBackgroundWeight", animationSpec = spring( dampingRatio = Spring.DampingRatioNoBouncy, - stiffness = Spring.StiffnessLow, + stiffness = (Spring.StiffnessLow + Spring.StiffnessVeryLow) / 2f, ) ) return animatedWeight.value @@ -378,6 +379,8 @@ private fun rememeberGoogleStringResource(): AnnotatedString { private fun AuthenticationScreenContentPreview() { LexiconTheme { Surface { + PartyBackground() + AuthenticationScreenContent( modifier = Modifier .fillMaxSize() diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/search/SearchScreen.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/search/SearchScreen.kt index c112dd9..39d4057 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/search/SearchScreen.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/search/SearchScreen.kt @@ -2,7 +2,6 @@ package com.pixelized.rplexicon.ui.screens.search import android.content.res.Configuration.UI_MODE_NIGHT_NO import android.content.res.Configuration.UI_MODE_NIGHT_YES -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -34,7 +33,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -51,6 +49,7 @@ import com.pixelized.rplexicon.ui.composable.form.TextFieldUio import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost import com.pixelized.rplexicon.ui.navigation.screens.navigateToCharacterDetail import com.pixelized.rplexicon.ui.theme.LexiconTheme +import com.pixelized.rplexicon.utilitary.composable.stringResource import com.pixelized.rplexicon.utilitary.extentions.lexicon @Stable @@ -81,8 +80,8 @@ fun SearchScreen( screen.navigateToCharacterDetail( id = item.id, highlight = form.search.value.value.takeIf { it.isNotEmpty() }, - race = form.race.value.value.first, - gender = form.gender.value.value.first, + race = form.race.value.value, + gender = form.gender.value.value, ) }, onBack = { @@ -95,7 +94,7 @@ fun SearchScreen( } } -@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable private fun SearchScreenContent( modifier: Modifier = Modifier, @@ -178,21 +177,20 @@ private fun SearchScreenContent( @Preview(uiMode = UI_MODE_NIGHT_YES) private fun SearchScreenContentPreview() { LexiconTheme { - val context = LocalContext.current Surface { SearchScreenContent( modifier = Modifier.fillMaxSize(), form = SearchFormUio( search = TextFieldUio.preview(R.string.search_field_search), gender = DropDownFieldUio.preview( - label = R.string.search_field_gender, id = Lexicon.Gender.FEMALE, - value = context.getString(R.string.gender_female), + label = R.string.search_field_gender, + valueLabel = { stringResource(id = Lexicon.Gender.FEMALE) }, ), race = DropDownFieldUio.preview( - label = R.string.search_field_race, id = null, - value = "", + label = R.string.search_field_race, + valueLabel = { stringResource(id = Lexicon.Race.HALF_ORC) }, ), ), items = remember { diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/search/SearchViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/search/SearchViewModel.kt index 0b4be7c..d341e90 100644 --- a/app/src/main/java/com/pixelized/rplexicon/ui/screens/search/SearchViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/search/SearchViewModel.kt @@ -10,6 +10,7 @@ import com.pixelized.rplexicon.model.Lexicon.Race import com.pixelized.rplexicon.repository.LexiconRepository import com.pixelized.rplexicon.ui.composable.form.DropDownFieldUio import com.pixelized.rplexicon.ui.composable.form.TextFieldUio +import com.pixelized.rplexicon.utilitary.composable.stringResource import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -18,8 +19,8 @@ class SearchViewModel @Inject constructor( repository: LexiconRepository, ) : ViewModel() { private val _search = mutableStateOf("") - private val _gender = mutableStateOf>(null to "") - private val _race = mutableStateOf>(null to "") + private val _gender = mutableStateOf(null) + private val _race = mutableStateOf(null) val form = SearchFormUio( search = TextFieldUio( @@ -31,15 +32,17 @@ class SearchViewModel @Inject constructor( ), gender = DropDownFieldUio( label = R.string.search_field_gender, - values = genders(), + values = Lexicon.Gender.values().toList(), value = _gender, - onValueChange = { id, value -> _gender.value = id to value }, + valueLabel = { stringResource(id = it) }, + onValueChange = { id -> _gender.value = id }, ), race = DropDownFieldUio( label = R.string.search_field_race, - values = races(), + values = Lexicon.Race.values().toList(), value = _race, - onValueChange = { id, value -> _race.value = id to value }, + valueLabel = { stringResource(id = it) }, + onValueChange = { id -> _race.value = id }, ), ) @@ -47,8 +50,8 @@ class SearchViewModel @Inject constructor( val filter = derivedStateOf { data.filter { item -> - val gender = _gender.value.first?.let { it == item.gender } - val race = _race.value.first?.let { it == item.race } + val gender = _gender.value?.let { it == item.gender } + val race = _race.value?.let { it == item.race } val search = _search.value.takeIf { it.isNotEmpty() }?.let { val name = item.name.contains(_search.value, true) val diminutive = item.diminutive?.contains(_search.value, true) == true @@ -66,8 +69,8 @@ class SearchViewModel @Inject constructor( private fun Lexicon.toSearchUio( search: String = _search.value, - highlightGender: Boolean = this.gender == _gender.value.first, - highlightRace: Boolean = this.race == _race.value.first, + highlightGender: Boolean = this.gender == _gender.value, + highlightRace: Boolean = this.race == _race.value, ) = SearchItemUio( id = this.id, name = this.name, @@ -80,29 +83,4 @@ class SearchViewModel @Inject constructor( highlightGender = highlightGender, highlightRace = highlightRace, ) - - companion object { - private fun genders() = listOf( - Gender.MALE to R.string.gender_male, - Gender.FEMALE to R.string.gender_female, - Gender.UNDETERMINED to R.string.gender_undetermined, - ) - - private fun races() = listOf( - Race.ELF to R.string.race_elf, - Race.HALFLING to R.string.race_halfling, - Race.HUMAN to R.string.race_human, - Race.DWARF to R.string.race_dwarf, - Race.HALF_ELF to R.string.race_half_elf, - Race.HALF_ORC to R.string.race_half_orc, - Race.DRAGONBORN to R.string.race_dragonborn, - Race.GNOME to R.string.race_gnome, - Race.TIEFLING to R.string.race_tiefling, - Race.AARAKOCRA to R.string.race_aarakocra, - Race.GENASI to R.string.race_genasi, - Race.DEEP_GNOME to R.string.race_deep_gnome, - Race.GOLIATH to R.string.race_goliath, - Race.UNDETERMINED to R.string.race_undetermined, - ) - } } \ No newline at end of file diff --git a/app/src/main/res/drawable/im_brulkhai.jpeg b/app/src/main/res/drawable/im_brulkhai.jpeg new file mode 100644 index 0000000..535ac5a Binary files /dev/null and b/app/src/main/res/drawable/im_brulkhai.jpeg differ diff --git a/app/src/main/res/drawable/im_brulkhai.webp b/app/src/main/res/drawable/im_brulkhai.webp deleted file mode 100644 index 6e61c16..0000000 Binary files a/app/src/main/res/drawable/im_brulkhai.webp and /dev/null differ diff --git a/app/src/main/res/drawable/im_leandre.webp b/app/src/main/res/drawable/im_leandre.webp index d93c5d3..43a5dc1 100644 Binary files a/app/src/main/res/drawable/im_leandre.webp and b/app/src/main/res/drawable/im_leandre.webp differ diff --git a/app/src/main/res/drawable/im_nelia.webp b/app/src/main/res/drawable/im_nelia.webp index 5cd6144..694b8b7 100644 Binary files a/app/src/main/res/drawable/im_nelia.webp and b/app/src/main/res/drawable/im_nelia.webp differ diff --git a/app/src/main/res/drawable/im_unathana.webp b/app/src/main/res/drawable/im_unathana.webp index de61af7..4d3d8f3 100644 Binary files a/app/src/main/res/drawable/im_unathana.webp and b/app/src/main/res/drawable/im_unathana.webp differ