Skip to content

Commit

Permalink
♻️ Refactor settings view to use componentized list items
Browse files Browse the repository at this point in the history
The settings view has been refactored to use componentized list items,
improving code readability and maintainability. Each settings item and
dialog was extracted into a separate Composable function in separate
files, which also allows easier and isolated previewing using the
@Preview annotation. The componentized settings items include: Currency,
 PIN, Repository, Date, Time, Milliseconds Bar Enabled, Hit Timer
 Milliseconds Enabled, Precision, and Share App items.

Signed-off-by: Leonardo Colman Lopes <[email protected]>
  • Loading branch information
LeoColman committed May 27, 2024
1 parent a3812cc commit c4c9f77
Show file tree
Hide file tree
Showing 13 changed files with 562 additions and 654 deletions.
688 changes: 34 additions & 654 deletions app/src/main/kotlin/br/com/colman/petals/settings/SettingsView.kt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
@file:OptIn(ExperimentalMaterialApi::class)

package br.com.colman.petals.settings.view.dialog

import androidx.annotation.StringRes
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.padding
import androidx.compose.material.AlertDialog
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.ExposedDropdownMenuBox
import androidx.compose.material.ExposedDropdownMenuDefaults
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import br.com.colman.petals.R

@Composable
fun SelectFromListDialog(
initialValue: String,
possibleValues: List<String>,
setValue: (String) -> Unit,
onDismiss: () -> Unit,
@StringRes label: Int,
) {
var value by remember { mutableStateOf(initialValue) }
var expanded by remember { mutableStateOf(false) }
AlertDialog(
onDismissRequest = onDismiss,
text = {
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded }
) {
TextField(
value = value,
onValueChange = { },
readOnly = true,
label = { Text(text = stringResource(label)) },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
colors = ExposedDropdownMenuDefaults.textFieldColors()
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
possibleValues.forEach { selectedOption ->
DropdownMenuItem(onClick = {
value = selectedOption
expanded = false
}) { Text(text = selectedOption) }
}
}
}
},
confirmButton = {
Text(
stringResource(R.string.ok),
Modifier
.padding(8.dp)
.clickable {
setValue(value)
onDismiss()
}
)
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package br.com.colman.petals.settings.view.dialog

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.padding
import androidx.compose.material.AlertDialog
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.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.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import br.com.colman.petals.R

@Composable
fun TextfieldDialog(
initialValue: String,
setValue: (String) -> Unit,
onDismiss: () -> Unit,
resourceLabel: Int,
) {
var value by remember { mutableStateOf(initialValue) }
AlertDialog(
onDismissRequest = onDismiss,
text = {
OutlinedTextField(
value,
{ value = it },
label = { Text(stringResource(resourceLabel)) }
)
},
confirmButton = {
Text(
stringResource(R.string.ok),
Modifier
.padding(8.dp)
.clickable {
setValue(value)
onDismiss()
}
)
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package br.com.colman.petals.settings.view.listitem

import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import br.com.colman.petals.R
import br.com.colman.petals.R.string
import br.com.colman.petals.settings.view.dialog.TextfieldDialog
import compose.icons.TablerIcons
import compose.icons.tablericons.Cash

@Preview
@Composable
fun CurrencyListItem(currency: String = "", setCurrency: (String) -> Unit = {}) {
DialogListItem(
icon = TablerIcons.Cash,
textId = R.string.currency_icon,
descriptionId = R.string.what_icon_should_be_used_for_currency,
dialog = { hideDialog -> CurrencyDialog(currency, setCurrency, hideDialog) }
)
}

@Preview
@Composable
private fun CurrencyDialog(
initialCurrencyFormat: String = "$",
setCurrencyFormat: (String) -> Unit = {},
onDismiss: () -> Unit = {},
) {
TextfieldDialog(
initialValue = initialCurrencyFormat,
setValue = setCurrencyFormat,
onDismiss = onDismiss,
resourceLabel = string.currency_icon
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package br.com.colman.petals.settings.view.listitem

import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import br.com.colman.petals.R.string.date_format_label
import br.com.colman.petals.R.string.what_date_format_should_be_used
import br.com.colman.petals.settings.view.dialog.SelectFromListDialog
import compose.icons.TablerIcons
import compose.icons.tablericons.Calendar

@Preview
@Composable
fun DateListItem(
dateFormat: String = "",
dateFormatList: List<String> = listOf(),
setDateFormat: (String) -> Unit = {}
) {
DialogListItem(
icon = TablerIcons.Calendar,
textId = date_format_label,
descriptionId = what_date_format_should_be_used,
dialog = { hideDialog -> DateDialog(dateFormat, dateFormatList, setDateFormat, hideDialog) }
)
}

@Preview
@Composable
private fun DateDialog(
initialDateFormat: String = "",
dateFormatList: List<String> = listOf(),
setDateFormat: (String) -> Unit = {},
onDismiss: () -> Unit = {},
) {
SelectFromListDialog(
initialValue = initialDateFormat,
possibleValues = dateFormatList,
setValue = setDateFormat,
onDismiss = onDismiss,
label = date_format_label
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@file:OptIn(ExperimentalMaterialApi::class)

package br.com.colman.petals.settings.view.listitem

import androidx.annotation.StringRes
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.size
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Icon
import androidx.compose.material.ListItem
import androidx.compose.material.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.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp

@Composable
fun DialogListItem(
icon: ImageVector,
@StringRes textId: Int,
@StringRes descriptionId: Int,
dialog: @Composable (hideDialog: () -> Unit) -> Unit
) {
var showDialog by remember { mutableStateOf(false) }
ListItem(
modifier = Modifier.clickable { showDialog = true },
icon = { Icon(icon, null, Modifier.size(42.dp)) },
secondaryText = { Text(stringResource(descriptionId)) }
) {
Text(stringResource(textId))
}
if (showDialog) {
dialog { showDialog = false }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package br.com.colman.petals.settings.view.listitem

import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import br.com.colman.petals.R.string.enable_or_disable_milliseconds_on_hit_timer_page
import br.com.colman.petals.R.string.hit_timer_milliseconds_enabled
import br.com.colman.petals.settings.view.dialog.SelectFromListDialog
import compose.icons.TablerIcons
import compose.icons.tablericons.ToggleLeft

@Preview
@Composable
fun HitTimerMillisecondsEnabledListItem(
hitTimerMillisecondsEnabled: String = "",
hitTimerMillisecondsEnabledList: List<String> = listOf(),
setHitTimerMillisecondsEnabled: (String) -> Unit = {}
) {
DialogListItem(
icon = TablerIcons.ToggleLeft,
textId = hit_timer_milliseconds_enabled,
descriptionId = enable_or_disable_milliseconds_on_hit_timer_page,
dialog = { hideDialog ->
HitTimerMillisecondsEnabledDialog(
hitTimerMillisecondsEnabled,
hitTimerMillisecondsEnabledList,
setHitTimerMillisecondsEnabled,
hideDialog
)
}
)
}

@Preview
@Composable
private fun HitTimerMillisecondsEnabledDialog(
initialHitTimerMillisecondsEnabled: String = "",
hitTimerMillisecondsEnabledList: List<String> = listOf(),
setHitTimerMillisecondsEnabled: (String) -> Unit = {},
onDismiss: () -> Unit = {},
) {
SelectFromListDialog(
initialValue = initialHitTimerMillisecondsEnabled,
possibleValues = hitTimerMillisecondsEnabledList,
setValue = setHitTimerMillisecondsEnabled,
onDismiss = onDismiss,
label = hit_timer_milliseconds_enabled
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package br.com.colman.petals.settings.view.listitem

import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import br.com.colman.petals.R.string.enable_or_disable_milliseconds_bar_on_home_page
import br.com.colman.petals.R.string.milliseconds_enabled
import br.com.colman.petals.settings.view.dialog.SelectFromListDialog
import compose.icons.TablerIcons
import compose.icons.tablericons.CircleOff

@Preview
@Composable
fun MillisecondsBarEnabledListItem(
millisEnabled: String = "",
millisOptions: List<String> = listOf(),
setMillisEnabled: (String) -> Unit = {}
) {
DialogListItem(
icon = TablerIcons.CircleOff,
textId = milliseconds_enabled,
descriptionId = enable_or_disable_milliseconds_bar_on_home_page,
dialog = { hideDialog -> MillisecondsEnabledDialog(millisEnabled, millisOptions, setMillisEnabled, hideDialog) }
)
}

@Preview
@Composable
private fun MillisecondsEnabledDialog(
initialMillisecondsEnabled: String = "",
millisecondsEnabledList: List<String> = listOf(),
setMillisecondsEnabled: (String) -> Unit = {},
onDismiss: () -> Unit = {},
) {
SelectFromListDialog(
initialValue = initialMillisecondsEnabled,
possibleValues = millisecondsEnabledList,
setValue = setMillisecondsEnabled,
onDismiss = onDismiss,
label = milliseconds_enabled
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package br.com.colman.petals.settings.view.listitem

import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import br.com.colman.petals.R.string.app_pin
import br.com.colman.petals.R.string.password_description
import br.com.colman.petals.settings.view.dialog.TextfieldDialog
import compose.icons.TablerIcons
import compose.icons.tablericons.Lock

@Preview
@Composable
fun PinListItem(setPin: (String?) -> Unit = {}) {
DialogListItem(
icon = TablerIcons.Lock,
descriptionId = password_description,
textId = app_pin,
dialog = { hideDialog -> PinDialog(setPin, hideDialog) }
)
}

@Preview
@Composable
private fun PinDialog(
setPin: (String?) -> Unit = {},
onDismiss: () -> Unit = {},
) {
fun setValue(value: String) = if (value.isEmpty()) setPin(null) else setPin(value)

TextfieldDialog(
initialValue = "",
setValue = { setValue(it) },
onDismiss = onDismiss,
resourceLabel = app_pin
)
}
Loading

0 comments on commit c4c9f77

Please sign in to comment.