Skip to content

Commit

Permalink
control notifications worker
Browse files Browse the repository at this point in the history
  • Loading branch information
omer358 committed Sep 22, 2024
1 parent a6d9fbc commit 1ec26fe
Show file tree
Hide file tree
Showing 13 changed files with 138 additions and 15 deletions.
35 changes: 29 additions & 6 deletions app/src/main/java/com/omo/rememberme/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class MainActivity : ComponentActivity() {

private val settingsViewModel: SettingsViewModel by viewModels()
private val mainViewModel: MainViewModel by viewModels()

@Inject
lateinit var appEntryUseCases: AppEntryUseCases

Expand All @@ -52,7 +53,7 @@ class MainActivity : ComponentActivity() {
private fun setupUI(viewModel: MainViewModel) {
enableEdgeToEdge()
installSplashScreen().apply {
setKeepOnScreenCondition{
setKeepOnScreenCondition {
viewModel.splashCondition
}
}
Expand All @@ -62,15 +63,26 @@ class MainActivity : ComponentActivity() {
private fun observeUiState() {
lifecycleScope.launch {
settingsViewModel.uiState.collect { uiState ->
if (shouldScheduleWork(uiState.remindersRepetition)) {
handlePermissionsAndScheduleWork(uiState.remindersRepetition)
Log.i(TAG,"the SettingsUiState has changed!: $uiState")
if (uiState.notificationsEnabled) {
Log.i(TAG,"the notifications is enabled")
if (shouldScheduleWork(uiState.remindersRepetition)) {
Log.i(TAG,"Should scheduleWork")
handlePermissionsAndScheduleWork(uiState.remindersRepetition)
}
Log.i(TAG,"Should not schedule work, the reminder is duplicated")
} else {
Log.i(TAG,"Should not cancel work")
cancelNotificationWork()
}
}
}
}

private fun shouldScheduleWork(currentRepetition: RemindersRepetition): Boolean {
return currentRepetition != lastRepetition
private fun shouldScheduleWork(
currentRepetition: RemindersRepetition
): Boolean {
return (currentRepetition != lastRepetition)
}

private fun handlePermissionsAndScheduleWork(repetition: RemindersRepetition) {
Expand Down Expand Up @@ -100,7 +112,10 @@ class MainActivity : ComponentActivity() {
private fun handlePermissionResult(isGranted: Boolean) {
lifecycleScope.launch {
settingsViewModel.uiState.collect { uiState ->
if (isGranted && shouldScheduleWork(uiState.remindersRepetition)) {
if (isGranted && shouldScheduleWork(
uiState.remindersRepetition
)
) {
scheduleNotificationWork(uiState.remindersRepetition)
}
}
Expand All @@ -126,6 +141,14 @@ class MainActivity : ComponentActivity() {
lastRepetition = repetition
}

private fun cancelNotificationWork() {
Log.i(TAG, "Cancelling notification work")
val cancelUniqueWork = WorkManager.getInstance(this).cancelUniqueWork("notificationWork")
cancelUniqueWork.result.run {
Log.i(TAG, "Notification work cancelled")
}
}

private fun getRepeatIntervalInHours(repetition: RemindersRepetition): Int {
return when (repetition) {
RemindersRepetition.OnceADay -> 24
Expand Down
4 changes: 0 additions & 4 deletions app/src/main/java/com/omo/rememberme/RememberMeApp.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package com.omo.rememberme

import android.content.res.Configuration.UI_MODE_NIGHT_YES
import android.util.Log
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
Expand All @@ -20,7 +18,6 @@ import com.omo.rememberme.ui.theme.RememberMeTheme

private const val TAG = "RememberMeApp"

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun RememberMeApp(startDestination: String) {
val viewModel: SettingsViewModel = hiltViewModel()
Expand All @@ -33,7 +30,6 @@ fun RememberMeApp(startDestination: String) {
ThemeMode.DARK -> true
ThemeMode.SYSTEM -> isSystemInDarkTheme()
}
Log.i(TAG, "RememberMeApp: $isDarkTheme")
RememberMeTheme(
darkTheme = isDarkTheme
){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import android.util.Log
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
Expand Down Expand Up @@ -64,12 +65,25 @@ class SettingsManagerImpl @Inject constructor(
}
}

override suspend fun saveNotificationStatus(enabled: Boolean) {
context.dataStore.edit { preferences ->
preferences[PreferencesKeys.REMINDERS_ENABLED] = enabled
}
}

override suspend fun isNotificationEnabled(): Flow<Boolean> {
return context.dataStore.data.map { preferences ->
preferences[PreferencesKeys.REMINDERS_ENABLED] ?: false
}
}

companion object {
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = REMEMBER_ME_SETTING_NAME)

private object PreferencesKeys {
val UI_MODE = intPreferencesKey(Constants.UI_MODE)
val SCHEDULE = intPreferencesKey(Constants.SCHEDULE)
val REMINDERS_ENABLED = booleanPreferencesKey(Constants.REMINDERS_ENABLED)
}

private const val TAG = "SettingsManagerImpl"
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/java/com/omo/rememberme/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ import com.omo.rememberme.domain.usecases.people.InsertNewPerson
import com.omo.rememberme.domain.usecases.people.PeopleUseCases
import com.omo.rememberme.domain.usecases.people.UpdatePerson
import com.omo.rememberme.domain.usecases.reminders.GetSchedule
import com.omo.rememberme.domain.usecases.reminders.IsNotificationEnabled
import com.omo.rememberme.domain.usecases.reminders.ReminderUseCases
import com.omo.rememberme.domain.usecases.reminders.SetNotificationEnabled
import com.omo.rememberme.domain.usecases.reminders.SetSchedule
import com.omo.rememberme.domain.usecases.theme.GetThemeMode
import com.omo.rememberme.domain.usecases.theme.IsDarkModeEnabled
Expand Down Expand Up @@ -130,7 +132,9 @@ object AppModule {
): ReminderUseCases {
return ReminderUseCases(
getSchedule = GetSchedule(settingsManager),
setSchedule = SetSchedule(settingsManager)
setSchedule = SetSchedule(settingsManager),
setNotificationEnabled = SetNotificationEnabled(settingsManager),
isNotificationEnabled = IsNotificationEnabled(settingsManager)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ interface SettingsManager {
suspend fun isDarkModeEnabled(): Flow<Boolean>
suspend fun getSchedules(): Flow<RemindersRepetition>
suspend fun setSchedules(schedules: RemindersRepetition)
suspend fun saveNotificationStatus(enabled: Boolean)
suspend fun isNotificationEnabled(): Flow<Boolean>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.omo.rememberme.domain.usecases.reminders

import com.omo.rememberme.domain.manager.SettingsManager
import kotlinx.coroutines.flow.Flow

class IsNotificationEnabled(private val settingsManager: SettingsManager) {
suspend operator fun invoke(): Flow<Boolean> {
return settingsManager.isNotificationEnabled()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ package com.omo.rememberme.domain.usecases.reminders

data class ReminderUseCases(
val setSchedule: SetSchedule,
val getSchedule: GetSchedule
val getSchedule: GetSchedule,
val setNotificationEnabled: SetNotificationEnabled,
val isNotificationEnabled: IsNotificationEnabled

)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.omo.rememberme.domain.usecases.reminders

import com.omo.rememberme.domain.manager.SettingsManager

class SetNotificationEnabled(private val settingsManager: SettingsManager) {
suspend operator fun invoke(enabled: Boolean) {
settingsManager.saveNotificationStatus(enabled)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ sealed class SettingsEvent {
data object GetTheme : SettingsEvent()
data class ChangeRemindersRepetition(val repetition: RemindersRepetition) : SettingsEvent()
data object GetRemindersRepetition : SettingsEvent()
data object LoadNotificationsStatus: SettingsEvent()
data class ToggleNotifications(val enabled: Boolean) : SettingsEvent()
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
Expand All @@ -22,6 +23,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -57,6 +59,9 @@ fun SettingsScreen(
},
onRepetitionSelected = { repetition ->
viewModel.onEvent(SettingsEvent.ChangeRemindersRepetition(repetition))
},
onNotificationStatusChanged = { isEnabled: Boolean ->
viewModel.onEvent(SettingsEvent.ToggleNotifications(isEnabled))
}
)
}
Expand All @@ -68,7 +73,8 @@ fun SettingsScreenContent(
onBackClick: () -> Unit = {},
state: SettingsUiState,
onThemeSelected: (ThemeMode) -> Unit,
onRepetitionSelected: (RemindersRepetition) -> Unit
onRepetitionSelected: (RemindersRepetition) -> Unit,
onNotificationStatusChanged: (Boolean) -> Unit
) {
var showThemeDialog by rememberSaveable { mutableStateOf(false) }
var showRepetitionDialog by rememberSaveable { mutableStateOf(false) }
Expand Down Expand Up @@ -129,6 +135,30 @@ fun SettingsScreenContent(
Text(text = state.remindersRepetition.toString())
},
)
ListItem(
modifier = Modifier,
headlineContent = {
Text(text = "Enable Reminders")
},
leadingContent = {
Icon(
imageVector = Icons.Default.CheckCircle,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
},
supportingContent = {
Text(text = state.remindersRepetition.toString())
},
trailingContent = {
Switch(
checked = state.notificationsEnabled,
onCheckedChange = {onNotificationStatusChanged(
state.notificationsEnabled.not()
)}
)
}
)
}
}
ThemeSelectionDialog(
Expand Down Expand Up @@ -292,7 +322,8 @@ fun SettingsScreenPreview() {
remindersRepetition = RemindersRepetition.OnceADay
),
onThemeSelected = {},
onRepetitionSelected = {}
onRepetitionSelected = {},
onNotificationStatusChanged = { }
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ import com.omo.rememberme.domain.model.ThemeMode

data class SettingsUiState(
val theme: ThemeMode = ThemeMode.SYSTEM,
val remindersRepetition: RemindersRepetition = RemindersRepetition.OnceADay
val remindersRepetition: RemindersRepetition = RemindersRepetition.OnceADay,
val notificationsEnabled: Boolean = false,
)
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class SettingsViewModel @Inject constructor(
Log.d(TAG, "ViewModel initialized")
getCurrentTheme()
getCurrentRemindersRepetition()
loadNotificationStatus()
}

fun onEvent(event: SettingsEvent) {
Expand All @@ -47,6 +48,12 @@ class SettingsViewModel @Inject constructor(
Log.d(TAG, "onEvent: GetRemindersRepetition")
getCurrentRemindersRepetition()
}
is SettingsEvent.LoadNotificationsStatus -> {
loadNotificationStatus()
}
is SettingsEvent.ToggleNotifications -> {
toggleNotification(event.enabled)
}
}
}

Expand Down Expand Up @@ -89,6 +96,26 @@ class SettingsViewModel @Inject constructor(
}
}

private fun loadNotificationStatus() {
viewModelScope.launch {
Log.d(TAG, "getCurrentNotificationsStatus: Fetching current Notifications status")

reminderUseCases.isNotificationEnabled()
.collect { isEnabled ->
Log.d(TAG, "loadNotificationStatus: Current notification status is: $isEnabled")
_uiState.update { it.copy(notificationsEnabled = isEnabled)}
}
}
}

private fun toggleNotification(isEnabled: Boolean) {
viewModelScope.launch {
reminderUseCases.setNotificationEnabled(isEnabled)
_uiState.value = _uiState.value.copy(notificationsEnabled = isEnabled)
loadNotificationStatus()
}
}

companion object {
private const val TAG = "SettingsViewModel"
}
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/omo/rememberme/utils/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ object Constants {
const val REMEMBER_ME_SETTING_NAME = "remember_me_settingS"
const val UI_MODE = "uiMode"
const val SCHEDULE = "schedule"
const val REMINDERS_ENABLED = "reminders_enabled"
const val PEOPLE_CHANNEL_ID = "people_notification_channel"
const val NOTIFICATION_ID = 0
}

0 comments on commit 1ec26fe

Please sign in to comment.