Skip to content

Commit

Permalink
♻️ Introduced a viewmodel for user preferences
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzovngl committed Sep 6, 2023
1 parent f832370 commit 3d7f10d
Show file tree
Hide file tree
Showing 30 changed files with 514 additions and 543 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.lorenzovainigli.foodexpirationdates.di

import com.lorenzovainigli.foodexpirationdates.viewmodel.ExpirationDateViewModel
import com.lorenzovainigli.foodexpirationdates.viewmodel.ExpirationDatesViewModel
import com.lorenzovainigli.foodexpirationdates.model.dao.ExpirationDatesDao
import dagger.Component

@Component(modules = [AppModule::class])
interface AppComponent {
fun injectViewModel(expirationDateViewModel: ExpirationDateViewModel)
fun injectViewModel(expirationDateViewModel: ExpirationDatesViewModel)
fun injectDao(expirationDatesDao: ExpirationDatesDao)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.room.Room
import com.lorenzovainigli.foodexpirationdates.model.AppDatabase
import com.lorenzovainigli.foodexpirationdates.model.repository.ExpirationDateRepository
import com.lorenzovainigli.foodexpirationdates.model.repository.ExpirationDatesRepositoryImpl
import com.lorenzovainigli.foodexpirationdates.model.repository.PreferencesRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -25,13 +26,15 @@ class AppModule {
).allowMainThreadQueries().build()
}

// @Provides
// @Singleton
// fun expirationDatesDao(database: AppDatabase): ExpirationDatesDao = database.expirationDatesDao

@Provides
@Singleton
fun provideExpirationDateRepository(database: AppDatabase): ExpirationDateRepository {
return ExpirationDatesRepositoryImpl(database.expirationDatesDao)
}

@Provides
@Singleton
fun providePreferencesRepository(): PreferencesRepository {
return PreferencesRepository()
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.lorenzovainigli.foodexpirationdates.model
package com.lorenzovainigli.foodexpirationdates.model.repository

import android.content.Context
import androidx.activity.ComponentActivity
Expand All @@ -8,7 +8,7 @@ import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Locale

class PreferencesProvider {
class PreferencesRepository {

companion object {

Expand Down Expand Up @@ -85,7 +85,7 @@ class PreferencesProvider {

fun setThemeMode(context: Context, themeMode: ThemeMode) {
return context.getSharedPreferences(sharedPrefsName, ComponentActivity.MODE_PRIVATE)
.edit().putInt(this.themeMode, themeMode.ordinal).apply()
.edit().putInt(Companion.themeMode, themeMode.ordinal).apply()
}

fun getDynamicColors(context: Context): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ class InfoActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
InfoActivityLayout()
InfoActivityLayout(
context = this
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ class InsertActivity : ComponentActivity() {
.appModule(AppModule())
.build()
setContent {
InsertActivityLayout(itemId = itemId)
InsertActivityLayout(
context = this,
itemId = itemId
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import com.lorenzovainigli.foodexpirationdates.di.AppModule
import com.lorenzovainigli.foodexpirationdates.di.DaggerAppComponent
import com.lorenzovainigli.foodexpirationdates.model.NotificationManager
import com.lorenzovainigli.foodexpirationdates.view.composable.activity.MainActivityLayout
import com.lorenzovainigli.foodexpirationdates.viewmodel.ExpirationDateViewModel
import com.lorenzovainigli.foodexpirationdates.viewmodel.ExpirationDatesViewModel
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
Expand All @@ -27,9 +27,13 @@ class MainActivity : ComponentActivity() {
override fun onResume() {
super.onResume()
setContent {
val viewModel: ExpirationDateViewModel = viewModel()
val dates by viewModel.getDates().collectAsState(emptyList())
MainActivityLayout(dates)
val viewModel: ExpirationDatesViewModel = viewModel()
val items by viewModel.getDates().collectAsState(emptyList())
MainActivityLayout(
context = this,
items = items,
viewModel = viewModel
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import androidx.work.WorkManager
import com.lorenzovainigli.foodexpirationdates.BuildConfig
import com.lorenzovainigli.foodexpirationdates.model.worker.CheckExpirationsWorker
import com.lorenzovainigli.foodexpirationdates.view.composable.activity.SettingsActivityLayout
import dagger.hilt.android.AndroidEntryPoint
import java.util.Calendar
import java.util.concurrent.TimeUnit

@AndroidEntryPoint
class SettingsActivity : ComponentActivity() {

@RequiresApi(Build.VERSION_CODES.O)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.lorenzovainigli.foodexpirationdates.view.composable

import android.content.Context
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
Expand All @@ -19,7 +20,7 @@ import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import com.lorenzovainigli.foodexpirationdates.R
import com.lorenzovainigli.foodexpirationdates.model.PreferencesProvider
import com.lorenzovainigli.foodexpirationdates.model.repository.PreferencesRepository
import com.lorenzovainigli.foodexpirationdates.ui.theme.FoodExpirationDatesTheme
import com.lorenzovainigli.foodexpirationdates.view.preview.DefaultPreviews
import com.lorenzovainigli.foodexpirationdates.view.preview.LanguagePreviews
Expand All @@ -29,7 +30,11 @@ import java.util.Calendar
const val DateFormatDialog = "DateFormatDialog"

@Composable
fun DateFormatDialog(isDialogOpen: Boolean = true, onDismissRequest: () -> Unit = {}) {
fun DateFormatDialog(
isDialogOpen: Boolean = true,
onDismissRequest: () -> Unit = {},
onClickDate: (Context, String) -> Unit = { _, _ -> }
) {
if (isDialogOpen) {
Dialog(onDismissRequest = onDismissRequest) {
Card(
Expand All @@ -54,16 +59,24 @@ fun DateFormatDialog(isDialogOpen: Boolean = true, onDismissRequest: () -> Unit
text = stringResource(id = R.string.locale_formats),
color = MaterialTheme.colorScheme.onSurface
)
PreferencesProvider.getAvailLocaleDateFormats().forEach { item ->
DateFormatRow(item = item, onDismissRequest = onDismissRequest)
PreferencesRepository.getAvailLocaleDateFormats().forEach { item ->
DateFormatRow(
item = item,
onDismissRequest = onDismissRequest,
onClick = onClickDate
)
}
Text(
modifier = Modifier.padding(top = 8.dp, bottom = 4.dp),
text = stringResource(id = R.string.other_formats),
color = MaterialTheme.colorScheme.onSurface
)
PreferencesProvider.getAvailOtherDateFormats().forEach { item ->
DateFormatRow(item = item, onDismissRequest = onDismissRequest)
PreferencesRepository.getAvailOtherDateFormats().forEach { item ->
DateFormatRow(
item = item,
onDismissRequest = onDismissRequest,
onClick = onClickDate
)
}
}
}
Expand All @@ -74,15 +87,19 @@ fun DateFormatDialog(isDialogOpen: Boolean = true, onDismissRequest: () -> Unit
const val DateFormatRow = "DateFormatRow"

@Composable
fun DateFormatRow(item: String, onDismissRequest: () -> Unit){
fun DateFormatRow(
item: String,
onDismissRequest: () -> Unit,
onClick: (Context, String) -> Unit
){
val context = LocalContext.current
val sdf = SimpleDateFormat(item, context.resources.configuration.locales[0])
ClickableText(
modifier = Modifier.padding(2.dp).testTag(DateFormatRow),
text = AnnotatedString(sdf.format(Calendar.getInstance().time)),
style = MaterialTheme.typography.headlineSmall.copy(color = MaterialTheme.colorScheme.onSurface),
onClick = {
PreferencesProvider.setUserDateFormat(context, item)
onClick(context, item)
onDismissRequest()
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.lorenzovainigli.foodexpirationdates.R
import com.lorenzovainigli.foodexpirationdates.model.PreferencesProvider
import com.lorenzovainigli.foodexpirationdates.model.repository.PreferencesRepository
import com.lorenzovainigli.foodexpirationdates.model.entity.ExpirationDate
import com.lorenzovainigli.foodexpirationdates.ui.theme.DarkOrange
import com.lorenzovainigli.foodexpirationdates.ui.theme.DarkRed
Expand All @@ -56,7 +56,7 @@ fun FoodCard(
isInDarkTheme: Boolean = false
) {
val context = LocalContext.current
val dateFormat = PreferencesProvider.getUserDateFormat(context)
val dateFormat = PreferencesRepository.getUserDateFormat(context)
val sdf = SimpleDateFormat(dateFormat, context.resources.configuration.locales[0])
val today = Calendar.getInstance()
val twoDaysAgo = Calendar.getInstance()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.lorenzovainigli.foodexpirationdates.view.composable.activity

import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
Expand All @@ -23,6 +24,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
Expand All @@ -33,29 +35,38 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.lorenzovainigli.foodexpirationdates.BuildConfig
import com.lorenzovainigli.foodexpirationdates.R
import com.lorenzovainigli.foodexpirationdates.model.PreferencesProvider
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.TextIconButton
import com.lorenzovainigli.foodexpirationdates.view.preview.DefaultPreviews
import com.lorenzovainigli.foodexpirationdates.view.preview.DevicePreviews
import com.lorenzovainigli.foodexpirationdates.view.preview.LanguagePreviews
import com.lorenzovainigli.foodexpirationdates.viewmodel.PreferencesViewModel

@Composable
@Preview
fun InfoActivityLayout() {
val context = LocalContext.current
val activity = (LocalContext.current as? Activity)
fun InfoActivityLayout(
context: Context = LocalContext.current,
prefsViewModel: PreferencesViewModel? = viewModel()
) {
val activity = (context as? Activity)
val uriHandler = LocalUriHandler.current
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 = when (PreferencesProvider.getThemeMode(context)){
PreferencesProvider.Companion.ThemeMode.LIGHT.ordinal -> false
PreferencesProvider.Companion.ThemeMode.DARK.ordinal -> true
else -> isSystemInDarkTheme()
},
dynamicColor = PreferencesProvider.getDynamicColors(context)
darkTheme = isInDarkTheme,
dynamicColor = dynamicColorsState
) {
Surface(
modifier = Modifier.fillMaxSize(),
Expand Down Expand Up @@ -211,7 +222,9 @@ fun InfoActivityLayout() {
}

@DefaultPreviews
@DevicePreviews
@LanguagePreviews
@Composable
fun PreviewDarkMode() {
fun InfoActivityLayoutPreview() {
InfoActivityLayout()
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.lorenzovainigli.foodexpirationdates.view.composable.activity

import android.app.Activity
import android.content.Context
import android.widget.Toast
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.clickable
Expand Down Expand Up @@ -35,6 +36,7 @@ import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
Expand All @@ -48,32 +50,39 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.lorenzovainigli.foodexpirationdates.R
import com.lorenzovainigli.foodexpirationdates.model.PreferencesProvider
import com.lorenzovainigli.foodexpirationdates.model.repository.PreferencesRepository
import com.lorenzovainigli.foodexpirationdates.model.entity.ExpirationDate
import com.lorenzovainigli.foodexpirationdates.ui.theme.FoodExpirationDatesTheme
import com.lorenzovainigli.foodexpirationdates.view.composable.MyTopAppBar
import com.lorenzovainigli.foodexpirationdates.view.preview.DevicePreviews
import com.lorenzovainigli.foodexpirationdates.view.preview.LanguagePreviews
import com.lorenzovainigli.foodexpirationdates.viewmodel.ExpirationDateViewModel
import com.lorenzovainigli.foodexpirationdates.viewmodel.ExpirationDatesViewModel
import com.lorenzovainigli.foodexpirationdates.viewmodel.PreferencesViewModel
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Locale

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun InsertActivityLayout(
context: Context = LocalContext.current,
itemId: Int? = null,
viewModel: ExpirationDateViewModel? = viewModel(),
viewModel: ExpirationDatesViewModel? = viewModel(),
prefsViewModel: PreferencesViewModel? = viewModel(),
addExpirationDate: ((ExpirationDate) -> Unit)? = viewModel!!::addExpirationDate
) {
val context = LocalContext.current
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 = when (PreferencesProvider.getThemeMode(context)){
PreferencesProvider.Companion.ThemeMode.LIGHT.ordinal -> false
PreferencesProvider.Companion.ThemeMode.DARK.ordinal -> true
else -> isSystemInDarkTheme()
},
dynamicColor = PreferencesProvider.getDynamicColors(context)
darkTheme = isInDarkTheme,
dynamicColor = dynamicColorsState
) {
Surface(
modifier = Modifier.fillMaxSize(),
Expand Down Expand Up @@ -289,5 +298,9 @@ fun InsertActivityLayout(
@LanguagePreviews
@Composable
fun InsertActivityLayoutPreview() {
InsertActivityLayout(null, null)
InsertActivityLayout(
context = LocalContext.current,
itemId = null,
viewModel = null
)
}
Loading

0 comments on commit 3d7f10d

Please sign in to comment.