feat(ui): implement navigation between settings pages
This commit is contained in:
@@ -1,3 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Nishant Mishra
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.nsh07.pomodoro
|
package org.nsh07.pomodoro
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -11,8 +28,6 @@ import androidx.compose.runtime.LaunchedEffect
|
|||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import org.nsh07.pomodoro.ui.AppScreen
|
import org.nsh07.pomodoro.ui.AppScreen
|
||||||
import org.nsh07.pomodoro.ui.NavItem
|
|
||||||
import org.nsh07.pomodoro.ui.Screen
|
|
||||||
import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsViewModel
|
import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsViewModel
|
||||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||||
import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerViewModel
|
import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerViewModel
|
||||||
@@ -70,27 +85,4 @@ class MainActivity : ComponentActivity() {
|
|||||||
// Increase the timer loop frequency again when visible to make the progress smoother
|
// Increase the timer loop frequency again when visible to make the progress smoother
|
||||||
appContainer.appTimerRepository.timerFrequency = 10f
|
appContainer.appTimerRepository.timerFrequency = 10f
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
val screens = listOf(
|
|
||||||
NavItem(
|
|
||||||
Screen.Timer,
|
|
||||||
R.drawable.timer_outlined,
|
|
||||||
R.drawable.timer_filled,
|
|
||||||
R.string.timer
|
|
||||||
),
|
|
||||||
NavItem(
|
|
||||||
Screen.Stats,
|
|
||||||
R.drawable.monitoring,
|
|
||||||
R.drawable.monitoring_filled,
|
|
||||||
R.string.stats
|
|
||||||
),
|
|
||||||
NavItem(
|
|
||||||
Screen.Settings,
|
|
||||||
R.drawable.settings,
|
|
||||||
R.drawable.settings_filled,
|
|
||||||
R.string.settings
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2025 Nishant Mishra
|
* Copyright (c) 2025 Nishant Mishra
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* This file is part of Tomato - a minimalist pomodoro timer for Android.
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.nsh07.pomodoro.ui
|
package org.nsh07.pomodoro.ui
|
||||||
@@ -45,7 +55,6 @@ import androidx.navigation3.runtime.entryProvider
|
|||||||
import androidx.navigation3.runtime.rememberNavBackStack
|
import androidx.navigation3.runtime.rememberNavBackStack
|
||||||
import androidx.navigation3.ui.NavDisplay
|
import androidx.navigation3.ui.NavDisplay
|
||||||
import androidx.window.core.layout.WindowSizeClass
|
import androidx.window.core.layout.WindowSizeClass
|
||||||
import org.nsh07.pomodoro.MainActivity.Companion.screens
|
|
||||||
import org.nsh07.pomodoro.service.TimerService
|
import org.nsh07.pomodoro.service.TimerService
|
||||||
import org.nsh07.pomodoro.ui.settingsScreen.SettingsScreenRoot
|
import org.nsh07.pomodoro.ui.settingsScreen.SettingsScreenRoot
|
||||||
import org.nsh07.pomodoro.ui.statsScreen.StatsScreenRoot
|
import org.nsh07.pomodoro.ui.statsScreen.StatsScreenRoot
|
||||||
@@ -100,7 +109,7 @@ fun AppScreen(
|
|||||||
if (wide) ShortNavigationBarArrangement.Centered
|
if (wide) ShortNavigationBarArrangement.Centered
|
||||||
else ShortNavigationBarArrangement.EqualWeight
|
else ShortNavigationBarArrangement.EqualWeight
|
||||||
) {
|
) {
|
||||||
screens.forEach {
|
mainScreens.forEach {
|
||||||
val selected = backStack.last() == it.route
|
val selected = backStack.last() == it.route
|
||||||
ShortNavigationBarItem(
|
ShortNavigationBarItem(
|
||||||
selected = selected,
|
selected = selected,
|
||||||
@@ -131,7 +140,7 @@ fun AppScreen(
|
|||||||
SharedTransitionLayout {
|
SharedTransitionLayout {
|
||||||
NavDisplay(
|
NavDisplay(
|
||||||
backStack = backStack,
|
backStack = backStack,
|
||||||
onBack = { backStack.removeLastOrNull() },
|
onBack = backStack::removeLastOrNull,
|
||||||
transitionSpec = {
|
transitionSpec = {
|
||||||
ContentTransform(
|
ContentTransform(
|
||||||
fadeIn(motionScheme.defaultEffectsSpec()),
|
fadeIn(motionScheme.defaultEffectsSpec()),
|
||||||
@@ -213,7 +222,7 @@ fun AppScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
entry<Screen.Settings> {
|
entry<Screen.Settings.Main> {
|
||||||
SettingsScreenRoot(
|
SettingsScreenRoot(
|
||||||
modifier = modifier.padding(
|
modifier = modifier.padding(
|
||||||
start = contentPadding.calculateStartPadding(layoutDirection),
|
start = contentPadding.calculateStartPadding(layoutDirection),
|
||||||
|
|||||||
62
app/src/main/java/org/nsh07/pomodoro/ui/Navigation.kt
Normal file
62
app/src/main/java/org/nsh07/pomodoro/ui/Navigation.kt
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Nishant Mishra
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.nsh07.pomodoro.ui
|
||||||
|
|
||||||
|
import org.nsh07.pomodoro.R
|
||||||
|
|
||||||
|
val mainScreens = listOf(
|
||||||
|
NavItem(
|
||||||
|
Screen.Timer,
|
||||||
|
R.drawable.timer_outlined,
|
||||||
|
R.drawable.timer_filled,
|
||||||
|
R.string.timer
|
||||||
|
),
|
||||||
|
NavItem(
|
||||||
|
Screen.Stats,
|
||||||
|
R.drawable.monitoring,
|
||||||
|
R.drawable.monitoring_filled,
|
||||||
|
R.string.stats
|
||||||
|
),
|
||||||
|
NavItem(
|
||||||
|
Screen.Settings.Main,
|
||||||
|
R.drawable.settings,
|
||||||
|
R.drawable.settings_filled,
|
||||||
|
R.string.settings
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val settingsScreens = listOf(
|
||||||
|
SettingsNavItem(
|
||||||
|
Screen.Settings.Timer,
|
||||||
|
R.drawable.timer_filled,
|
||||||
|
R.string.timer,
|
||||||
|
listOf(R.string.durations, R.string.session_length, R.string.always_on_display)
|
||||||
|
),
|
||||||
|
SettingsNavItem(
|
||||||
|
Screen.Settings.Alarm,
|
||||||
|
R.drawable.alarm,
|
||||||
|
R.string.alarm,
|
||||||
|
listOf(R.string.alarm_sound, R.string.alarm, R.string.vibrate)
|
||||||
|
),
|
||||||
|
SettingsNavItem(
|
||||||
|
Screen.Settings.Appearance,
|
||||||
|
R.drawable.palette,
|
||||||
|
R.string.appearance,
|
||||||
|
listOf(R.string.color_scheme, R.string.theme, R.string.black_theme)
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -1,3 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Nishant Mishra
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.nsh07.pomodoro.ui
|
package org.nsh07.pomodoro.ui
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
@@ -13,7 +30,19 @@ sealed class Screen : NavKey {
|
|||||||
object AOD : Screen()
|
object AOD : Screen()
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
object Settings : Screen()
|
sealed class Settings : Screen() {
|
||||||
|
@Serializable
|
||||||
|
object Main : Settings()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
object Alarm : Settings()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
object Appearance : Settings()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
object Timer : Settings()
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
object Stats : Screen()
|
object Stats : Screen()
|
||||||
@@ -24,4 +53,11 @@ data class NavItem(
|
|||||||
@param:DrawableRes val unselectedIcon: Int,
|
@param:DrawableRes val unselectedIcon: Int,
|
||||||
@param:DrawableRes val selectedIcon: Int,
|
@param:DrawableRes val selectedIcon: Int,
|
||||||
@param:StringRes val label: Int
|
@param:StringRes val label: Int
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class SettingsNavItem(
|
||||||
|
val route: Screen.Settings,
|
||||||
|
@param:DrawableRes val icon: Int,
|
||||||
|
@param:StringRes val label: Int,
|
||||||
|
val innerSettings: List<Int>
|
||||||
|
)
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ package org.nsh07.pomodoro.ui.settingsScreen
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.fadeOut
|
||||||
|
import androidx.compose.animation.slideInHorizontally
|
||||||
|
import androidx.compose.animation.slideOutHorizontally
|
||||||
|
import androidx.compose.animation.togetherWith
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -27,10 +32,12 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.text.input.TextFieldState
|
import androidx.compose.foundation.text.input.TextFieldState
|
||||||
import androidx.compose.foundation.text.input.rememberTextFieldState
|
import androidx.compose.foundation.text.input.rememberTextFieldState
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.SliderState
|
import androidx.compose.material3.SliderState
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@@ -40,24 +47,36 @@ import androidx.compose.material3.rememberSliderState
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.tooling.preview.Devices
|
import androidx.compose.ui.tooling.preview.Devices
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import androidx.navigation3.runtime.entryProvider
|
||||||
|
import androidx.navigation3.runtime.rememberNavBackStack
|
||||||
|
import androidx.navigation3.ui.NavDisplay
|
||||||
import org.nsh07.pomodoro.R
|
import org.nsh07.pomodoro.R
|
||||||
import org.nsh07.pomodoro.service.TimerService
|
import org.nsh07.pomodoro.service.TimerService
|
||||||
|
import org.nsh07.pomodoro.ui.ClickableListItem
|
||||||
|
import org.nsh07.pomodoro.ui.Screen
|
||||||
import org.nsh07.pomodoro.ui.settingsScreen.components.AboutCard
|
import org.nsh07.pomodoro.ui.settingsScreen.components.AboutCard
|
||||||
|
import org.nsh07.pomodoro.ui.settingsScreen.screens.AlarmSettings
|
||||||
|
import org.nsh07.pomodoro.ui.settingsScreen.screens.AppearanceSettings
|
||||||
|
import org.nsh07.pomodoro.ui.settingsScreen.screens.TimerSettings
|
||||||
import org.nsh07.pomodoro.ui.settingsScreen.viewModel.PreferencesState
|
import org.nsh07.pomodoro.ui.settingsScreen.viewModel.PreferencesState
|
||||||
import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsViewModel
|
import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsViewModel
|
||||||
|
import org.nsh07.pomodoro.ui.settingsScreens
|
||||||
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
|
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
|
||||||
import org.nsh07.pomodoro.ui.theme.CustomColors.topBarColors
|
import org.nsh07.pomodoro.ui.theme.CustomColors.topBarColors
|
||||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||||
@@ -147,44 +166,122 @@ private fun SettingsScreen(
|
|||||||
onColorSchemeChange: (Color) -> Unit,
|
onColorSchemeChange: (Color) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||||
|
val backStack = rememberNavBackStack(Screen.Settings.Main)
|
||||||
|
|
||||||
Column(modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) {
|
NavDisplay(
|
||||||
TopAppBar(
|
backStack = backStack,
|
||||||
title = {
|
onBack = backStack::removeLastOrNull,
|
||||||
Text(
|
transitionSpec = {
|
||||||
stringResource(R.string.settings),
|
(slideInHorizontally(initialOffsetX = { it }))
|
||||||
style = LocalTextStyle.current.copy(
|
.togetherWith(slideOutHorizontally(targetOffsetX = { -it / 4 }) + fadeOut())
|
||||||
fontFamily = robotoFlexTopBar,
|
},
|
||||||
fontSize = 32.sp,
|
popTransitionSpec = {
|
||||||
lineHeight = 32.sp
|
(slideInHorizontally(initialOffsetX = { -it / 4 }) + fadeIn())
|
||||||
|
.togetherWith(slideOutHorizontally(targetOffsetX = { it }))
|
||||||
|
},
|
||||||
|
predictivePopTransitionSpec = {
|
||||||
|
(slideInHorizontally(initialOffsetX = { -it / 4 }) + fadeIn())
|
||||||
|
.togetherWith(slideOutHorizontally(targetOffsetX = { it }))
|
||||||
|
},
|
||||||
|
entryProvider = entryProvider {
|
||||||
|
entry<Screen.Settings.Main> {
|
||||||
|
Column(modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) {
|
||||||
|
TopAppBar(
|
||||||
|
title = {
|
||||||
|
Text(
|
||||||
|
stringResource(R.string.settings),
|
||||||
|
style = LocalTextStyle.current.copy(
|
||||||
|
fontFamily = robotoFlexTopBar,
|
||||||
|
fontSize = 32.sp,
|
||||||
|
lineHeight = 32.sp
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
subtitle = {},
|
||||||
|
colors = topBarColors,
|
||||||
|
titleHorizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
scrollBehavior = scrollBehavior
|
||||||
)
|
)
|
||||||
|
|
||||||
|
LazyColumn(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||||
|
modifier = Modifier
|
||||||
|
.background(topBarColors.containerColor)
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
) {
|
||||||
|
item { Spacer(Modifier.height(12.dp)) }
|
||||||
|
|
||||||
|
item { AboutCard() }
|
||||||
|
|
||||||
|
item { Spacer(Modifier.height(12.dp)) }
|
||||||
|
|
||||||
|
itemsIndexed(settingsScreens) { index, item ->
|
||||||
|
ClickableListItem(
|
||||||
|
leadingContent = {
|
||||||
|
Icon(painterResource(item.icon), null)
|
||||||
|
},
|
||||||
|
headlineContent = { Text(stringResource(item.label)) },
|
||||||
|
supportingContent = {
|
||||||
|
Text(
|
||||||
|
remember {
|
||||||
|
item.innerSettings.joinToString(", ") {
|
||||||
|
context.getString(it)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
},
|
||||||
|
trailingContent = {
|
||||||
|
Icon(painterResource(R.drawable.arrow_forward_big), null)
|
||||||
|
},
|
||||||
|
items = settingsScreens.size,
|
||||||
|
index = index
|
||||||
|
) { backStack.add(item.route) }
|
||||||
|
}
|
||||||
|
|
||||||
|
item { Spacer(Modifier.height(12.dp)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<Screen.Settings.Alarm> {
|
||||||
|
AlarmSettings(
|
||||||
|
preferencesState = preferencesState,
|
||||||
|
alarmEnabled = alarmEnabled,
|
||||||
|
vibrateEnabled = vibrateEnabled,
|
||||||
|
alarmSound = alarmSound,
|
||||||
|
onAlarmEnabledChange = onAlarmEnabledChange,
|
||||||
|
onVibrateEnabledChange = onVibrateEnabledChange,
|
||||||
|
onAlarmSoundChanged = onAlarmSoundChanged,
|
||||||
|
onBack = backStack::removeLastOrNull
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
subtitle = {},
|
entry<Screen.Settings.Appearance> {
|
||||||
colors = topBarColors,
|
AppearanceSettings(
|
||||||
titleHorizontalAlignment = Alignment.CenterHorizontally,
|
preferencesState = preferencesState,
|
||||||
scrollBehavior = scrollBehavior
|
onBlackThemeChange = onBlackThemeChange,
|
||||||
)
|
onThemeChange = onThemeChange,
|
||||||
|
onColorSchemeChange = onColorSchemeChange,
|
||||||
LazyColumn(
|
onBack = backStack::removeLastOrNull
|
||||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
)
|
||||||
modifier = Modifier
|
}
|
||||||
.background(topBarColors.containerColor)
|
entry<Screen.Settings.Timer> {
|
||||||
.fillMaxSize()
|
TimerSettings(
|
||||||
.padding(horizontal = 16.dp)
|
aodEnabled = preferencesState.aodEnabled,
|
||||||
) {
|
focusTimeInputFieldState = focusTimeInputFieldState,
|
||||||
item { Spacer(Modifier.height(12.dp)) }
|
shortBreakTimeInputFieldState = shortBreakTimeInputFieldState,
|
||||||
|
longBreakTimeInputFieldState = longBreakTimeInputFieldState,
|
||||||
item { AboutCard() }
|
sessionsSliderState = sessionsSliderState,
|
||||||
|
onAodEnabledChange = onAodEnabledChange,
|
||||||
item { Spacer(Modifier.height(12.dp)) }
|
onBack = backStack::removeLastOrNull
|
||||||
|
)
|
||||||
item {}
|
}
|
||||||
|
|
||||||
item { Spacer(Modifier.height(12.dp)) }
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
|||||||
@@ -151,10 +151,10 @@ fun AlarmSettings(
|
|||||||
Column(modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) {
|
Column(modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) {
|
||||||
LargeFlexibleTopAppBar(
|
LargeFlexibleTopAppBar(
|
||||||
title = {
|
title = {
|
||||||
Text("Alarm", fontFamily = robotoFlexTopBar)
|
Text(stringResource(R.string.alarm), fontFamily = robotoFlexTopBar)
|
||||||
},
|
},
|
||||||
subtitle = {
|
subtitle = {
|
||||||
Text("Settings")
|
Text(stringResource(R.string.settings))
|
||||||
},
|
},
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onBack) {
|
IconButton(onBack) {
|
||||||
@@ -241,12 +241,7 @@ fun AlarmSettings(
|
|||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun AlarmSettingsPreview() {
|
fun AlarmSettingsPreview() {
|
||||||
val preferencesState = PreferencesState(
|
val preferencesState = PreferencesState()
|
||||||
theme = "auto",
|
|
||||||
colorScheme = "White",
|
|
||||||
blackTheme = false,
|
|
||||||
aodEnabled = false
|
|
||||||
)
|
|
||||||
AlarmSettings(
|
AlarmSettings(
|
||||||
preferencesState = preferencesState,
|
preferencesState = preferencesState,
|
||||||
alarmEnabled = true,
|
alarmEnabled = true,
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
@@ -70,8 +69,6 @@ fun AppearanceSettings(
|
|||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
val themeMap: Map<String, Pair<Int, Int>> = remember {
|
val themeMap: Map<String, Pair<Int, Int>> = remember {
|
||||||
mapOf(
|
mapOf(
|
||||||
"auto" to Pair(
|
"auto" to Pair(
|
||||||
@@ -82,23 +79,21 @@ fun AppearanceSettings(
|
|||||||
"dark" to Pair(R.drawable.dark_mode, R.string.dark)
|
"dark" to Pair(R.drawable.dark_mode, R.string.dark)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val reverseThemeMap: Map<String, String> = remember {
|
val reverseThemeMap: Map<String, String> = mapOf(
|
||||||
mapOf(
|
stringResource(R.string.system_default) to "auto",
|
||||||
context.getString(R.string.system_default) to "auto",
|
stringResource(R.string.light) to "light",
|
||||||
context.getString(R.string.light) to "light",
|
stringResource(R.string.dark) to "dark"
|
||||||
context.getString(R.string.dark) to "dark"
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||||
|
|
||||||
Column(modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) {
|
Column(modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) {
|
||||||
LargeFlexibleTopAppBar(
|
LargeFlexibleTopAppBar(
|
||||||
title = {
|
title = {
|
||||||
Text("Appearance", fontFamily = robotoFlexTopBar)
|
Text(stringResource(R.string.appearance), fontFamily = robotoFlexTopBar)
|
||||||
},
|
},
|
||||||
subtitle = {
|
subtitle = {
|
||||||
Text("Settings")
|
Text(stringResource(R.string.settings))
|
||||||
},
|
},
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onBack) {
|
IconButton(onBack) {
|
||||||
|
|||||||
@@ -93,10 +93,10 @@ fun TimerSettings(
|
|||||||
Column(modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) {
|
Column(modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) {
|
||||||
LargeFlexibleTopAppBar(
|
LargeFlexibleTopAppBar(
|
||||||
title = {
|
title = {
|
||||||
Text("Timer", fontFamily = robotoFlexTopBar)
|
Text(stringResource(R.string.timer), fontFamily = robotoFlexTopBar)
|
||||||
},
|
},
|
||||||
subtitle = {
|
subtitle = {
|
||||||
Text("Settings")
|
Text(stringResource(R.string.settings))
|
||||||
},
|
},
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onBack) {
|
IconButton(onBack) {
|
||||||
|
|||||||
26
app/src/main/res/drawable/arrow_forward_big.xml
Normal file
26
app/src/main/res/drawable/arrow_forward_big.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<!--
|
||||||
|
~ Copyright (c) 2025 Nishant Mishra
|
||||||
|
~
|
||||||
|
~ 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 <https://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960">
|
||||||
|
<path
|
||||||
|
android:fillColor="#e3e3e3"
|
||||||
|
android:pathData="m321,880 l-71,-71 329,-329 -329,-329 71,-71 400,400L321,880Z" />
|
||||||
|
</vector>
|
||||||
@@ -1,3 +1,20 @@
|
|||||||
|
<!--
|
||||||
|
~ Copyright (c) 2025 Nishant Mishra
|
||||||
|
~
|
||||||
|
~ 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 <https://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
<string name="alarm">Alarm</string>
|
<string name="alarm">Alarm</string>
|
||||||
<string name="alarm_desc">Ring alarm when a timer completes</string>
|
<string name="alarm_desc">Ring alarm when a timer completes</string>
|
||||||
@@ -59,4 +76,6 @@
|
|||||||
<string name="vibrate">Vibrate</string>
|
<string name="vibrate">Vibrate</string>
|
||||||
<string name="vibrate_desc">Vibrate when a timer completes</string>
|
<string name="vibrate_desc">Vibrate when a timer completes</string>
|
||||||
<string name="weekly_productivity_analysis">Weekly productivity analysis</string>
|
<string name="weekly_productivity_analysis">Weekly productivity analysis</string>
|
||||||
|
<string name="appearance">Appearance</string>
|
||||||
|
<string name="durations">Durations</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user