diff --git a/app/src/main/java/com/sadellie/unitto/screens/setttings/components/SettingsListItem.kt b/app/src/main/java/com/sadellie/unitto/screens/common/UnittoListItem.kt similarity index 64% rename from app/src/main/java/com/sadellie/unitto/screens/setttings/components/SettingsListItem.kt rename to app/src/main/java/com/sadellie/unitto/screens/common/UnittoListItem.kt index aaeba835..17966702 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/setttings/components/SettingsListItem.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/common/UnittoListItem.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.sadellie.unitto.screens.setttings.components +package com.sadellie.unitto.screens.common import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.animateFloatAsState @@ -25,6 +25,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxWidth @@ -67,7 +68,7 @@ import com.sadellie.unitto.R * @param leadingItem Additional composable: buttons, switches, checkboxes or something else. */ @Composable -private fun BasicSettingsListItem( +private fun BasicUnittoListItem( modifier: Modifier = Modifier, label: String, supportText: String? = null, @@ -76,8 +77,7 @@ private fun BasicSettingsListItem( ) { Row( modifier = modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 12.dp), + .fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(16.dp) ) { @@ -88,7 +88,9 @@ private fun BasicSettingsListItem( Text( modifier = Modifier .fillMaxWidth(), - text = label + text = label, + maxLines = 1, + overflow = TextOverflow.Ellipsis ) supportText?.let { Text( @@ -115,17 +117,19 @@ private fun BasicSettingsListItem( * @param onClick Action to perform when user clicks on this component (whole component is clickable). */ @Composable -fun SettingsListItem( +fun UnittoListItem( modifier: Modifier = Modifier, label: String, supportText: String? = null, onClick: () -> Unit, -) = BasicSettingsListItem( - modifier = modifier.clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(), - onClick = onClick - ), +) = BasicUnittoListItem( + modifier = modifier + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(), + onClick = onClick + ) + .padding(horizontal = 16.dp, vertical = 12.dp), label = label, supportText = supportText ) @@ -140,17 +144,19 @@ fun SettingsListItem( * you new value. */ @Composable -fun SettingsListItem( +fun UnittoListItem( label: String, supportText: String? = null, switchState: Boolean, onSwitchChange: (Boolean) -> Unit -) = BasicSettingsListItem( - modifier = Modifier.clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(), - onClick = { onSwitchChange(!switchState) } - ), +) = BasicUnittoListItem( + modifier = Modifier + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(), + onClick = { onSwitchChange(!switchState) } + ) + .padding(horizontal = 16.dp, vertical = 12.dp), label = label, supportText = supportText ) { @@ -168,59 +174,65 @@ fun SettingsListItem( * @param onSelectedChange Action to perform when drop-down menu item is selected. */ @Composable -fun SettingsListItem( +fun UnittoListItem( label: String, supportText: String? = null, allOptions: Map, selected: T, onSelectedChange: (T) -> Unit -) = BasicSettingsListItem(Modifier, label, supportText) { - var dropDownExpanded by rememberSaveable { mutableStateOf(false) } - var currentOption by rememberSaveable { mutableStateOf(selected) } - val dropDownRotation: Float by animateFloatAsState( - targetValue = if (dropDownExpanded) 180f else 0f, - animationSpec = tween(easing = FastOutSlowInEasing) - ) - - ExposedDropdownMenuBox( - modifier = Modifier, - expanded = dropDownExpanded, - onExpandedChange = { dropDownExpanded = it } +) { + BasicUnittoListItem( + modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), + label = label, + supportText = supportText ) { - OutlinedTextField( - modifier = Modifier.widthIn(1.dp), - value = allOptions[currentOption] ?: selected.toString(), - onValueChange = {}, - readOnly = true, - singleLine = true, - enabled = false, - colors = TextFieldDefaults.outlinedTextFieldColors( - disabledBorderColor = MaterialTheme.colorScheme.outline, - disabledTextColor = MaterialTheme.colorScheme.onSurface, - disabledTrailingIconColor = MaterialTheme.colorScheme.onSurfaceVariant - ), - trailingIcon = { - Icon( - imageVector = Icons.Outlined.ArrowDropDown, - modifier = Modifier.rotate(dropDownRotation), - contentDescription = stringResource(R.string.drop_down_description) - ) - } + var dropDownExpanded by rememberSaveable { mutableStateOf(false) } + var currentOption by rememberSaveable { mutableStateOf(selected) } + val dropDownRotation: Float by animateFloatAsState( + targetValue = if (dropDownExpanded) 180f else 0f, + animationSpec = tween(easing = FastOutSlowInEasing) ) - ExposedDropdownMenu( - modifier = Modifier.exposedDropdownSize(), + + ExposedDropdownMenuBox( + modifier = Modifier, expanded = dropDownExpanded, - onDismissRequest = { dropDownExpanded = false } + onExpandedChange = { dropDownExpanded = it } ) { - allOptions.forEach { - DropdownMenuItem( - text = { Text(it.value) }, - onClick = { - currentOption = it.key - onSelectedChange(it.key) - dropDownExpanded = false - } - ) + OutlinedTextField( + modifier = Modifier.widthIn(1.dp), + value = allOptions[currentOption] ?: selected.toString(), + onValueChange = {}, + readOnly = true, + singleLine = true, + enabled = false, + colors = TextFieldDefaults.outlinedTextFieldColors( + disabledBorderColor = MaterialTheme.colorScheme.outline, + disabledTextColor = MaterialTheme.colorScheme.onSurface, + disabledTrailingIconColor = MaterialTheme.colorScheme.onSurfaceVariant + ), + trailingIcon = { + Icon( + imageVector = Icons.Outlined.ArrowDropDown, + modifier = Modifier.rotate(dropDownRotation), + contentDescription = stringResource(R.string.drop_down_description) + ) + } + ) + ExposedDropdownMenu( + modifier = Modifier.exposedDropdownSize(), + expanded = dropDownExpanded, + onDismissRequest = { dropDownExpanded = false } + ) { + allOptions.forEach { + DropdownMenuItem( + text = { Text(it.value) }, + onClick = { + currentOption = it.key + onSelectedChange(it.key) + dropDownExpanded = false + } + ) + } } } } @@ -235,11 +247,21 @@ fun SettingsListItem( * @param leadingItem Additional composable: buttons, switches, checkboxes or something else. */ @Composable -fun SettingsListItem( +fun UnittoListItem( label: String, + supportText: String? = null, modifier: Modifier = Modifier, + paddingValues: PaddingValues = PaddingValues(horizontal = 16.dp, vertical = 12.dp), leadingItem: @Composable RowScope.() -> Unit = {}, trailingItem: @Composable RowScope.() -> Unit = {} ) { - BasicSettingsListItem(modifier = modifier, label = label, trailingItem = trailingItem, leadingItem = leadingItem) + BasicUnittoListItem( + modifier = modifier.padding(paddingValues), + label = label, + supportText = supportText, + trailingItem = trailingItem, + leadingItem = leadingItem + ) } + + diff --git a/app/src/main/java/com/sadellie/unitto/screens/second/components/UnitListItem.kt b/app/src/main/java/com/sadellie/unitto/screens/second/components/UnitListItem.kt index c4845dad..f66eb6ec 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/second/components/UnitListItem.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/second/components/UnitListItem.kt @@ -26,11 +26,8 @@ import androidx.compose.animation.with import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons @@ -38,23 +35,20 @@ import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.FavoriteBorder import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.sadellie.unitto.R import com.sadellie.unitto.data.units.AbstractUnit +import com.sadellie.unitto.screens.common.UnittoListItem /** * Represents one list item. Once clicked will navigate up. @@ -78,41 +72,28 @@ private fun BasicUnitListItem( modifier = Modifier .clickable( interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(), // You can also change the color and radius of the ripple + indication = rememberRipple(), onClick = { selectAction(unit) } ) .padding(horizontal = 12.dp) ) { - Row( + UnittoListItem( modifier = Modifier - .fillMaxWidth() .background( if (isSelected) MaterialTheme.colorScheme.secondaryContainer else Color.Transparent, RoundedCornerShape(24.dp) ), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - Column( - Modifier - .padding(horizontal = 16.dp) - .weight(1f) - ) { - Text( - text = stringResource(id = unit.displayName), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = shortNameLabel, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - IconButton(onClick = { favoriteAction(unit); isFavorite = !isFavorite }) { + paddingValues = PaddingValues(horizontal = 12.dp, vertical = 8.dp), + label = stringResource(id = unit.displayName), + supportText = shortNameLabel, + trailingItem = { AnimatedContent( + modifier = Modifier + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(false), + onClick = { favoriteAction(unit); isFavorite = !isFavorite } + ), targetState = isFavorite, transitionSpec = { (scaleIn() with scaleOut()).using(SizeTransform(clip = false)) @@ -124,7 +105,7 @@ private fun BasicUnitListItem( ) } } - } + ) } } diff --git a/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt b/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt index 1ca7e3df..b70a18fa 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt @@ -36,9 +36,9 @@ import com.sadellie.unitto.data.preferences.PRECISIONS import com.sadellie.unitto.data.preferences.SEPARATORS import com.sadellie.unitto.screens.common.Header import com.sadellie.unitto.screens.common.UnittoLargeTopAppBar +import com.sadellie.unitto.screens.common.UnittoListItem import com.sadellie.unitto.screens.openLink import com.sadellie.unitto.screens.setttings.components.AlertDialogWithList -import com.sadellie.unitto.screens.setttings.components.SettingsListItem @Composable fun SettingsScreen( @@ -62,47 +62,51 @@ fun SettingsScreen( // THEME item { - SettingsListItem( + UnittoListItem( label = stringResource(id = R.string.unit_groups_setting), - onClick = { navControllerAction(UNIT_GROUPS_SCREEN) } + onClick = { navControllerAction(UNIT_GROUPS_SCREEN) } ) } // PRECISION item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.precision_setting), - supportText = stringResource(R.string.precision_setting_support) - ) { dialogState = DialogState.PRECISION } + supportText = stringResource(R.string.precision_setting_support), + onClick = { dialogState = DialogState.PRECISION } + ) } // SEPARATOR item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.separator_setting), - supportText = stringResource(R.string.separator_setting_support) - ) { dialogState = DialogState.SEPARATOR } + supportText = stringResource(R.string.separator_setting_support), + onClick = { dialogState = DialogState.SEPARATOR } + ) } // OUTPUT FORMAT item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.output_format_setting), - supportText = stringResource(R.string.output_format_setting_support) - ) { dialogState = DialogState.OUTPUT_FORMAT } + supportText = stringResource(R.string.output_format_setting_support), + onClick = { dialogState = DialogState.OUTPUT_FORMAT } + ) } // THEME item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.theme_setting), - supportText = stringResource(R.string.theme_setting_support) - ) { navControllerAction(THEMES_SCREEN) } + supportText = stringResource(R.string.theme_setting_support), + onClick = { navControllerAction(THEMES_SCREEN) } + ) } // CURRENCY RATE NOTE item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.currency_rates_note_setting), onClick = { dialogState = DialogState.CURRENCY_RATE } ) @@ -113,24 +117,34 @@ fun SettingsScreen( // TERMS AND CONDITIONS item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.terms_and_conditions), - onClick = { openLink(mContext, "http://sadellie.github.io/unitto/terms-app.html") } + onClick = { + openLink( + mContext, + "http://sadellie.github.io/unitto/terms-app.html" + ) + } ) } // PRIVACY POLICY item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.privacy_policy), - onClick = { openLink(mContext, "http://sadellie.github.io/unitto/privacy-app.html") } + onClick = { + openLink( + mContext, + "http://sadellie.github.io/unitto/privacy-app.html" + ) + } ) } // ANALYTICS if (BuildConfig.ANALYTICS) { item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.send_usage_statistics), supportText = stringResource(R.string.send_usage_statistics_support), switchState = viewModel.userPrefs.enableAnalytics @@ -140,7 +154,7 @@ fun SettingsScreen( // THIRD PARTY item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.third_party_licenses), onClick = { navControllerAction(ABOUT_SCREEN) } ) @@ -149,19 +163,20 @@ fun SettingsScreen( // RATE THIS APP if (BuildConfig.STORE_LINK.isNotEmpty()) { item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.rate_this_app), - onClick = { openLink(mContext, BuildConfig.STORE_LINK) } + onClick = { openLink(mContext, BuildConfig.STORE_LINK) } ) } } // APP VERSION item { - SettingsListItem( + UnittoListItem( label = stringResource(id = R.string.app_version_name_setting), - supportText = "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})" - ) {} + supportText = "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})", + onClick = {} + ) } } } diff --git a/app/src/main/java/com/sadellie/unitto/screens/setttings/ThemesScreen.kt b/app/src/main/java/com/sadellie/unitto/screens/setttings/ThemesScreen.kt index 9e848e51..74aec914 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/setttings/ThemesScreen.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/setttings/ThemesScreen.kt @@ -28,7 +28,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import com.sadellie.unitto.R import com.sadellie.unitto.screens.common.UnittoLargeTopAppBar -import com.sadellie.unitto.screens.setttings.components.SettingsListItem +import com.sadellie.unitto.screens.common.UnittoListItem import io.github.sadellie.themmo.ThemingMode import io.github.sadellie.themmo.ThemmoController @@ -44,7 +44,7 @@ fun ThemesScreen( ) { paddingValues -> LazyColumn(contentPadding = paddingValues) { item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.color_theme), allOptions = mapOf( ThemingMode.AUTO to stringResource(R.string.force_auto_mode), @@ -60,7 +60,7 @@ fun ThemesScreen( } item { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.enable_dynamic_colors), supportText = stringResource(R.string.enable_dynamic_colors_support), switchState = themmoController.isDynamicThemeEnabled, @@ -77,7 +77,7 @@ fun ThemesScreen( enter = expandVertically() + fadeIn(), exit = shrinkVertically() + fadeOut(), ) { - SettingsListItem( + UnittoListItem( label = stringResource(R.string.force_amoled_mode), supportText = stringResource(R.string.force_amoled_mode_support), switchState = themmoController.isAmoledThemeEnabled, diff --git a/app/src/main/java/com/sadellie/unitto/screens/setttings/UnitGroupsScreen.kt b/app/src/main/java/com/sadellie/unitto/screens/setttings/UnitGroupsScreen.kt index fd3e48ba..da45f735 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/setttings/UnitGroupsScreen.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/setttings/UnitGroupsScreen.kt @@ -44,7 +44,7 @@ import androidx.compose.ui.unit.dp import com.sadellie.unitto.R import com.sadellie.unitto.screens.common.UnittoLargeTopAppBar import com.sadellie.unitto.screens.common.Header -import com.sadellie.unitto.screens.setttings.components.SettingsListItem +import com.sadellie.unitto.screens.common.UnittoListItem import org.burnoutcrew.reorderable.ReorderableItem import org.burnoutcrew.reorderable.detectReorder import org.burnoutcrew.reorderable.detectReorderAfterLongPress @@ -86,7 +86,7 @@ fun UnitGroupsScreen( ) val cornerRadius = animateDpAsState(if (isDragging) 16.dp else 0.dp) - SettingsListItem( + UnittoListItem( modifier = Modifier .padding(horizontal = cornerRadius.value) .clip(RoundedCornerShape(cornerRadius.value)) @@ -132,7 +132,7 @@ fun UnitGroupsScreen( } items(hiddenUnits.value, { it }) { - SettingsListItem( + UnittoListItem( modifier = Modifier .background(MaterialTheme.colorScheme.surface) .clickable { viewModel.returnUnitGroup(it) }