Improved unit groups screen

Better visuals, less bugs, more animations
This commit is contained in:
Sad Ellie 2022-08-13 14:53:49 +03:00
parent eec27637c6
commit 3ba2d1d5f6
6 changed files with 127 additions and 34 deletions

View File

@ -63,8 +63,9 @@ fun SettingsScreen(
// THEME
item {
SettingsListItem(
label = stringResource(id = R.string.unit_groups_setting)
) { navControllerAction(UNIT_GROUPS_SCREEN) }
label = stringResource(id = R.string.unit_groups_setting),
onClick = { navControllerAction(UNIT_GROUPS_SCREEN) }
)
}
// PRECISION
@ -102,8 +103,9 @@ fun SettingsScreen(
// CURRENCY RATE NOTE
item {
SettingsListItem(
label = stringResource(R.string.currency_rates_note_setting)
) { dialogState = DialogState.CURRENCY_RATE }
label = stringResource(R.string.currency_rates_note_setting),
onClick = { dialogState = DialogState.CURRENCY_RATE }
)
}
// ADDITIONAL GROUP
@ -112,15 +114,17 @@ fun SettingsScreen(
// TERMS AND CONDITIONS
item {
SettingsListItem(
label = stringResource(R.string.terms_and_conditions)
) { openLink(mContext, "http://sadellie.github.io/unitto/terms-app.html") }
label = stringResource(R.string.terms_and_conditions),
onClick = { openLink(mContext, "http://sadellie.github.io/unitto/terms-app.html") }
)
}
// PRIVACY POLICY
item {
SettingsListItem(
label = stringResource(R.string.privacy_policy)
) { openLink(mContext, "http://sadellie.github.io/unitto/privacy-app.html") }
label = stringResource(R.string.privacy_policy),
onClick = { openLink(mContext, "http://sadellie.github.io/unitto/privacy-app.html") }
)
}
// ANALYTICS
@ -137,16 +141,18 @@ fun SettingsScreen(
// THIRD PARTY
item {
SettingsListItem(
label = stringResource(R.string.third_party_licenses)
) { navControllerAction(ABOUT_SCREEN) }
label = stringResource(R.string.third_party_licenses),
onClick = { navControllerAction(ABOUT_SCREEN) }
)
}
// RATE THIS APP
if (BuildConfig.STORE_LINK.isNotEmpty()) {
item {
SettingsListItem(
label = stringResource(R.string.rate_this_app)
) { openLink(mContext, BuildConfig.STORE_LINK) }
label = stringResource(R.string.rate_this_app),
onClick = { openLink(mContext, BuildConfig.STORE_LINK) }
)
}
}

View File

@ -21,13 +21,22 @@ package com.sadellie.unitto.screens.setttings
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AddCircle
import androidx.compose.material.icons.filled.RemoveCircle
import androidx.compose.material.icons.filled.Reorder
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
@ -37,6 +46,7 @@ import com.sadellie.unitto.screens.common.UnittoLargeTopAppBar
import com.sadellie.unitto.screens.second.components.Header
import com.sadellie.unitto.screens.setttings.components.SettingsListItem
import org.burnoutcrew.reorderable.ReorderableItem
import org.burnoutcrew.reorderable.detectReorder
import org.burnoutcrew.reorderable.detectReorderAfterLongPress
import org.burnoutcrew.reorderable.rememberReorderableLazyListState
import org.burnoutcrew.reorderable.reorderable
@ -53,7 +63,7 @@ fun UnitGroupsScreen(
val shownUnits = viewModel.shownUnitGroups.collectAsState()
val hiddenUnits = viewModel.hiddenUnitGroups.collectAsState()
val state = rememberReorderableLazyListState(
onMove = viewModel::onMove,
canDragOver = viewModel::canDragOver
@ -64,7 +74,6 @@ fun UnitGroupsScreen(
modifier = Modifier
.padding(paddingValues)
.reorderable(state)
.detectReorderAfterLongPress(state)
) {
item(key = "enabled") {
Header(text = stringResource(id = R.string.enabled_label))
@ -81,9 +90,34 @@ fun UnitGroupsScreen(
modifier = Modifier
.padding(horizontal = cornerRadius.value)
.clip(RoundedCornerShape(cornerRadius.value))
.background(background.value),
.background(background.value)
.clickable { viewModel.hideUnitGroup(item) }
.detectReorderAfterLongPress(state),
label = stringResource(item.res),
onClick = { viewModel.hideUnitGroup(item) }
leadingItem = {
Icon(
Icons.Default.RemoveCircle,
stringResource(id = R.string.disable_unit_group_description),
modifier = Modifier.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(false),
onClick = { viewModel.hideUnitGroup(item) }
)
)
},
trailingItem = {
Icon(
Icons.Default.Reorder,
stringResource(id = R.string.reorder_unit_group_description),
modifier = Modifier
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(false),
onClick = {}
)
.detectReorder(state)
)
}
)
}
}
@ -97,9 +131,22 @@ fun UnitGroupsScreen(
items(hiddenUnits.value, { it }) {
SettingsListItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier
.background(MaterialTheme.colorScheme.surface)
.clickable { viewModel.returnUnitGroup(it) }
.animateItemPlacement(),
label = stringResource(it.res),
onClick = { viewModel.returnUnitGroup(it) }
trailingItem = {
Icon(
Icons.Default.AddCircle,
stringResource(id = R.string.enable_unit_group_description),
modifier = Modifier.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(false),
onClick = { viewModel.returnUnitGroup(it) }
)
)
}
)
}
}

View File

@ -23,6 +23,7 @@ import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
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.Row
import androidx.compose.foundation.layout.RowScope
@ -62,32 +63,27 @@ import com.sadellie.unitto.R
* @param modifier Modifier that will be applied to a Row.
* @param label Main text.
* @param supportText Text that is located below label.
* @param onClick Action to perform when user clicks on this component (whole component is clickable).
* @param content Additional composable: buttons, switches, checkboxes or something else.
* @param trailingItem Additional composable, icons for example.
* @param leadingItem Additional composable: buttons, switches, checkboxes or something else.
*/
@Composable
private fun BasicSettingsListItem(
modifier: Modifier = Modifier,
label: String,
supportText: String? = null,
onClick: () -> Unit = {},
content: @Composable RowScope.() -> Unit = {}
leadingItem: @Composable() (RowScope.() -> Unit) = {},
trailingItem: @Composable() (RowScope.() -> Unit) = {}
) {
Row(
modifier = modifier
.fillMaxWidth()
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(),
onClick = onClick
)
.padding(horizontal = 16.dp, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
leadingItem()
Column(
Modifier
.padding(horizontal = 0.dp)
.weight(1f) // This makes additional composable to be seen
Modifier.weight(1f), // This makes additional composable to be seen
) {
Text(
modifier = Modifier
@ -106,7 +102,7 @@ private fun BasicSettingsListItem(
)
}
}
content()
trailingItem()
}
}
@ -124,7 +120,15 @@ fun SettingsListItem(
label: String,
supportText: String? = null,
onClick: () -> Unit,
) = BasicSettingsListItem(modifier, label, supportText, onClick)
) = BasicSettingsListItem(
modifier = modifier.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(),
onClick = onClick
),
label = label,
supportText = supportText
)
/**
* Represents one item in list on Settings screen.
@ -141,7 +145,15 @@ fun SettingsListItem(
supportText: String? = null,
switchState: Boolean,
onSwitchChange: (Boolean) -> Unit
) = BasicSettingsListItem(Modifier, label, supportText, { onSwitchChange(!switchState) }) {
) = BasicSettingsListItem(
modifier = Modifier.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(),
onClick = { onSwitchChange(!switchState) }
),
label = label,
supportText = supportText
) {
Switch(checked = switchState, onCheckedChange = { onSwitchChange(it) })
}
@ -162,7 +174,7 @@ fun <T> SettingsListItem(
allOptions: Map<T, String>,
selected: T,
onSelectedChange: (T) -> Unit
) = BasicSettingsListItem(Modifier, label, supportText, {}) {
) = BasicSettingsListItem(Modifier, label, supportText) {
var dropDownExpanded by rememberSaveable { mutableStateOf(false) }
var currentOption by rememberSaveable { mutableStateOf(selected) }
val dropDownRotation: Float by animateFloatAsState(
@ -213,3 +225,21 @@ fun <T> SettingsListItem(
}
}
}
/**
* Composable with leading and trailing items.
*
* @param label Main text.
* @param modifier Modifier that will be applied to a Row.
* @param trailingItem Additional composable, icons for example.
* @param leadingItem Additional composable: buttons, switches, checkboxes or something else.
*/
@Composable
fun SettingsListItem(
label: String,
modifier: Modifier = Modifier,
leadingItem: @Composable RowScope.() -> Unit = {},
trailingItem: @Composable RowScope.() -> Unit = {}
) {
BasicSettingsListItem(modifier = modifier, label = label, trailingItem = trailingItem, leadingItem = leadingItem)
}

View File

@ -745,5 +745,8 @@
<string name="search_placeholder_button_label">Open settings</string>
<string name="enabled_label">Enabled</string>
<string name="disabled_label">Disabled</string>
<string name="enable_unit_group_description">Enable unit group</string>
<string name="disable_unit_group_description">Disable unit group</string>
<string name="reorder_unit_group_description">Reorder unit group</string>
</resources>

View File

@ -680,5 +680,8 @@
<string name="search_placeholder_button_label">Открыть настройки</string>
<string name="enabled_label">Включено</string>
<string name="disabled_label">Отключено</string>
<string name="enable_unit_group_description">Включить группу величин</string>
<string name="disable_unit_group_description">Отключить группу величин</string>
<string name="reorder_unit_group_description">Переместить группу величин</string>
</resources>

View File

@ -1020,6 +1020,10 @@
<string name="favorite_button_description">Add or remove unit from favorites</string>
<string name="empty_search_result_description">Empty search result</string>
<string name="drop_down_description">Open or close drop down menu</string>
<string name="enable_unit_group_description">Enable unit group</string>
<string name="reorder_unit_group_description">Reorder unit group</string>
<string name="disable_unit_group_description">Disable unit group</string>
<string name="send_usage_statistics">Send usage statistics</string>
<string name="send_usage_statistics_support">All data is anonymous and encrypted</string>
<string name="app_version_name_setting">Version name</string>