diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b5f9c1d..4c3c663 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -35,6 +35,9 @@
+
+
{
return availLocaleDateFormats.map {
(DateFormat.getDateInstance(
@@ -113,6 +120,28 @@ class PreferencesRepository {
.edit().putInt(keyThemeMode, themeMode.ordinal).apply()
}
+ fun getTopBarFont(
+ context: Context,
+ sharedPrefs: String = sharedPrefsName,
+ ): Int{
+ try {
+ return context.getSharedPreferences(sharedPrefs, ComponentActivity.MODE_PRIVATE)
+ .getInt(keyTopBarFont,TopBarFont.NORMAL.ordinal)
+ } catch (e: Exception){
+ e.printStackTrace()
+ }
+ return TopBarFont.NORMAL.ordinal
+ }
+
+ fun setTopBarFont(
+ context: Context,
+ sharedPrefs: String = sharedPrefsName,
+ topBarFont: TopBarFont
+ ) {
+ return context.getSharedPreferences(sharedPrefs, ComponentActivity.MODE_PRIVATE)
+ .edit().putInt(keyTopBarFont, topBarFont.ordinal).apply()
+ }
+
fun getDynamicColors(
context: Context,
sharedPrefs: String = sharedPrefsName,
diff --git a/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/activity/UISettingsActivity.kt b/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/activity/UISettingsActivity.kt
new file mode 100644
index 0000000..0606fe0
--- /dev/null
+++ b/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/activity/UISettingsActivity.kt
@@ -0,0 +1,21 @@
+package com.lorenzovainigli.foodexpirationdates.view.activity
+
+import android.os.Build
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.annotation.RequiresApi
+import com.lorenzovainigli.foodexpirationdates.view.composable.activity.UISettingsActivityLayout
+import dagger.hilt.android.AndroidEntryPoint
+
+@AndroidEntryPoint
+class UISettingsActivity : ComponentActivity() {
+
+ @RequiresApi(Build.VERSION_CODES.O)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ UISettingsActivityLayout()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/composable/MyTopAppBar.kt b/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/composable/MyTopAppBar.kt
index b294ccb..09b7174 100644
--- a/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/composable/MyTopAppBar.kt
+++ b/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/composable/MyTopAppBar.kt
@@ -6,11 +6,17 @@ import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import androidx.lifecycle.viewmodel.compose.viewModel
+import com.lorenzovainigli.foodexpirationdates.model.repository.PreferencesRepository
import com.lorenzovainigli.foodexpirationdates.ui.theme.FoodExpirationDatesTheme
+import com.lorenzovainigli.foodexpirationdates.viewmodel.PreferencesViewModel
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -18,8 +24,13 @@ fun MyTopAppBar(
title: String,
actions: @Composable RowScope.() -> Unit = {},
navigationIcon: @Composable () -> Unit = {},
- scrollBehavior: TopAppBarScrollBehavior? = null
+ scrollBehavior: TopAppBarScrollBehavior? = null,
+ prefsViewModel: PreferencesViewModel? = viewModel()
) {
+ val context = LocalContext.current
+ val topBarFontState = prefsViewModel?.getTopBarFont(context)?.collectAsState()?.value
+ ?: PreferencesRepository.Companion.TopBarFont.NORMAL.ordinal
+
LargeTopAppBar(
modifier = Modifier
.padding(bottom = 4.dp)
@@ -30,7 +41,13 @@ fun MyTopAppBar(
title = {
Text(
text = title,
- color = MaterialTheme.colorScheme.primary
+ color = MaterialTheme.colorScheme.primary,
+ fontWeight = when(topBarFontState){
+ PreferencesRepository.Companion.TopBarFont.NORMAL.ordinal -> FontWeight.Normal
+ PreferencesRepository.Companion.TopBarFont.BOLD.ordinal -> FontWeight.Medium
+ PreferencesRepository.Companion.TopBarFont.EXTRA_BOLD.ordinal-> FontWeight.Bold
+ else -> null
+ }
)
},
actions = actions,
diff --git a/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/composable/activity/SettingsActivityLayout.kt b/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/composable/activity/SettingsActivityLayout.kt
index db3b1e7..6c447cc 100644
--- a/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/composable/activity/SettingsActivityLayout.kt
+++ b/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/composable/activity/SettingsActivityLayout.kt
@@ -2,6 +2,7 @@ package com.lorenzovainigli.foodexpirationdates.view.composable.activity
import android.app.Activity
import android.content.Context
+import android.content.Intent
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.foundation.isSystemInDarkTheme
@@ -45,6 +46,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.lorenzovainigli.foodexpirationdates.R
import com.lorenzovainigli.foodexpirationdates.model.repository.PreferencesRepository
import com.lorenzovainigli.foodexpirationdates.ui.theme.FoodExpirationDatesTheme
+import com.lorenzovainigli.foodexpirationdates.view.activity.UISettingsActivity
import com.lorenzovainigli.foodexpirationdates.view.composable.DateFormatDialog
import com.lorenzovainigli.foodexpirationdates.view.composable.MyTopAppBar
import com.lorenzovainigli.foodexpirationdates.view.composable.NotificationTimeBottomSheet
@@ -233,6 +235,19 @@ fun SettingsActivityLayout(
}
)
}
+ SettingsItem(
+ label = stringResource(R.string.ui_settings)
+ ){
+ OutlinedButton(
+ onClick = {
+ val intent = Intent(context, UISettingsActivity::class.java)
+ context.startActivity(intent)
+ }
+ ) {
+ Text(text = stringResource(R.string.custom_ui))
+ }
+ }
+
}
}
}
diff --git a/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/composable/activity/UISettingsActivityLayout.kt b/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/composable/activity/UISettingsActivityLayout.kt
new file mode 100644
index 0000000..146e3cc
--- /dev/null
+++ b/app/src/main/java/com/lorenzovainigli/foodexpirationdates/view/composable/activity/UISettingsActivityLayout.kt
@@ -0,0 +1,134 @@
+package com.lorenzovainigli.foodexpirationdates.view.composable.activity
+
+import android.app.Activity
+import android.content.Context
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.ArrowBack
+import androidx.compose.material3.Button
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.OutlinedButton
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBarDefaults
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.lifecycle.viewmodel.compose.viewModel
+import com.lorenzovainigli.foodexpirationdates.R
+import com.lorenzovainigli.foodexpirationdates.model.repository.PreferencesRepository
+import com.lorenzovainigli.foodexpirationdates.ui.theme.FoodExpirationDatesTheme
+import com.lorenzovainigli.foodexpirationdates.view.composable.MyTopAppBar
+import com.lorenzovainigli.foodexpirationdates.view.composable.SettingsItem
+import com.lorenzovainigli.foodexpirationdates.view.preview.DefaultPreviews
+import com.lorenzovainigli.foodexpirationdates.view.preview.LanguagePreviews
+import com.lorenzovainigli.foodexpirationdates.viewmodel.PreferencesViewModel
+
+@OptIn(ExperimentalMaterial3Api::class)
+@RequiresApi(Build.VERSION_CODES.O)
+@Composable
+fun UISettingsActivityLayout(
+ context: Context = LocalContext.current,
+ prefsViewModel: PreferencesViewModel? = viewModel()
+) {
+ val activity = (context as? Activity)
+ val topBarFontState = prefsViewModel?.getTopBarFont(context)?.collectAsState()?.value
+ ?: PreferencesRepository.Companion.TopBarFont.NORMAL.ordinal
+ val darkThemeState = prefsViewModel?.getThemeMode(context)?.collectAsState()?.value
+ ?: PreferencesRepository.Companion.ThemeMode.SYSTEM
+ val dynamicColorsState = prefsViewModel?.getDynamicColors(context)?.collectAsState()?.value
+ ?: false
+
+ val isInDarkTheme = when (darkThemeState) {
+ PreferencesRepository.Companion.ThemeMode.LIGHT.ordinal -> false
+ PreferencesRepository.Companion.ThemeMode.DARK.ordinal -> true
+ else -> isSystemInDarkTheme()
+ }
+
+ FoodExpirationDatesTheme(
+ darkTheme = isInDarkTheme,
+ dynamicColor = dynamicColorsState
+ ){
+ val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
+ Scaffold(
+ modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
+ topBar = {
+ MyTopAppBar(
+ title = stringResource(id = R.string.ui_settings),
+ navigationIcon = {
+ IconButton(onClick = { activity?.finish() }) {
+ Icon(
+ imageVector = Icons.Outlined.ArrowBack,
+ contentDescription = stringResource(id = R.string.back),
+ tint = MaterialTheme.colorScheme.primary
+ )
+ }
+ },
+ scrollBehavior = scrollBehavior
+ )
+ }
+ ) { padding ->
+ Column(
+ modifier = Modifier
+ .padding(padding)
+ .padding(10.dp)
+ .verticalScroll(rememberScrollState()),
+ verticalArrangement = Arrangement.spacedBy(16.dp)
+ ) {
+ SettingsItem(
+ label = stringResource(R.string.top_bar_font_weight)
+ ) {
+ PreferencesRepository.Companion.TopBarFont.values().forEach { topBarFont->
+ Spacer(
+ modifier = Modifier
+ .fillMaxHeight()
+ .weight(0.1f)
+ )
+ if (topBarFont.ordinal == topBarFontState) {
+ Button(onClick = {}) {
+ Text(
+ text = context.getString(topBarFont.label)
+ )
+ }
+ }
+ if (topBarFont.ordinal != topBarFontState) {
+ OutlinedButton(
+ onClick = {
+ prefsViewModel?.setTopBarFont(context, topBarFont)
+ },
+ ) {
+ Text(
+ text = context.getString(topBarFont.label)
+ )
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+@RequiresApi(Build.VERSION_CODES.O)
+@DefaultPreviews
+@LanguagePreviews
+@Composable
+fun UISettingsActivityLayoutPreview() {
+ UISettingsActivityLayout()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lorenzovainigli/foodexpirationdates/viewmodel/PreferencesViewModel.kt b/app/src/main/java/com/lorenzovainigli/foodexpirationdates/viewmodel/PreferencesViewModel.kt
index 0aaa0c7..813122c 100644
--- a/app/src/main/java/com/lorenzovainigli/foodexpirationdates/viewmodel/PreferencesViewModel.kt
+++ b/app/src/main/java/com/lorenzovainigli/foodexpirationdates/viewmodel/PreferencesViewModel.kt
@@ -25,10 +25,12 @@ class PreferencesViewModel @Inject constructor(): ViewModel() {
private var _themeMode = MutableStateFlow(0)
private var themeMode = _themeMode.asStateFlow()
-
private var _dynamicColors = MutableStateFlow(false)
private var dynamicColors = _dynamicColors.asStateFlow()
+ private var _topBarFont = MutableStateFlow(0)
+ private var topbarFont = _topBarFont.asStateFlow()
+
fun getDateFormat(context: Context): StateFlow {
viewModelScope.launch {
_dateFormat.value = PreferencesRepository.getUserDateFormat(context)
@@ -88,6 +90,23 @@ class PreferencesViewModel @Inject constructor(): ViewModel() {
_themeMode.value = theme.ordinal
}
+ fun getTopBarFont(context: Context):StateFlow {
+ viewModelScope.launch {
+ _topBarFont.value = PreferencesRepository.getTopBarFont(context)
+ }
+ return topbarFont
+ }
+
+ fun setTopBarFont(context: Context, topBarFont: PreferencesRepository.Companion.TopBarFont) {
+ viewModelScope.launch {
+ PreferencesRepository.setTopBarFont(
+ context = context,
+ topBarFont = topBarFont
+ )
+ }
+ _topBarFont.value = topBarFont.ordinal
+ }
+
fun getDynamicColors(context: Context): StateFlow {
viewModelScope.launch {
_dynamicColors.value = PreferencesRepository.getDynamicColors(context)
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a31e081..9436807 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -44,6 +44,13 @@
Dark
%1$s deleted
Undo
+ Normal
+ Bold
+ Extra Bold
+ UI Settings
+ Custom UI
+ Top Bar Font Weight
+
- Display a list with food expiration dates in ascending time order.