mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-19 16:55:26 +02:00
Less garbage and bad decisions in code
This commit is contained in:
parent
e03fa61a17
commit
588474529f
@ -153,11 +153,11 @@ fun DatePickerDialog(
|
|||||||
|
|
||||||
Box(modifier = Modifier
|
Box(modifier = Modifier
|
||||||
.align(Alignment.End)
|
.align(Alignment.End)
|
||||||
.padding(DialogButtonsPadding)) {
|
.padding(_dialogButtonsPadding)) {
|
||||||
|
|
||||||
AlertDialogFlowRow(
|
AlertDialogFlowRow(
|
||||||
mainAxisSpacing = DialogButtonsMainAxisSpacing,
|
mainAxisSpacing = _dialogButtonsMainAxisSpacing,
|
||||||
crossAxisSpacing = DialogButtonsCrossAxisSpacing
|
crossAxisSpacing = _dialogButtonsCrossAxisSpacing
|
||||||
) {
|
) {
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = onDismiss
|
onClick = onDismiss
|
||||||
@ -277,6 +277,6 @@ private fun AlertDialogFlowRow(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val DialogButtonsPadding by lazy { PaddingValues(bottom = 8.dp, end = 6.dp) }
|
private val _dialogButtonsPadding by lazy { PaddingValues(bottom = 8.dp, end = 6.dp) }
|
||||||
private val DialogButtonsMainAxisSpacing by lazy { 8.dp }
|
private val _dialogButtonsMainAxisSpacing by lazy { 8.dp }
|
||||||
private val DialogButtonsCrossAxisSpacing by lazy { 12.dp }
|
private val _dialogButtonsCrossAxisSpacing by lazy { 12.dp }
|
||||||
|
@ -46,6 +46,7 @@ fun Modifier.squashable(
|
|||||||
val cornerRadius: Int by animateIntAsState(
|
val cornerRadius: Int by animateIntAsState(
|
||||||
targetValue = if (isPressed) cornerRadiusRange.first else cornerRadiusRange.last,
|
targetValue = if (isPressed) cornerRadiusRange.first else cornerRadiusRange.last,
|
||||||
animationSpec = tween(easing = FastOutSlowInEasing),
|
animationSpec = tween(easing = FastOutSlowInEasing),
|
||||||
|
label = "Squashed animation"
|
||||||
)
|
)
|
||||||
|
|
||||||
Modifier
|
Modifier
|
||||||
@ -72,6 +73,7 @@ fun Modifier.squashable(
|
|||||||
val cornerRadius: Dp by animateDpAsState(
|
val cornerRadius: Dp by animateDpAsState(
|
||||||
targetValue = if (isPressed) cornerRadiusRange.start else cornerRadiusRange.endInclusive,
|
targetValue = if (isPressed) cornerRadiusRange.start else cornerRadiusRange.endInclusive,
|
||||||
animationSpec = tween(easing = FastOutSlowInEasing),
|
animationSpec = tween(easing = FastOutSlowInEasing),
|
||||||
|
label = "Squashed animation"
|
||||||
)
|
)
|
||||||
|
|
||||||
Modifier
|
Modifier
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
package com.sadellie.unitto.core.ui.common
|
package com.sadellie.unitto.core.ui.common
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Divider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.ModalDrawerSheet
|
import androidx.compose.material3.ModalDrawerSheet
|
||||||
import androidx.compose.material3.NavigationDrawerItemDefaults
|
import androidx.compose.material3.NavigationDrawerItemDefaults
|
||||||
@ -64,7 +64,7 @@ fun UnittoDrawerSheet(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Divider(Modifier.padding(28.dp, 16.dp))
|
HorizontalDivider(Modifier.padding(28.dp, 16.dp))
|
||||||
|
|
||||||
additionalTabs.forEach { drawerItem ->
|
additionalTabs.forEach { drawerItem ->
|
||||||
val selected = drawerItem.destination.start == currentDestination
|
val selected = drawerItem.destination.start == currentDestination
|
||||||
|
@ -18,35 +18,15 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.core.ui.common
|
package com.sadellie.unitto.core.ui.common
|
||||||
|
|
||||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
|
||||||
import androidx.compose.animation.core.tween
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.widthIn
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.outlined.ArrowDropDown
|
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
import androidx.compose.material.ripple.rememberRipple
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
|
||||||
import androidx.compose.material3.ExposedDropdownMenuBox
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.ListItem
|
import androidx.compose.material3.ListItem
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.OutlinedTextField
|
|
||||||
import androidx.compose.material3.OutlinedTextFieldDefaults
|
|
||||||
import androidx.compose.material3.Switch
|
import androidx.compose.material3.Switch
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.rotate
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.sadellie.unitto.core.base.R
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents one item in list on Settings screen.
|
* Represents one item in list on Settings screen.
|
||||||
@ -83,83 +63,3 @@ fun UnittoListItem(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents one item in list on Settings screen with drop-down menu.
|
|
||||||
*
|
|
||||||
* @param label Main text.
|
|
||||||
* @param supportText Text that is located below label.
|
|
||||||
* @param allOptions Options in drop-down menu. Key is option itself and value is the string that
|
|
||||||
* will be shown.
|
|
||||||
* @param selected Selected option.
|
|
||||||
* @param onSelectedChange Action to perform when drop-down menu item is selected.
|
|
||||||
*/
|
|
||||||
@Composable
|
|
||||||
fun <T> UnittoListItem(
|
|
||||||
label: String,
|
|
||||||
supportText: String? = null,
|
|
||||||
allOptions: Map<T, String>,
|
|
||||||
leadingContent: @Composable (() -> Unit)?,
|
|
||||||
selected: T,
|
|
||||||
onSelectedChange: (T) -> Unit
|
|
||||||
) {
|
|
||||||
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)
|
|
||||||
)
|
|
||||||
|
|
||||||
ListItem(
|
|
||||||
headlineContent = { Text(label) },
|
|
||||||
supportingContent = { supportText?.let { Text(text = it) } },
|
|
||||||
leadingContent = leadingContent,
|
|
||||||
trailingContent = {
|
|
||||||
ExposedDropdownMenuBox(
|
|
||||||
modifier = Modifier,
|
|
||||||
expanded = dropDownExpanded,
|
|
||||||
onExpandedChange = { dropDownExpanded = it }
|
|
||||||
) {
|
|
||||||
OutlinedTextField(
|
|
||||||
modifier = Modifier
|
|
||||||
.menuAnchor()
|
|
||||||
.widthIn(1.dp),
|
|
||||||
value = allOptions[currentOption] ?: selected.toString(),
|
|
||||||
onValueChange = {},
|
|
||||||
readOnly = true,
|
|
||||||
singleLine = true,
|
|
||||||
enabled = false,
|
|
||||||
textStyle = MaterialTheme.typography.bodyLarge,
|
|
||||||
colors = OutlinedTextFieldDefaults.colors(
|
|
||||||
disabledTextColor = MaterialTheme.colorScheme.onSurface,
|
|
||||||
disabledBorderColor = MaterialTheme.colorScheme.outline,
|
|
||||||
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
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
@ -70,13 +70,13 @@ fun UnittoSearchBar(
|
|||||||
scrollBehavior: TopAppBarScrollBehavior? = null,
|
scrollBehavior: TopAppBarScrollBehavior? = null,
|
||||||
colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors()
|
colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors()
|
||||||
) {
|
) {
|
||||||
var showSearch by remember { mutableStateOf(false) }
|
var showSearchInput by remember { mutableStateOf(false) }
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
fun stagedNavigateUp() {
|
fun stagedNavigateUp() {
|
||||||
if (showSearch) {
|
if (showSearchInput) {
|
||||||
// Search text field is open, need to close it and clear search query
|
// Search text field is open, need to close it and clear search query
|
||||||
showSearch = false
|
showSearchInput = false
|
||||||
// focusManager.clearFocus()
|
// focusManager.clearFocus()
|
||||||
onQueryChange("")
|
onQueryChange("")
|
||||||
} else {
|
} else {
|
||||||
@ -88,8 +88,8 @@ fun UnittoSearchBar(
|
|||||||
TopAppBar(
|
TopAppBar(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
title = {
|
title = {
|
||||||
Crossfade(showSearch) { _showSearch ->
|
Crossfade(showSearchInput) { showSearch ->
|
||||||
if (_showSearch) {
|
if (showSearch) {
|
||||||
LaunchedEffect(Unit) { focusRequester.requestFocus() }
|
LaunchedEffect(Unit) { focusRequester.requestFocus() }
|
||||||
|
|
||||||
SearchTextField(
|
SearchTextField(
|
||||||
@ -113,13 +113,13 @@ fun UnittoSearchBar(
|
|||||||
NavigateUpButton { stagedNavigateUp() }
|
NavigateUpButton { stagedNavigateUp() }
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
Crossfade(showSearch) { _showSearch ->
|
Crossfade(showSearchInput) { showSearch ->
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
if (_showSearch) {
|
if (showSearch) {
|
||||||
ClearButton(visible = query.isNotEmpty()) { onQueryChange("") }
|
ClearButton(visible = query.isNotEmpty()) { onQueryChange("") }
|
||||||
searchActions()
|
searchActions()
|
||||||
} else {
|
} else {
|
||||||
SearchButton { showSearch = true }
|
SearchButton { showSearchInput = true }
|
||||||
noSearchActions()
|
noSearchActions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,8 @@ fun UnittoSlider(
|
|||||||
) {
|
) {
|
||||||
val animated = animateFloatAsState(
|
val animated = animateFloatAsState(
|
||||||
targetValue = value.roundToInt().toFloat(),
|
targetValue = value.roundToInt().toFloat(),
|
||||||
animationSpec = spring()
|
animationSpec = spring(),
|
||||||
|
label = "Thumb animation"
|
||||||
)
|
)
|
||||||
|
|
||||||
Slider(
|
Slider(
|
||||||
@ -82,7 +83,11 @@ private fun SquigglyTrack(
|
|||||||
) {
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
var direct by remember { mutableFloatStateOf(0.72f) }
|
var direct by remember { mutableFloatStateOf(0.72f) }
|
||||||
val animatedDirect = animateFloatAsState(direct, spring(stiffness = Spring.StiffnessLow))
|
val animatedDirect = animateFloatAsState(
|
||||||
|
targetValue = direct,
|
||||||
|
animationSpec = spring(stiffness = Spring.StiffnessLow),
|
||||||
|
label = "Track animation"
|
||||||
|
)
|
||||||
|
|
||||||
LaunchedEffect(sliderState.value) {
|
LaunchedEffect(sliderState.value) {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
|
@ -21,9 +21,9 @@ package com.sadellie.unitto.core.ui.common.textfield
|
|||||||
import com.sadellie.unitto.core.base.Separator
|
import com.sadellie.unitto.core.base.Separator
|
||||||
|
|
||||||
sealed class FormatterSymbols(val grouping: String, val fractional: String) {
|
sealed class FormatterSymbols(val grouping: String, val fractional: String) {
|
||||||
object Spaces : FormatterSymbols(" ", ".")
|
data object Spaces : FormatterSymbols(" ", ".")
|
||||||
object Period : FormatterSymbols(".", ",")
|
data object Period : FormatterSymbols(".", ",")
|
||||||
object Comma : FormatterSymbols(",", ".")
|
data object Comma : FormatterSymbols(",", ".")
|
||||||
}
|
}
|
||||||
|
|
||||||
object AllFormatterSymbols {
|
object AllFormatterSymbols {
|
||||||
|
@ -37,31 +37,31 @@ sealed class DrawerItems(
|
|||||||
val selectedIcon: ImageVector,
|
val selectedIcon: ImageVector,
|
||||||
val defaultIcon: ImageVector
|
val defaultIcon: ImageVector
|
||||||
) {
|
) {
|
||||||
object Calculator : DrawerItems(
|
data object Calculator : DrawerItems(
|
||||||
destination = TopLevelDestinations.Calculator,
|
destination = TopLevelDestinations.Calculator,
|
||||||
selectedIcon = Icons.Filled.Calculate,
|
selectedIcon = Icons.Filled.Calculate,
|
||||||
defaultIcon = Icons.Outlined.Calculate
|
defaultIcon = Icons.Outlined.Calculate
|
||||||
)
|
)
|
||||||
|
|
||||||
object Converter : DrawerItems(
|
data object Converter : DrawerItems(
|
||||||
destination = TopLevelDestinations.Converter,
|
destination = TopLevelDestinations.Converter,
|
||||||
selectedIcon = Icons.Filled.SwapHoriz,
|
selectedIcon = Icons.Filled.SwapHoriz,
|
||||||
defaultIcon = Icons.Outlined.SwapHoriz
|
defaultIcon = Icons.Outlined.SwapHoriz
|
||||||
)
|
)
|
||||||
|
|
||||||
object DateDifference : DrawerItems(
|
data object DateDifference : DrawerItems(
|
||||||
destination = TopLevelDestinations.DateCalculator,
|
destination = TopLevelDestinations.DateCalculator,
|
||||||
selectedIcon = Icons.Filled.Event,
|
selectedIcon = Icons.Filled.Event,
|
||||||
defaultIcon = Icons.Outlined.Event
|
defaultIcon = Icons.Outlined.Event
|
||||||
)
|
)
|
||||||
|
|
||||||
object TimeZones : DrawerItems(
|
data object TimeZones : DrawerItems(
|
||||||
destination = TopLevelDestinations.TimeZone,
|
destination = TopLevelDestinations.TimeZone,
|
||||||
selectedIcon = Icons.Filled.Schedule,
|
selectedIcon = Icons.Filled.Schedule,
|
||||||
defaultIcon = Icons.Outlined.Schedule
|
defaultIcon = Icons.Outlined.Schedule
|
||||||
)
|
)
|
||||||
|
|
||||||
object Settings : DrawerItems(
|
data object Settings : DrawerItems(
|
||||||
destination = TopLevelDestinations.Settings,
|
destination = TopLevelDestinations.Settings,
|
||||||
selectedIcon = Icons.Filled.Settings,
|
selectedIcon = Icons.Filled.Settings,
|
||||||
defaultIcon = Icons.Outlined.Settings
|
defaultIcon = Icons.Outlined.Settings
|
||||||
|
@ -36,6 +36,6 @@ data class CalculatorUIState(
|
|||||||
|
|
||||||
sealed class CalculationResult(@StringRes val label: Int? = null) {
|
sealed class CalculationResult(@StringRes val label: Int? = null) {
|
||||||
data class Default(val text: String = "") : CalculationResult()
|
data class Default(val text: String = "") : CalculationResult()
|
||||||
object DivideByZeroError : CalculationResult(R.string.divide_by_zero_error)
|
data object DivideByZeroError : CalculationResult(R.string.divide_by_zero_error)
|
||||||
object Error : CalculationResult(R.string.error_label)
|
data object Error : CalculationResult(R.string.error_label)
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,8 @@ private fun PortraitKeyboard(
|
|||||||
var invMode: Boolean by remember { mutableStateOf(false) }
|
var invMode: Boolean by remember { mutableStateOf(false) }
|
||||||
val expandRotation: Float by animateFloatAsState(
|
val expandRotation: Float by animateFloatAsState(
|
||||||
targetValue = if (showAdditional) 0f else 180f,
|
targetValue = if (showAdditional) 0f else 180f,
|
||||||
animationSpec = tween(easing = FastOutSlowInEasing)
|
animationSpec = tween(easing = FastOutSlowInEasing),
|
||||||
|
label = "Rotate on expand"
|
||||||
)
|
)
|
||||||
|
|
||||||
ColumnWithConstraints(
|
ColumnWithConstraints(
|
||||||
|
@ -60,6 +60,6 @@ sealed class ConversionResult {
|
|||||||
data class Default(val result: String) : ConversionResult()
|
data class Default(val result: String) : ConversionResult()
|
||||||
data class Time(val result: String) : ConversionResult()
|
data class Time(val result: String) : ConversionResult()
|
||||||
data class NumberBase(val result: String) : ConversionResult()
|
data class NumberBase(val result: String) : ConversionResult()
|
||||||
object Loading : ConversionResult()
|
data object Loading : ConversionResult()
|
||||||
object Error : ConversionResult()
|
data object Error : ConversionResult()
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,8 @@ internal fun TopScreenPart(
|
|||||||
var swapped by remember { mutableStateOf(false) }
|
var swapped by remember { mutableStateOf(false) }
|
||||||
val swapButtonRotation: Float by animateFloatAsState(
|
val swapButtonRotation: Float by animateFloatAsState(
|
||||||
targetValue = if (swapped) 0f else 180f,
|
targetValue = if (swapped) 0f else 180f,
|
||||||
animationSpec = tween(easing = FastOutSlowInEasing)
|
animationSpec = tween(easing = FastOutSlowInEasing),
|
||||||
|
label = "Swap button rotation"
|
||||||
)
|
)
|
||||||
val mContext = LocalContext.current
|
val mContext = LocalContext.current
|
||||||
|
|
||||||
@ -165,7 +166,8 @@ internal fun TopScreenPart(
|
|||||||
(expandHorizontally(clip = false, expandFrom = Alignment.Start) + fadeIn()
|
(expandHorizontally(clip = false, expandFrom = Alignment.Start) + fadeIn()
|
||||||
togetherWith fadeOut())
|
togetherWith fadeOut())
|
||||||
.using(SizeTransform(clip = false))
|
.using(SizeTransform(clip = false))
|
||||||
}
|
},
|
||||||
|
label = "Animated short name from"
|
||||||
) { value ->
|
) { value ->
|
||||||
Text(
|
Text(
|
||||||
text = value,
|
text = value,
|
||||||
@ -262,7 +264,8 @@ internal fun TopScreenPart(
|
|||||||
// Exit animation
|
// Exit animation
|
||||||
togetherWith fadeOut())
|
togetherWith fadeOut())
|
||||||
.using(SizeTransform(clip = false))
|
.using(SizeTransform(clip = false))
|
||||||
}
|
},
|
||||||
|
label = "Animated short label to"
|
||||||
) { value ->
|
) { value ->
|
||||||
Text(
|
Text(
|
||||||
text = value,
|
text = value,
|
||||||
|
@ -73,12 +73,12 @@ internal fun DateTimeSelectorBlock(
|
|||||||
if (DateFormat.is24HourFormat(LocalContext.current)) {
|
if (DateFormat.is24HourFormat(LocalContext.current)) {
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = dateTime.format(UnittoDateTimeFormatter.time24Formatter),
|
targetState = dateTime.format(UnittoDateTimeFormatter.time24Formatter),
|
||||||
label = "date time change",
|
|
||||||
transitionSpec = {
|
transitionSpec = {
|
||||||
slideInVertically { height -> height } + fadeIn() togetherWith
|
slideInVertically { height -> height } + fadeIn() togetherWith
|
||||||
slideOutVertically { height -> -height } + fadeOut() using
|
slideOutVertically { height -> -height } + fadeOut() using
|
||||||
SizeTransform()
|
SizeTransform()
|
||||||
}
|
},
|
||||||
|
label = "Animated 24 hour",
|
||||||
) { time ->
|
) { time ->
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.clickable(
|
modifier = Modifier.clickable(
|
||||||
@ -105,7 +105,8 @@ internal fun DateTimeSelectorBlock(
|
|||||||
slideInVertically { height -> height } + fadeIn() togetherWith
|
slideInVertically { height -> height } + fadeIn() togetherWith
|
||||||
slideOutVertically { height -> -height } + fadeOut() using
|
slideOutVertically { height -> -height } + fadeOut() using
|
||||||
SizeTransform()
|
SizeTransform()
|
||||||
}
|
},
|
||||||
|
label = "Animated 12 hour",
|
||||||
) { time ->
|
) { time ->
|
||||||
Text(
|
Text(
|
||||||
text = time.format(UnittoDateTimeFormatter.time12Formatter1),
|
text = time.format(UnittoDateTimeFormatter.time12Formatter1),
|
||||||
@ -120,7 +121,8 @@ internal fun DateTimeSelectorBlock(
|
|||||||
slideInVertically { height -> height } + fadeIn() togetherWith
|
slideInVertically { height -> height } + fadeIn() togetherWith
|
||||||
slideOutVertically { height -> -height } + fadeOut() using
|
slideOutVertically { height -> -height } + fadeOut() using
|
||||||
SizeTransform()
|
SizeTransform()
|
||||||
}
|
},
|
||||||
|
label = "Animated am/pm",
|
||||||
) { time ->
|
) { time ->
|
||||||
Text(
|
Text(
|
||||||
text = time.format(UnittoDateTimeFormatter.time12Formatter2),
|
text = time.format(UnittoDateTimeFormatter.time12Formatter2),
|
||||||
@ -137,7 +139,8 @@ internal fun DateTimeSelectorBlock(
|
|||||||
slideInVertically { height -> height } + fadeIn() togetherWith
|
slideInVertically { height -> height } + fadeIn() togetherWith
|
||||||
slideOutVertically { height -> -height } + fadeOut() using
|
slideOutVertically { height -> -height } + fadeOut() using
|
||||||
SizeTransform()
|
SizeTransform()
|
||||||
}
|
},
|
||||||
|
label = "Animated date",
|
||||||
) { date ->
|
) { date ->
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.clickable(
|
modifier = Modifier.clickable(
|
||||||
|
@ -42,7 +42,7 @@ internal sealed class ZonedDateTimeDifference(
|
|||||||
minutes = minutes,
|
minutes = minutes,
|
||||||
)
|
)
|
||||||
|
|
||||||
object Zero : ZonedDateTimeDifference()
|
data object Zero : ZonedDateTimeDifference()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/a/25760725
|
// https://stackoverflow.com/a/25760725
|
||||||
|
@ -82,8 +82,9 @@ internal fun LeftSideScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val chipsBackground = animateColorAsState(
|
val chipsBackground = animateColorAsState(
|
||||||
if (needToTint) elevatedColor else MaterialTheme.colorScheme.surface,
|
targetValue = if (needToTint) elevatedColor else MaterialTheme.colorScheme.surface,
|
||||||
tween(durationMillis = 500, easing = LinearOutSlowInEasing)
|
animationSpec = tween(durationMillis = 500, easing = LinearOutSlowInEasing),
|
||||||
|
label = "Chips background",
|
||||||
)
|
)
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
@ -99,10 +100,9 @@ internal fun LeftSideScreen(
|
|||||||
title = stringResource(R.string.units_screen_from),
|
title = stringResource(R.string.units_screen_from),
|
||||||
placeholder = stringResource(R.string.search_bar_placeholder),
|
placeholder = stringResource(R.string.search_bar_placeholder),
|
||||||
noSearchActions = {
|
noSearchActions = {
|
||||||
FavoritesButton(
|
FavoritesButton(uiState.value.favoritesOnly) {
|
||||||
favoritesOnly = uiState.value.favoritesOnly,
|
viewModel.toggleFavoritesOnly(false)
|
||||||
favoriteAction = { viewModel.toggleFavoritesOnly(false) }
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
ChipsRow(
|
ChipsRow(
|
||||||
|
@ -100,10 +100,9 @@ internal fun RightSideScreen(
|
|||||||
title = stringResource(R.string.units_screen_to),
|
title = stringResource(R.string.units_screen_to),
|
||||||
placeholder = stringResource(R.string.search_bar_placeholder),
|
placeholder = stringResource(R.string.search_bar_placeholder),
|
||||||
noSearchActions = {
|
noSearchActions = {
|
||||||
FavoritesButton(
|
FavoritesButton(uiState.value.favoritesOnly) {
|
||||||
favoritesOnly = uiState.value.favoritesOnly,
|
viewModel.toggleFavoritesOnly(true)
|
||||||
favoriteAction = { viewModel.toggleFavoritesOnly(true) }
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -34,15 +34,16 @@ import com.sadellie.unitto.core.base.R
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun FavoritesButton(
|
internal fun FavoritesButton(
|
||||||
favoritesOnly: Boolean,
|
state: Boolean,
|
||||||
favoriteAction: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
IconButton(onClick = favoriteAction) {
|
IconButton(onClick = onClick) {
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = favoritesOnly,
|
targetState = state,
|
||||||
transitionSpec = {
|
transitionSpec = {
|
||||||
(scaleIn() togetherWith scaleOut()).using(SizeTransform(clip = false))
|
(scaleIn() togetherWith scaleOut()).using(SizeTransform(clip = false))
|
||||||
}
|
},
|
||||||
|
label = "Animated click"
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
if (it) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder,
|
if (it) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder,
|
||||||
|
@ -27,18 +27,18 @@ import com.sadellie.unitto.feature.unitslist.LeftSideScreen
|
|||||||
import com.sadellie.unitto.feature.unitslist.RightSideScreen
|
import com.sadellie.unitto.feature.unitslist.RightSideScreen
|
||||||
import com.sadellie.unitto.feature.unitslist.UnitsListViewModel
|
import com.sadellie.unitto.feature.unitslist.UnitsListViewModel
|
||||||
|
|
||||||
const val leftSideRoute = "left_side_route"
|
private const val LEFT_SIDE_ROUTE = "LEFT_SIDE_ROUTE"
|
||||||
const val rightSideRoute = "right_side_route"
|
private const val RIGHT_SIDE_ROUTE = "RIGHT_SIDE_ROUTE"
|
||||||
private const val unitFromIdArg = "unitFromId"
|
private const val UNIT_FROM_ARG = "UNIT_FROM_ARG"
|
||||||
private const val unitToIdArg = "unitToId"
|
private const val UNIT_TO_ARG = "UNIT_FROM_ARG"
|
||||||
private const val inputArg = "input"
|
private const val INPUT_ARG = "INPUT_ARG"
|
||||||
|
|
||||||
fun NavController.navigateToLeftSide(unitFromId: String) {
|
fun NavController.navigateToLeftSide(unitFromId: String) {
|
||||||
navigate("$leftSideRoute/$unitFromId")
|
navigate("$LEFT_SIDE_ROUTE/$unitFromId")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun NavController.navigateToRightSide(unitFromId: String, unitToId: String, input: String?) {
|
fun NavController.navigateToRightSide(unitFromId: String, unitToId: String, input: String?) {
|
||||||
navigate("$rightSideRoute/$unitFromId/$unitToId/$input")
|
navigate("$RIGHT_SIDE_ROUTE/$unitFromId/$unitToId/$input")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun NavGraphBuilder.leftScreen(
|
fun NavGraphBuilder.leftScreen(
|
||||||
@ -48,11 +48,11 @@ fun NavGraphBuilder.leftScreen(
|
|||||||
onSelect: (AbstractUnit) -> Unit
|
onSelect: (AbstractUnit) -> Unit
|
||||||
) {
|
) {
|
||||||
composable(
|
composable(
|
||||||
route = "$leftSideRoute/{$unitFromIdArg}"
|
route = "$LEFT_SIDE_ROUTE/{$UNIT_FROM_ARG}"
|
||||||
) {
|
) {
|
||||||
LeftSideScreen(
|
LeftSideScreen(
|
||||||
viewModel = viewModel,
|
viewModel = viewModel,
|
||||||
currentUnitId = it.arguments?.getString(unitFromIdArg),
|
currentUnitId = it.arguments?.getString(UNIT_FROM_ARG),
|
||||||
navigateUp = navigateUp,
|
navigateUp = navigateUp,
|
||||||
navigateToSettingsAction = navigateToUnitGroups,
|
navigateToSettingsAction = navigateToUnitGroups,
|
||||||
selectAction = onSelect
|
selectAction = onSelect
|
||||||
@ -68,11 +68,11 @@ fun NavGraphBuilder.rightScreen(
|
|||||||
|
|
||||||
) {
|
) {
|
||||||
composable(
|
composable(
|
||||||
route = "$rightSideRoute/{$unitFromIdArg}/{$unitToIdArg}/{$inputArg}"
|
route = "$RIGHT_SIDE_ROUTE/{$UNIT_FROM_ARG}/{$UNIT_TO_ARG}/{$INPUT_ARG}"
|
||||||
) {
|
) {
|
||||||
val unitFromId = it.arguments?.getString(unitFromIdArg) ?: return@composable
|
val unitFromId = it.arguments?.getString(UNIT_FROM_ARG) ?: return@composable
|
||||||
val unitToId = it.arguments?.getString(unitToIdArg) ?: return@composable
|
val unitToId = it.arguments?.getString(UNIT_TO_ARG) ?: return@composable
|
||||||
val input = it.arguments?.getString(inputArg)
|
val input = it.arguments?.getString(INPUT_ARG)
|
||||||
viewModel.setSelectedChip(unitFromId, true)
|
viewModel.setSelectedChip(unitFromId, true)
|
||||||
|
|
||||||
RightSideScreen(
|
RightSideScreen(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user