fix(#23,#24,#27): theme preference wiring, dd MMM yyyy dates, calendar icon in DateField #38
@@ -8,9 +8,12 @@ import android.view.ViewTreeObserver
|
|||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.core.util.Consumer
|
import androidx.core.util.Consumer
|
||||||
import cafe.adriel.voyager.core.screen.Screen
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
@@ -18,6 +21,9 @@ import cafe.adriel.voyager.core.stack.StackEvent
|
|||||||
import cafe.adriel.voyager.navigator.Navigator
|
import cafe.adriel.voyager.navigator.Navigator
|
||||||
import cafe.adriel.voyager.navigator.NavigatorDisposeBehavior
|
import cafe.adriel.voyager.navigator.NavigatorDisposeBehavior
|
||||||
import cafe.adriel.voyager.transitions.ScreenTransition
|
import cafe.adriel.voyager.transitions.ScreenTransition
|
||||||
|
import dev.achmad.ledgerr.di.util.inject
|
||||||
|
import dev.achmad.ledgerr.domain.preference.AppPreference
|
||||||
|
import dev.achmad.ledgerr.domain.preference.AppTheme as AppThemePref
|
||||||
import dev.achmad.ledgerr.ui.screens.home.HomeScreen
|
import dev.achmad.ledgerr.ui.screens.home.HomeScreen
|
||||||
import dev.achmad.ledgerr.ui.theme.AppTheme
|
import dev.achmad.ledgerr.ui.theme.AppTheme
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
@@ -53,7 +59,17 @@ class MainActivity : ComponentActivity() {
|
|||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
AppTheme {
|
val systemDark = isSystemInDarkTheme()
|
||||||
|
val appThemePref by inject<AppPreference>()
|
||||||
|
.appTheme()
|
||||||
|
.changes()
|
||||||
|
.collectAsState(initial = AppThemePref.SYSTEM)
|
||||||
|
val darkTheme = when (appThemePref) {
|
||||||
|
AppThemePref.LIGHT -> false
|
||||||
|
AppThemePref.DARK -> true
|
||||||
|
AppThemePref.SYSTEM -> systemDark
|
||||||
|
}
|
||||||
|
AppTheme(darkTheme = darkTheme) {
|
||||||
val slideDistance = rememberSlideDistance()
|
val slideDistance = rememberSlideDistance()
|
||||||
Navigator(
|
Navigator(
|
||||||
screen = initialScreen,
|
screen = initialScreen,
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package dev.achmad.ledgerr.ui.components
|
package dev.achmad.ledgerr.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.CalendarMonth
|
||||||
import androidx.compose.material3.DatePicker
|
import androidx.compose.material3.DatePicker
|
||||||
import androidx.compose.material3.DatePickerDialog
|
import androidx.compose.material3.DatePickerDialog
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
@@ -16,10 +21,10 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import dev.achmad.ledgerr.R
|
import dev.achmad.ledgerr.R
|
||||||
|
import dev.achmad.ledgerr.ui.util.dateFormatter
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
import java.time.format.DateTimeFormatter
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -32,14 +37,17 @@ fun DateField(
|
|||||||
var showPicker by remember { mutableStateOf(false) }
|
var showPicker by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = date.format(DateTimeFormatter.ISO_LOCAL_DATE),
|
value = date.format(dateFormatter()),
|
||||||
onValueChange = {},
|
onValueChange = {},
|
||||||
label = { Text(label) },
|
label = { Text(label) },
|
||||||
readOnly = true,
|
readOnly = true,
|
||||||
modifier = modifier.fillMaxWidth(),
|
modifier = modifier.fillMaxWidth().clickable { showPicker = true },
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
TextButton(onClick = { showPicker = true }) {
|
IconButton(onClick = { showPicker = true }) {
|
||||||
Text(text = stringResource(R.string.action_pick))
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.CalendarMonth,
|
||||||
|
contentDescription = stringResource(R.string.action_pick),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ package dev.achmad.ledgerr.ui.components
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.CalendarMonth
|
||||||
import androidx.compose.material.icons.outlined.IosShare
|
import androidx.compose.material.icons.outlined.IosShare
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.DatePicker
|
import androidx.compose.material3.DatePicker
|
||||||
@@ -30,6 +32,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import dev.achmad.ledgerr.R
|
import dev.achmad.ledgerr.R
|
||||||
import dev.achmad.ledgerr.domain.expense.model.DateRange
|
import dev.achmad.ledgerr.domain.expense.model.DateRange
|
||||||
import dev.achmad.ledgerr.ui.components.preference.widget.TextPreferenceWidget
|
import dev.achmad.ledgerr.ui.components.preference.widget.TextPreferenceWidget
|
||||||
|
import dev.achmad.ledgerr.ui.util.dateFormatter
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
@@ -170,16 +173,20 @@ private fun DateField(
|
|||||||
var showPicker by remember { mutableStateOf(false) }
|
var showPicker by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = date.format(DateTimeFormatter.ISO_LOCAL_DATE),
|
value = date.format(dateFormatter()),
|
||||||
onValueChange = {},
|
onValueChange = {},
|
||||||
label = { Text(label) },
|
label = { Text(label) },
|
||||||
readOnly = true,
|
readOnly = true,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 4.dp),
|
.padding(vertical = 4.dp)
|
||||||
|
.clickable { showPicker = true },
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
TextButton(onClick = { showPicker = true }) {
|
IconButton(onClick = { showPicker = true }) {
|
||||||
Text(text = stringResource(R.string.action_pick))
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.CalendarMonth,
|
||||||
|
contentDescription = stringResource(R.string.action_pick),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ import dev.achmad.ledgerr.ui.components.SingleSelectFilterChipGroup
|
|||||||
import dev.achmad.ledgerr.ui.screens.add_edit_expense.AddEditExpenseScreen
|
import dev.achmad.ledgerr.ui.screens.add_edit_expense.AddEditExpenseScreen
|
||||||
import dev.achmad.ledgerr.ui.screens.add_edit_recurring.AddEditRecurringScreen
|
import dev.achmad.ledgerr.ui.screens.add_edit_recurring.AddEditRecurringScreen
|
||||||
import dev.achmad.ledgerr.ui.screens.import_bank_statement.ImportBankStatementScreen
|
import dev.achmad.ledgerr.ui.screens.import_bank_statement.ImportBankStatementScreen
|
||||||
|
import dev.achmad.ledgerr.ui.util.dateFormatter
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.time.format.DateTimeFormatter
|
|
||||||
|
|
||||||
object ExpenseListScreen : Screen {
|
object ExpenseListScreen : Screen {
|
||||||
|
|
||||||
@@ -365,7 +365,7 @@ private fun ExpenseRow(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
text = item.expense.date.format(DateTimeFormatter.ISO_LOCAL_DATE),
|
text = item.expense.date.format(dateFormatter()),
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
)
|
)
|
||||||
@@ -412,7 +412,7 @@ private fun RecurringRow(
|
|||||||
RecurringInterval.YEARLY -> stringResource(R.string.add_edit_recurring_interval_yearly)
|
RecurringInterval.YEARLY -> stringResource(R.string.add_edit_recurring_interval_yearly)
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
text = "$intervalText · ${item.recurring.nextDueDate.format(DateTimeFormatter.ISO_LOCAL_DATE)}",
|
text = "$intervalText · ${item.recurring.nextDueDate.format(dateFormatter())}",
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ import dev.achmad.ledgerr.ui.screens.add_edit_expense.AddEditExpenseScreen
|
|||||||
import dev.achmad.ledgerr.ui.screens.expenses.ExpenseListScreen
|
import dev.achmad.ledgerr.ui.screens.expenses.ExpenseListScreen
|
||||||
import dev.achmad.ledgerr.ui.screens.import_bank_statement.ImportBankStatementScreen
|
import dev.achmad.ledgerr.ui.screens.import_bank_statement.ImportBankStatementScreen
|
||||||
import dev.achmad.ledgerr.ui.screens.settings.SettingsScreen
|
import dev.achmad.ledgerr.ui.screens.settings.SettingsScreen
|
||||||
|
import dev.achmad.ledgerr.ui.util.dateFormatter
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.time.format.DateTimeFormatter
|
|
||||||
|
|
||||||
object HomeScreen : Screen {
|
object HomeScreen : Screen {
|
||||||
|
|
||||||
@@ -443,7 +443,7 @@ private fun ExpenseRow(item: ExpenseWithCategory) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
text = item.expense.date.format(DateTimeFormatter.ISO_LOCAL_DATE),
|
text = item.expense.date.format(dateFormatter()),
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package dev.achmad.ledgerr.ui.util
|
package dev.achmad.ledgerr.ui.util
|
||||||
|
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
fun timeFormatter(is24Hour: Boolean): DateTimeFormatter {
|
fun timeFormatter(is24Hour: Boolean): DateTimeFormatter {
|
||||||
return if (is24Hour) {
|
return if (is24Hour) {
|
||||||
@@ -10,6 +11,9 @@ fun timeFormatter(is24Hour: Boolean): DateTimeFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun dateFormatter(): DateTimeFormatter =
|
||||||
|
DateTimeFormatter.ofPattern("dd MMM yyyy", Locale.getDefault())
|
||||||
|
|
||||||
fun String.toTitleCase(): String {
|
fun String.toTitleCase(): String {
|
||||||
return this.lowercase().split(" ").joinToString(" ") { word ->
|
return this.lowercase().split(" ").joinToString(" ") { word ->
|
||||||
word.replaceFirstChar { it.uppercase() }
|
word.replaceFirstChar { it.uppercase() }
|
||||||
|
|||||||
Reference in New Issue
Block a user