diff --git a/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/DataStore.kt b/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/DataStore.kt index a078787..2076663 100644 --- a/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/DataStore.kt +++ b/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/DataStore.kt @@ -24,6 +24,5 @@ const val STATS_TOTAL_GOOD = "total_good" /** DataStore clef lié au nombre de questions mal répondu */ const val STATS_TOTAL_BAD = "total_bad" -const val ENABLED = "enabled" const val HOUR = "hour" const val MINUTE = "minute" diff --git a/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/SettingsScreen.kt b/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/SettingsScreen.kt index 8336144..a5022ad 100644 --- a/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/SettingsScreen.kt +++ b/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/SettingsScreen.kt @@ -1,7 +1,6 @@ package fr.uparis.diamantkennel.memorisationapplication import android.os.Build -import android.util.Log import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.RequiresApi @@ -11,22 +10,23 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card import androidx.compose.material3.Divider import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.FloatingActionButton -import androidx.compose.material3.Switch import androidx.compose.material3.Text -import androidx.compose.material3.TimeInput +import androidx.compose.material3.TimePicker +import androidx.compose.material3.TimePickerLayoutType +import androidx.compose.material3.TimePickerState import androidx.compose.material3.rememberTimePickerState 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 import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -35,6 +35,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.colorResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.compose.ui.window.Dialog import androidx.lifecycle.viewmodel.compose.viewModel import fr.uparis.diamantkennel.memorisationapplication.ui.SettingsViewModel import kotlinx.coroutines.flow.first @@ -48,6 +49,7 @@ fun SettingsScreen(padding: PaddingValues, model: SettingsViewModel = viewModel( var deletionDBRequest by model.deletionDB var cleanStatRequest by model.deletionStat + var choiceTimeNotifRequest by model.notif var permissionNotif by model.gavePermissionNow val prefConfig = runBlocking { model.prefConfig.first() } @@ -57,8 +59,6 @@ fun SettingsScreen(padding: PaddingValues, model: SettingsViewModel = viewModel( initialMinute = prefConfig.minute, is24Hour = true ) - var enabled by remember { mutableStateOf(prefConfig.enabled) } - model.checkPermission(context) val permissionLauncher = rememberLauncherForActivityResult( @@ -77,6 +77,15 @@ fun SettingsScreen(padding: PaddingValues, model: SettingsViewModel = viewModel( CleanStatDialog(model::cleanStats) { cleanStatRequest = false } } + if (choiceTimeNotifRequest) + { + ChoiceTimeNotifDialog( + { (model::choiceTimeNotif)(state, context) }, + { choiceTimeNotifRequest = false }, + state + ) + } + Column( modifier = Modifier.padding(padding), horizontalAlignment = Alignment.CenterHorizontally @@ -107,31 +116,31 @@ fun SettingsScreen(padding: PaddingValues, model: SettingsViewModel = viewModel( } } - Button( - enabled = !permissionNotif, - onClick = { - model.requestNotificationPermission(permissionLauncher) - } - ) { - Text(text = context.getString(R.string.permission_button)) - } + Spacer(modifier = Modifier.padding(top = 10.dp)) + Divider(color = Color.Gray) + Spacer(modifier = Modifier.padding(top = 10.dp)) - Column { - Row { - TimeInput(state = state) - Switch(enabled, { enabled = it }) + Text(text = "Notifications", fontSize = 30.sp) + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceEvenly + ) { + Button( + enabled = !permissionNotif, + onClick = { + model.requestNotificationPermission(permissionLauncher) + } + ) { + Text(text = context.getString(R.string.permission_button)) } - FloatingActionButton(onClick = { - val newConfig = TimeConfig( - enabled, - state.hour, - state.minute - ) - Log.d("Periodic", "config=$newConfig") - model.save(newConfig) - model.schedule(newConfig, context) - }) { - Text("On y va!") + Button( + enabled = permissionNotif, + onClick = { + choiceTimeNotifRequest = true + } + ) { + Text(text = context.getString(R.string.time_notif_button)) } } } @@ -184,3 +193,41 @@ fun CleanStatDialog(confirm: () -> Unit, dismiss: () -> Unit) = Button(onClick = confirm) { Text(text = LocalContext.current.getString(R.string.yes)) } }, dismissButton = { Button(onClick = dismiss) { Text(text = LocalContext.current.getString(R.string.no)) } }) + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ChoiceTimeNotifDialog(confirm: () -> Unit, dismiss: () -> Unit, state: TimePickerState) { + Dialog(onDismissRequest = { dismiss() }) { + Card( + modifier = Modifier + .padding(16.dp) + .fillMaxWidth() + .height(550.dp), + shape = RoundedCornerShape(16.dp), + ) { + Column( + modifier = Modifier.padding(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text(text = LocalContext.current.getString(R.string.time_notif), fontSize = 30.sp) + Text(text = LocalContext.current.getString(R.string.time_notif_desc)) + + Spacer(modifier = Modifier.padding(top = 10.dp)) + TimePicker(state = state, layoutType = TimePickerLayoutType.Vertical) + Spacer(modifier = Modifier.padding(top = 10.dp)) + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceEvenly + ) { + Button(onClick = dismiss) { + Text(text = LocalContext.current.getString(R.string.no)) + } + Button(onClick = confirm) { + Text(text = LocalContext.current.getString(R.string.yes)) + } + } + } + } + } +} diff --git a/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/TimeConfig.kt b/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/TimeConfig.kt index 837ce13..eaf35c4 100644 --- a/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/TimeConfig.kt +++ b/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/TimeConfig.kt @@ -1,7 +1,6 @@ package fr.uparis.diamantkennel.memorisationapplication data class TimeConfig( - val enabled: Boolean = false, val hour: Int = 8, val minute: Int = 0 ) diff --git a/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/ui/SettingsViewModel.kt b/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/ui/SettingsViewModel.kt index 8a5100b..d0f4413 100644 --- a/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/ui/SettingsViewModel.kt +++ b/app/src/main/java/fr/uparis/diamantkennel/memorisationapplication/ui/SettingsViewModel.kt @@ -7,15 +7,15 @@ import android.os.Build import android.util.Log import androidx.activity.result.ActivityResultLauncher import androidx.annotation.RequiresApi +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.TimePickerState import androidx.compose.runtime.mutableStateOf -import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.intPreferencesKey import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope import androidx.work.PeriodicWorkRequest import androidx.work.WorkManager -import fr.uparis.diamantkennel.memorisationapplication.ENABLED import fr.uparis.diamantkennel.memorisationapplication.HOUR import fr.uparis.diamantkennel.memorisationapplication.MINUTE import fr.uparis.diamantkennel.memorisationapplication.MemoApplication @@ -41,9 +41,8 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application private val statsKeyTotalGood = intPreferencesKey(STATS_TOTAL_GOOD) private val statsKeyTotalBad = intPreferencesKey(STATS_TOTAL_BAD) - private val KEY_E = booleanPreferencesKey(ENABLED) - private val KEY_H = intPreferencesKey(HOUR) - private val KEY_M = intPreferencesKey(MINUTE) + private val notifH = intPreferencesKey(HOUR) + private val notifM = intPreferencesKey(MINUTE) val statTotal = stats.data.map { it[statsKeyTotal] ?: 0 } val statTotalDone = stats.data.map { it[statsKeyTotalDone] ?: 0 } @@ -52,6 +51,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application val deletionDB = mutableStateOf(false) val deletionStat = mutableStateOf(false) + var notif = mutableStateOf(false) val gavePermissionNow = mutableStateOf(false) @@ -74,6 +74,18 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application } } + @OptIn(ExperimentalMaterial3Api::class) + fun choiceTimeNotif(state: TimePickerState, context: Context) { + notif.value = false + val newConfig = TimeConfig( + state.hour, + state.minute + ) + Log.d("Periodic", "config=$newConfig") + save(newConfig) + schedule(newConfig, context) + } + fun winrate(good: Int, bad: Int): Int { val total = good + bad if (total == 0) { @@ -96,26 +108,23 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application fun save(config: TimeConfig) { viewModelScope.launch { stats.edit { - it[KEY_E] = config.enabled - it[KEY_H] = config.hour - it[KEY_M] = config.minute + it[notifH] = config.hour + it[notifM] = config.minute } } } val prefConfig = stats.data.map { TimeConfig( - it[KEY_E] ?: false, - it[KEY_H] ?: 8, - it[KEY_M] ?: 0 + it[notifH] ?: 8, + it[notifM] ?: 0 ) } - fun schedule(config: TimeConfig, context: Context) { + private fun schedule(config: TimeConfig, context: Context) { val wm = WorkManager.getInstance(context) wm.cancelAllWork() - if (config.enabled) - wm.enqueue(request(config.hour, config.minute)) + wm.enqueue(request(config.hour, config.minute)) } private fun request(h: Int, m: Int): PeriodicWorkRequest { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ea7ff63..25f66b0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -21,7 +21,7 @@ Erreur Supprimer un jeu de question Voulez-vous supprimer ce jeu de question ? - Ok + OK Mettre à jour la question Ajouter une question Question @@ -55,4 +55,7 @@ Notifications de rappel Rappel Il est temps de réviser ! + Modifier heure de rappel + Choix heure de rappel + Choisissez l\'heure à laquelle vous souhaitez être notifié