feat(ui): add about screen list item in settings, remove card

Closes: #160
This commit is contained in:
Nishant Mishra
2025-12-01 10:51:07 +05:30
parent 6c32743d22
commit 9efc4f6467
9 changed files with 94 additions and 184 deletions

View File

@@ -45,18 +45,18 @@ val settingsScreens = listOf(
Screen.Settings.Timer,
R.drawable.timer_filled,
R.string.timer,
listOf(R.string.durations, R.string.session_length, R.string.always_on_display)
listOf(R.string.durations, R.string.dnd, 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)
listOf(R.string.alarm_sound, R.string.sound, 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)
listOf(R.string.theme, R.string.color_scheme, R.string.black_theme)
)
)

View File

@@ -34,6 +34,9 @@ sealed class Screen : NavKey {
@Serializable
object Main : Settings()
@Serializable
object About : Settings()
@Serializable
object Alarm : Settings()

View File

@@ -65,13 +65,14 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.ui.NavDisplay
import org.nsh07.pomodoro.BuildConfig
import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.Screen
import org.nsh07.pomodoro.ui.mergePaddingValues
import org.nsh07.pomodoro.ui.settingsScreen.components.AboutCard
import org.nsh07.pomodoro.ui.settingsScreen.components.ClickableListItem
import org.nsh07.pomodoro.ui.settingsScreen.components.LocaleBottomSheet
import org.nsh07.pomodoro.ui.settingsScreen.components.PlusPromo
import org.nsh07.pomodoro.ui.settingsScreen.screens.AboutScreen
import org.nsh07.pomodoro.ui.settingsScreen.screens.AlarmSettings
import org.nsh07.pomodoro.ui.settingsScreen.screens.AppearanceSettings
import org.nsh07.pomodoro.ui.settingsScreen.screens.TimerSettings
@@ -216,22 +217,33 @@ private fun SettingsScreen(
.fillMaxSize()
.padding(horizontal = 16.dp)
) {
item { Spacer(Modifier.height(12.dp)) }
item { Spacer(Modifier.height(14.dp)) }
if (!isPlus) item {
item {
PlusPromo(isPlus, setShowPaywall)
Spacer(Modifier.height(14.dp))
}
item { AboutCard(isPlus) }
item {
ClickableListItem(
leadingContent = {
Icon(painterResource(R.drawable.info), null)
},
headlineContent = {
Text(stringResource(R.string.about))
},
supportingContent = {
Text(stringResource(R.string.app_name) + " ${BuildConfig.VERSION_NAME}")
},
trailingContent = {
Icon(painterResource(R.drawable.arrow_forward_big), null)
},
items = 2,
index = 1
) { backStack.add(Screen.Settings.About) }
}
item { Spacer(Modifier.height(12.dp)) }
if (isPlus) item {
PlusPromo(isPlus, setShowPaywall)
Spacer(Modifier.height(14.dp))
}
itemsIndexed(settingsScreens) { index, item ->
ClickableListItem(
leadingContent = {
@@ -286,6 +298,14 @@ private fun SettingsScreen(
}
}
entry<Screen.Settings.About> {
AboutScreen(
contentPadding = contentPadding,
isPlus = isPlus,
onBack = backStack::removeLastOrNull
)
}
entry<Screen.Settings.Alarm> {
AlarmSettings(
settingsState = settingsState,

View File

@@ -1,123 +0,0 @@
/*
* 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.settingsScreen.components
import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.MaterialTheme.shapes
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import org.nsh07.pomodoro.BuildConfig
import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
// Taken from https://github.com/shub39/Grit/blob/master/app/src/main/java/com/shub39/grit/core/presentation/settings/ui/component/AboutApp.kt
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun AboutCard(
isPlus: Boolean,
modifier: Modifier = Modifier
) {
val uriHandler = LocalUriHandler.current
val context = LocalContext.current
Card(
modifier = modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = colorScheme.primaryContainer,
contentColor = colorScheme.onPrimaryContainer
),
shape = shapes.extraLarge
) {
Row(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Column {
Text(
if (!isPlus) stringResource(R.string.app_name)
else stringResource(R.string.app_name_plus),
style = MaterialTheme.typography.titleLarge,
fontFamily = robotoFlexTopBar
)
Text(text = "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})")
}
Spacer(modifier = Modifier.weight(1f))
Row {
IconButton(
onClick = {
Toast.makeText(context, "Coming soon...", Toast.LENGTH_SHORT).show()
},
shapes = IconButtonDefaults.shapes()
) {
Icon(
painterResource(R.drawable.discord),
contentDescription = "Discord",
modifier = Modifier.size(24.dp)
)
}
IconButton(
onClick = { uriHandler.openUri("https://github.com/nsh07/Tomato") },
shapes = IconButtonDefaults.shapes()
) {
Icon(
painterResource(R.drawable.github),
contentDescription = "GitHub",
modifier = Modifier.size(24.dp)
)
}
}
}
FlowRow(
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
// TopButton(buttonColors)
// BottomButton(buttonColors)
}
}
}

View File

@@ -32,7 +32,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import org.nsh07.pomodoro.R
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -49,7 +51,7 @@ fun PlusDivider(
.background(colorScheme.surfaceContainer)
.padding(horizontal = 8.dp)
) {
Text("Customize further with Tomato+", style = typography.titleSmall)
Text(stringResource(R.string.tomato_plus_desc), style = typography.titleSmall)
}
}
}

View File

@@ -17,27 +17,18 @@
package org.nsh07.pomodoro.ui.settingsScreen.components
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
@Composable
fun PlusPromo(
@@ -45,38 +36,38 @@ fun PlusPromo(
setShowPaywall: (Boolean) -> Unit,
modifier: Modifier = Modifier
) {
val container = if (isPlus) colorScheme.surfaceBright else colorScheme.primary
val onContainer = if (isPlus) colorScheme.onSurface else colorScheme.onPrimary
val onContainerVariant = if (isPlus) colorScheme.onSurfaceVariant else colorScheme.onPrimary
Row(
verticalAlignment = Alignment.CenterVertically,
ClickableListItem(
leadingContent = {
Icon(
painterResource(R.drawable.tomato_logo_notification),
null,
modifier = Modifier.size(24.dp)
)
},
headlineContent = {
Text(
if (!isPlus) stringResource(R.string.get_plus)
else stringResource(R.string.app_name_plus)
)
},
supportingContent = {
if (!isPlus) Text(stringResource(R.string.tomato_plus_desc))
},
trailingContent = {
Icon(
painterResource(R.drawable.arrow_forward_big),
null
)
},
colors = if (isPlus) listItemColors else ListItemDefaults.colors(
containerColor = colorScheme.primary,
leadingIconColor = colorScheme.onPrimary,
trailingIconColor = colorScheme.onPrimary,
supportingColor = colorScheme.onPrimary,
headlineColor = colorScheme.onPrimary
),
items = 2,
index = 0,
modifier = modifier
.clip(CircleShape)
.clickable { setShowPaywall(true) }
.background(container)
.padding(16.dp)
) {
Icon(
painterResource(R.drawable.tomato_logo_notification),
null,
tint = onContainerVariant,
modifier = Modifier
.size(24.dp)
)
Spacer(Modifier.width(8.dp))
Text(
if (!isPlus) stringResource(R.string.get_plus)
else stringResource(R.string.app_name_plus),
style = typography.titleLarge,
fontFamily = robotoFlexTopBar,
color = onContainer
)
Spacer(Modifier.weight(1f))
Icon(
painterResource(R.drawable.arrow_forward_big),
null,
tint = onContainerVariant
)
}
) { setShowPaywall(true) }
}

View File

@@ -80,7 +80,7 @@ fun AboutScreen(
onBack: () -> Unit,
modifier: Modifier = Modifier
) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
val context = LocalContext.current
val uriHandler = LocalUriHandler.current

View File

@@ -1,10 +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:tint="#000000"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@android:color/white"
android:fillColor="#e3e3e3"
android:pathData="M480,680q17,0 28.5,-11.5T520,640v-160q0,-17 -11.5,-28.5T480,440q-17,0 -28.5,11.5T440,480v160q0,17 11.5,28.5T480,680ZM480,360q17,0 28.5,-11.5T520,320q0,-17 -11.5,-28.5T480,280q-17,0 -28.5,11.5T440,320q0,17 11.5,28.5T480,360ZM480,880q-83,0 -156,-31.5T197,763q-54,-54 -85.5,-127T80,480q0,-83 31.5,-156T197,197q54,-54 127,-85.5T480,80q83,0 156,31.5T763,197q54,54 85.5,127T880,480q0,83 -31.5,156T763,763q-54,54 -127,85.5T480,880Z" />
</vector>

View File

@@ -101,4 +101,5 @@
<string name="help_with_translation_desc">Translate Tomato into your language</string>
<string name="rate_on_google_play_desc">Liked the app? Write a review!</string>
<string name="bmc_desc">Support me with a small donation</string>
<string name="tomato_plus_desc">Customize further with Tomato+</string>
</resources>