diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3f3f018..62a7ee8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,6 +18,7 @@ + diff --git a/app/src/main/java/org/nsh07/pomodoro/data/AppContainer.kt b/app/src/main/java/org/nsh07/pomodoro/data/AppContainer.kt index f36a179..4ca23c9 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/AppContainer.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/AppContainer.kt @@ -17,6 +17,7 @@ package org.nsh07.pomodoro.data +import android.app.NotificationManager import android.app.PendingIntent import android.content.Context import androidx.compose.ui.graphics.Color @@ -34,6 +35,7 @@ interface AppContainer { val appStatRepository: AppStatRepository val appTimerRepository: AppTimerRepository val notificationManager: NotificationManagerCompat + val notificationManagerService: NotificationManager val notificationBuilder: NotificationCompat.Builder val timerState: MutableStateFlow val time: MutableStateFlow @@ -56,6 +58,9 @@ class DefaultAppContainer(context: Context) : AppContainer { NotificationManagerCompat.from(context) } + override val notificationManagerService: NotificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + override val notificationBuilder: NotificationCompat.Builder by lazy { NotificationCompat.Builder(context, "timer") .setSmallIcon(R.drawable.tomato_logo_notification) diff --git a/app/src/main/java/org/nsh07/pomodoro/data/TimerRepository.kt b/app/src/main/java/org/nsh07/pomodoro/data/TimerRepository.kt index a7a7b46..788d1af 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/TimerRepository.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/TimerRepository.kt @@ -1,8 +1,18 @@ /* * Copyright (c) 2025 Nishant Mishra * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * This file is part of Tomato - a minimalist pomodoro timer for Android. + * + * Tomato is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * Tomato is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Tomato. + * If not, see . */ package org.nsh07.pomodoro.data @@ -27,6 +37,7 @@ interface TimerRepository { var alarmEnabled: Boolean var vibrateEnabled: Boolean + var dndEnabled: Boolean var colorScheme: ColorScheme @@ -46,6 +57,7 @@ class AppTimerRepository : TimerRepository { override var timerFrequency: Float = 10f override var alarmEnabled = true override var vibrateEnabled = true + override var dndEnabled: Boolean = false override var colorScheme = lightColorScheme() override var alarmSoundUri: Uri? = Settings.System.DEFAULT_ALARM_ALERT_URI ?: Settings.System.DEFAULT_RINGTONE_URI diff --git a/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt b/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt index b2423d1..8932c50 100644 --- a/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt +++ b/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt @@ -18,6 +18,7 @@ package org.nsh07.pomodoro.service import android.annotation.SuppressLint +import android.app.NotificationManager import android.app.Service import android.content.Intent import android.media.AudioAttributes @@ -30,7 +31,6 @@ import android.os.Vibrator import android.os.VibratorManager import androidx.compose.ui.graphics.toArgb import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationManagerCompat import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -53,7 +53,8 @@ class TimerService : Service() { private val timerRepository by lazy { appContainer.appTimerRepository } private val statRepository by lazy { appContainer.appStatRepository } - private val notificationManager by lazy { NotificationManagerCompat.from(this) } + private val notificationManager by lazy { appContainer.notificationManager } + private val notificationManagerService by lazy { appContainer.notificationManagerService } private val notificationBuilder by lazy { appContainer.notificationBuilder } private val _timerState by lazy { appContainer.timerState } private val _time by lazy { appContainer.time } @@ -106,6 +107,7 @@ class TimerService : Service() { runBlocking { job.cancel() saveTimeToDb() + setDoNotDisturb(false) notificationManager.cancel(1) alarm?.release() } @@ -127,7 +129,7 @@ class TimerService : Service() { } } - Actions.SKIP.toString() -> skipTimer(true) + Actions.SKIP.toString() -> skipScope.launch { skipTimer(true) } Actions.STOP_ALARM.toString() -> stopAlarm() @@ -140,6 +142,7 @@ class TimerService : Service() { updateProgressSegments() if (timerState.value.timerRunning) { + setDoNotDisturb(false) notificationBuilder.clearActions().addTimerActions( this, R.drawable.play, getString(R.string.start) ) @@ -149,6 +152,8 @@ class TimerService : Service() { } pauseTime = SystemClock.elapsedRealtime() } else { + if (timerState.value.timerMode == TimerMode.FOCUS) setDoNotDisturb(true) + else setDoNotDisturb(false) notificationBuilder.clearActions().addTimerActions( this, R.drawable.pause, getString(R.string.stop) ) @@ -324,48 +329,48 @@ class TimerService : Service() { } } - private fun skipTimer(fromButton: Boolean = false) { + private suspend fun skipTimer(fromButton: Boolean = false) { updateProgressSegments() - skipScope.launch { - saveTimeToDb() - updateProgressSegments() - showTimerNotification(0, paused = true, complete = !fromButton) - startTime = 0L - pauseTime = 0L - pauseDuration = 0L + saveTimeToDb() + updateProgressSegments() + showTimerNotification(0, paused = true, complete = !fromButton) + startTime = 0L + pauseTime = 0L + pauseDuration = 0L - cycles = (cycles + 1) % (timerRepository.sessionLength * 2) + cycles = (cycles + 1) % (timerRepository.sessionLength * 2) - if (cycles % 2 == 0) { - time = timerRepository.focusTime - _timerState.update { currentState -> - currentState.copy( - timerMode = TimerMode.FOCUS, - timeStr = millisecondsToStr(time), - totalTime = time, - nextTimerMode = if (cycles == (timerRepository.sessionLength - 1) * 2) TimerMode.LONG_BREAK else TimerMode.SHORT_BREAK, - nextTimeStr = if (cycles == (timerRepository.sessionLength - 1) * 2) millisecondsToStr( - timerRepository.longBreakTime - ) else millisecondsToStr( - timerRepository.shortBreakTime - ), - currentFocusCount = cycles / 2 + 1, - totalFocusCount = timerRepository.sessionLength - ) - } - } else { - val long = cycles == (timerRepository.sessionLength * 2) - 1 - time = if (long) timerRepository.longBreakTime else timerRepository.shortBreakTime + if (cycles % 2 == 0) { + if (timerState.value.timerRunning) setDoNotDisturb(true) + time = timerRepository.focusTime + _timerState.update { currentState -> + currentState.copy( + timerMode = TimerMode.FOCUS, + timeStr = millisecondsToStr(time), + totalTime = time, + nextTimerMode = if (cycles == (timerRepository.sessionLength - 1) * 2) TimerMode.LONG_BREAK else TimerMode.SHORT_BREAK, + nextTimeStr = if (cycles == (timerRepository.sessionLength - 1) * 2) millisecondsToStr( + timerRepository.longBreakTime + ) else millisecondsToStr( + timerRepository.shortBreakTime + ), + currentFocusCount = cycles / 2 + 1, + totalFocusCount = timerRepository.sessionLength + ) + } + } else { + if (timerState.value.timerRunning) setDoNotDisturb(false) + val long = cycles == (timerRepository.sessionLength * 2) - 1 + time = if (long) timerRepository.longBreakTime else timerRepository.shortBreakTime - _timerState.update { currentState -> - currentState.copy( - timerMode = if (long) TimerMode.LONG_BREAK else TimerMode.SHORT_BREAK, - timeStr = millisecondsToStr(time), - totalTime = time, - nextTimerMode = TimerMode.FOCUS, - nextTimeStr = millisecondsToStr(timerRepository.focusTime) - ) - } + _timerState.update { currentState -> + currentState.copy( + timerMode = if (long) TimerMode.LONG_BREAK else TimerMode.SHORT_BREAK, + timeStr = millisecondsToStr(time), + totalTime = time, + nextTimerMode = TimerMode.FOCUS, + nextTimeStr = millisecondsToStr(timerRepository.focusTime) + ) } } } @@ -441,7 +446,15 @@ class TimerService : Service() { } } - fun updateAlarmTone() { + private fun setDoNotDisturb(doNotDisturb: Boolean) { + if (timerRepository.dndEnabled && notificationManagerService.isNotificationPolicyAccessGranted()) { + if (doNotDisturb) { + notificationManagerService.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALARMS) + } else notificationManagerService.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL) + } + } + + private fun updateAlarmTone() { alarm?.release() alarm = initializeMediaPlayer() } diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/SettingsScreen.kt b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/SettingsScreen.kt index 512df9a..a22b1f5 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/SettingsScreen.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/SettingsScreen.kt @@ -104,6 +104,7 @@ fun SettingsScreenRoot( val alarmEnabled by viewModel.alarmEnabled.collectAsStateWithLifecycle(true) val vibrateEnabled by viewModel.vibrateEnabled.collectAsStateWithLifecycle(true) + val dndEnabled by viewModel.dndEnabled.collectAsStateWithLifecycle(false) val alarmSound by viewModel.alarmSound.collectAsStateWithLifecycle(viewModel.currentAlarmSound) val preferencesState by viewModel.preferencesState.collectAsStateWithLifecycle() @@ -126,11 +127,13 @@ fun SettingsScreenRoot( sessionsSliderState = sessionsSliderState, alarmEnabled = alarmEnabled, vibrateEnabled = vibrateEnabled, + dndEnabled = dndEnabled, alarmSound = alarmSound, onAlarmEnabledChange = viewModel::saveAlarmEnabled, onVibrateEnabledChange = viewModel::saveVibrateEnabled, onBlackThemeChange = viewModel::saveBlackTheme, onAodEnabledChange = viewModel::saveAodEnabled, + onDndEnabledChange = viewModel::saveDndEnabled, onAlarmSoundChanged = { viewModel.saveAlarmSound(it) Intent(context, TimerService::class.java).apply { @@ -155,11 +158,13 @@ private fun SettingsScreen( sessionsSliderState: SliderState, alarmEnabled: Boolean, vibrateEnabled: Boolean, + dndEnabled: Boolean, alarmSound: String, onAlarmEnabledChange: (Boolean) -> Unit, onVibrateEnabledChange: (Boolean) -> Unit, onBlackThemeChange: (Boolean) -> Unit, onAodEnabledChange: (Boolean) -> Unit, + onDndEnabledChange: (Boolean) -> Unit, onAlarmSoundChanged: (Uri?) -> Unit, onThemeChange: (String) -> Unit, onColorSchemeChange: (Color) -> Unit, @@ -270,11 +275,13 @@ private fun SettingsScreen( entry { TimerSettings( aodEnabled = preferencesState.aodEnabled, + dndEnabled = dndEnabled, focusTimeInputFieldState = focusTimeInputFieldState, shortBreakTimeInputFieldState = shortBreakTimeInputFieldState, longBreakTimeInputFieldState = longBreakTimeInputFieldState, sessionsSliderState = sessionsSliderState, onAodEnabledChange = onAodEnabledChange, + onDndEnabledChange = onDndEnabledChange, onBack = backStack::removeLastOrNull ) } diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/components/AboutCard.kt b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/components/AboutCard.kt index fe0e1ce..3bf2f6c 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/components/AboutCard.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/components/AboutCard.kt @@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.FlowRow 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.layout.size import androidx.compose.material3.Button @@ -123,8 +124,9 @@ fun AboutCard(modifier: Modifier = Modifier) { verticalAlignment = Alignment.CenterVertically ) { Icon( - painterResource(R.drawable.coffee), + painterResource(R.drawable.bmc), contentDescription = "Buy me a coffee", + modifier = Modifier.height(24.dp) ) Text(text = "Buy me a coffee") diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/TimerSettings.kt b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/TimerSettings.kt index 01dddba..421140c 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/TimerSettings.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/screens/TimerSettings.kt @@ -17,6 +17,11 @@ package org.nsh07.pomodoro.ui.settingsScreen.screens +import android.app.NotificationManager +import android.content.Context +import android.content.Intent +import android.provider.Settings +import android.widget.Toast import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.background import androidx.compose.foundation.horizontalScroll @@ -31,6 +36,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.input.TextFieldState @@ -51,6 +57,7 @@ import androidx.compose.material3.SwitchDefaults import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -59,6 +66,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.ImeAction @@ -76,19 +84,58 @@ import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.cardShape import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.middleListItemShape import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.topListItemShape + @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @Composable fun TimerSettings( aodEnabled: Boolean, + dndEnabled: Boolean, focusTimeInputFieldState: TextFieldState, shortBreakTimeInputFieldState: TextFieldState, longBreakTimeInputFieldState: TextFieldState, sessionsSliderState: SliderState, onAodEnabledChange: (Boolean) -> Unit, + onDndEnabledChange: (Boolean) -> Unit, onBack: () -> Unit, modifier: Modifier = Modifier ) { val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() + val context = LocalContext.current + val appName = stringResource(R.string.app_name) + val notificationManagerService = + remember { context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager } + + LaunchedEffect(Unit) { + if (!notificationManagerService.isNotificationPolicyAccessGranted()) + onDndEnabledChange(false) + } + + val switchItems = listOf( + SettingsSwitchItem( + checked = dndEnabled, + icon = R.drawable.dnd, + label = R.string.dnd, + description = R.string.dnd_desc, + onClick = { + if (it && !notificationManagerService.isNotificationPolicyAccessGranted()) { + val intent = Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS) + Toast.makeText(context, "Enable permission for \"$appName\"", Toast.LENGTH_LONG) + .show() + context.startActivity(intent) + } else if (!it && notificationManagerService.isNotificationPolicyAccessGranted()) { + notificationManagerService.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL) + } + onDndEnabledChange(it) + } + ), + SettingsSwitchItem( + checked = aodEnabled, + icon = R.drawable.aod, + label = R.string.always_on_display, + description = R.string.always_on_display_desc, + onClick = onAodEnabledChange + ) + ) Column(modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) { LargeFlexibleTopAppBar( @@ -213,14 +260,7 @@ fun TimerSettings( ) } item { Spacer(Modifier.height(12.dp)) } - item { - val item = SettingsSwitchItem( - checked = aodEnabled, - icon = R.drawable.aod, - label = R.string.always_on_display, - description = R.string.always_on_display_desc, - onClick = onAodEnabledChange - ) + itemsIndexed(switchItems) { index, item -> ListItem( leadingContent = { Icon( @@ -254,7 +294,13 @@ fun TimerSettings( ) }, colors = listItemColors, - modifier = Modifier.clip(cardShape) + modifier = Modifier.clip( + when (index) { + 0 -> topListItemShape + switchItems.size - 1 -> bottomListItemShape + else -> middleListItemShape + } + ) ) } @@ -311,7 +357,9 @@ private fun TimerSettingsPreview() { longBreakTimeInputFieldState = longBreakTimeInputFieldState, sessionsSliderState = sessionsSliderState, aodEnabled = true, + dndEnabled = false, onBack = {}, - onAodEnabledChange = {} + onAodEnabledChange = {}, + onDndEnabledChange = {} ) } \ No newline at end of file diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsViewModel.kt b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsViewModel.kt index 76ebb8c..0a3262f 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsViewModel.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/settingsScreen/viewModel/SettingsViewModel.kt @@ -85,6 +85,8 @@ class SettingsViewModel( preferenceRepository.getBooleanPreferenceFlow("alarm_enabled").distinctUntilChanged() val vibrateEnabled = preferenceRepository.getBooleanPreferenceFlow("vibrate_enabled").distinctUntilChanged() + val dndEnabled = + preferenceRepository.getBooleanPreferenceFlow("dnd_enabled").distinctUntilChanged() init { viewModelScope.launch { @@ -179,6 +181,13 @@ class SettingsViewModel( } } + fun saveDndEnabled(enabled: Boolean) { + viewModelScope.launch { + timerRepository.dndEnabled = enabled + preferenceRepository.saveBooleanPreference("dnd_enabled", enabled) + } + } + fun saveAlarmSound(uri: Uri?) { viewModelScope.launch { timerRepository.alarmSoundUri = uri diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt b/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt index 68b9094..ee77820 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt @@ -1,8 +1,18 @@ /* * Copyright (c) 2025 Nishant Mishra * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * This file is part of Tomato - a minimalist pomodoro timer for Android. + * + * Tomato is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * Tomato is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Tomato. + * If not, see . */ package org.nsh07.pomodoro.ui.timerScreen @@ -92,6 +102,7 @@ import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerAction import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerMode import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerState + @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @Composable fun SharedTransitionScope.TimerScreen( diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/viewModel/TimerViewModel.kt b/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/viewModel/TimerViewModel.kt index 53c23b5..2c4e493 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/viewModel/TimerViewModel.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/viewModel/TimerViewModel.kt @@ -1,8 +1,18 @@ /* * Copyright (c) 2025 Nishant Mishra * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * This file is part of Tomato - a minimalist pomodoro timer for Android. + * + * Tomato is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * Tomato is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Tomato. + * If not, see . */ package org.nsh07.pomodoro.ui.timerScreen.viewModel @@ -85,6 +95,9 @@ class TimerViewModel( timerRepository.vibrateEnabled = preferenceRepository.getBooleanPreference("vibrate_enabled") ?: preferenceRepository.saveBooleanPreference("vibrate_enabled", true) + timerRepository.dndEnabled = + preferenceRepository.getBooleanPreference("dnd_enabled") + ?: preferenceRepository.saveBooleanPreference("dnd_enabled", false) timerRepository.alarmSoundUri = ( preferenceRepository.getStringPreference("alarm_sound") diff --git a/app/src/main/res/drawable/bmc.xml b/app/src/main/res/drawable/bmc.xml new file mode 100644 index 0000000..110fa4b --- /dev/null +++ b/app/src/main/res/drawable/bmc.xml @@ -0,0 +1,30 @@ + + + + + + diff --git a/app/src/main/res/drawable/coffee.xml b/app/src/main/res/drawable/coffee.xml deleted file mode 100644 index 05b913c..0000000 --- a/app/src/main/res/drawable/coffee.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/dnd.xml b/app/src/main/res/drawable/dnd.xml new file mode 100644 index 0000000..16113b4 --- /dev/null +++ b/app/src/main/res/drawable/dnd.xml @@ -0,0 +1,26 @@ + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cf51e15..f4c25b8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -79,4 +79,6 @@ Appearance Durations Sound + Do Not Disturb + Turn on DND when running a Focus timer \ No newline at end of file