Skip to content

Commit

Permalink
Merge pull request #73 from omer358/dev
Browse files Browse the repository at this point in the history
resolves #72
  • Loading branch information
omer358 authored Sep 22, 2024
2 parents ce1f2c7 + 1ec26fe commit 9c88fc9
Show file tree
Hide file tree
Showing 14 changed files with 154 additions and 16 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 @@ -12,18 +12,22 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
Expand All @@ -47,7 +51,7 @@ fun OnBoardingScreenContent(
onBoardingEvent: (OnBoardingEvent) -> Unit = {},
) {
Column(
modifier = modifier.fillMaxSize(),
modifier = modifier.fillMaxSize().navigationBarsPadding().systemBarsPadding(),
horizontalAlignment = Alignment.CenterHorizontally
) {
val pagerState = rememberPagerState(initialPage = 0) {
Expand All @@ -63,6 +67,17 @@ fun OnBoardingScreenContent(
}
}
}
TextButton(
onClick = { onBoardingEvent(OnBoardingEvent.SaveAppEntry) },
modifier = Modifier.align(Alignment.End)) {
Text(
text = "Skip",
style = TextStyle(
fontSize = MaterialTheme.typography.bodyLarge.fontSize,
)
)

}
HorizontalPager(state = pagerState) { index ->
OnBoardingPage(page = pages[index])

Expand Down
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 9c88fc9

Please sign in to comment.