feat(ui): Implement an about screen

This commit is contained in:
Nishant Mishra
2025-11-30 23:30:47 +05:30
parent 0f9f793bc5
commit 6c32743d22
18 changed files with 510 additions and 157 deletions

View File

@@ -17,18 +17,12 @@
package org.nsh07.pomodoro.ui.settingsScreen.components package org.nsh07.pomodoro.ui.settingsScreen.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@@ -38,56 +32,44 @@ import org.nsh07.pomodoro.R
@OptIn(ExperimentalMaterial3ExpressiveApi::class) @OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable @Composable
fun TopButton( fun TopButton(modifier: Modifier = Modifier) {
buttonColors: ButtonColors,
modifier: Modifier = Modifier
) {
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
Button( ClickableListItem(
colors = buttonColors, leadingContent = {
onClick = { uriHandler.openUri("https://coff.ee/nsh07") },
shapes = ButtonDefaults.shapes(),
modifier = modifier
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon( Icon(
painterResource(R.drawable.bmc), painterResource(R.drawable.bmc),
tint = colorScheme.primary,
contentDescription = null, contentDescription = null,
modifier = Modifier.height(24.dp) modifier = Modifier.size(24.dp)
) )
},
Text(text = stringResource(R.string.bmc)) headlineContent = { Text(stringResource(R.string.bmc)) },
} supportingContent = { Text(stringResource(R.string.bmc_desc)) },
} trailingContent = { Icon(painterResource(R.drawable.open_in_browser), null) },
items = 2,
index = 0,
modifier = modifier
) { uriHandler.openUri("https://coff.ee/nsh07") }
} }
@OptIn(ExperimentalMaterial3ExpressiveApi::class) @OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable @Composable
fun BottomButton( fun BottomButton(modifier: Modifier = Modifier) {
buttonColors: ButtonColors,
modifier: Modifier = Modifier
) {
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
Button( ClickableListItem(
colors = buttonColors, leadingContent = {
onClick = { uriHandler.openUri("https://hosted.weblate.org/engage/tomato/") },
shapes = ButtonDefaults.shapes(),
modifier = modifier
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon( Icon(
painterResource(R.drawable.weblate), painterResource(R.drawable.weblate),
tint = colorScheme.secondary,
contentDescription = null, contentDescription = null,
modifier = Modifier.size(20.dp) modifier = Modifier.size(24.dp)
) )
},
Text(text = stringResource(R.string.help_with_translation)) headlineContent = { Text(stringResource(R.string.help_with_translation)) },
} supportingContent = { Text(stringResource(R.string.help_with_translation_desc)) },
} trailingContent = { Icon(painterResource(R.drawable.open_in_browser), null) },
items = 2,
index = 1,
modifier = modifier
) { uriHandler.openUri("https://hosted.weblate.org/engage/tomato/") }
} }

View File

@@ -0,0 +1,39 @@
/*
* 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 androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalLayoutDirection
@Composable
fun mergePaddingValues(
topSource: PaddingValues,
restSource: PaddingValues
): PaddingValues {
val layoutDirection = LocalLayoutDirection.current
return PaddingValues(
top = topSource.calculateTopPadding(),
bottom = restSource.calculateBottomPadding(),
start = restSource.calculateStartPadding(layoutDirection),
end = restSource.calculateEndPadding(layoutDirection)
)
}

View File

@@ -29,8 +29,6 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxSize 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
@@ -58,7 +56,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
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.platform.LocalLayoutDirection
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.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
@@ -70,6 +67,7 @@ import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.ui.NavDisplay import androidx.navigation3.ui.NavDisplay
import org.nsh07.pomodoro.R import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.Screen 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.AboutCard
import org.nsh07.pomodoro.ui.settingsScreen.components.ClickableListItem import org.nsh07.pomodoro.ui.settingsScreen.components.ClickableListItem
import org.nsh07.pomodoro.ui.settingsScreen.components.LocaleBottomSheet import org.nsh07.pomodoro.ui.settingsScreen.components.LocaleBottomSheet
@@ -153,7 +151,6 @@ private fun SettingsScreen(
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val context = LocalContext.current val context = LocalContext.current
val layoutDirection = LocalLayoutDirection.current
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
val currentLocales = val currentLocales =
@@ -210,12 +207,7 @@ private fun SettingsScreen(
}, },
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection) modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
) { innerPadding -> ) { innerPadding ->
val insets = PaddingValues( val insets = mergePaddingValues(innerPadding, contentPadding)
bottom = contentPadding.calculateBottomPadding(),
top = innerPadding.calculateTopPadding(),
start = innerPadding.calculateStartPadding(layoutDirection),
end = innerPadding.calculateEndPadding(layoutDirection)
)
LazyColumn( LazyColumn(
verticalArrangement = Arrangement.spacedBy(2.dp), verticalArrangement = Arrangement.spacedBy(2.dp),
contentPadding = insets, contentPadding = insets,

View File

@@ -26,7 +26,6 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
@@ -67,11 +66,6 @@ fun AboutCard(
), ),
shape = shapes.extraLarge shape = shapes.extraLarge
) { ) {
val buttonColors = ButtonDefaults.buttonColors(
containerColor = colorScheme.onPrimaryContainer,
contentColor = colorScheme.primaryContainer
)
Row( Row(
modifier = Modifier modifier = Modifier
.padding(16.dp) .padding(16.dp)
@@ -122,8 +116,8 @@ fun AboutCard(
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp), modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp) horizontalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
TopButton(buttonColors) // TopButton(buttonColors)
BottomButton(buttonColors) // BottomButton(buttonColors)
} }
} }
} }

View File

@@ -0,0 +1,270 @@
/*
* 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.screens
import android.widget.Toast
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
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.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.LargeFlexibleTopAppBar
import androidx.compose.material3.MaterialShapes
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.toShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEach
import org.nsh07.pomodoro.BuildConfig
import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.mergePaddingValues
import org.nsh07.pomodoro.ui.settingsScreen.components.BottomButton
import org.nsh07.pomodoro.ui.settingsScreen.components.TopButton
import org.nsh07.pomodoro.ui.theme.AppFonts.googleFlex600
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
import org.nsh07.pomodoro.ui.theme.CustomColors.topBarColors
import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.bottomListItemShape
import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.topListItemShape
import org.nsh07.pomodoro.ui.theme.TomatoTheme
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun AboutScreen(
contentPadding: PaddingValues,
isPlus: Boolean,
onBack: () -> Unit,
modifier: Modifier = Modifier
) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
val context = LocalContext.current
val uriHandler = LocalUriHandler.current
val socialLinks = remember {
listOf(
SocialLink(R.drawable.github, "https://github.com/nsh07"),
SocialLink(R.drawable.x, "https://x.com/nsh_zero7"),
SocialLink(R.drawable.globe, "https://nsh07.github.io"),
SocialLink(R.drawable.email, "mailto:nishant.28@outlook.com")
)
}
Scaffold(
topBar = {
LargeFlexibleTopAppBar(
title = {
Text(stringResource(R.string.about), fontFamily = robotoFlexTopBar)
},
subtitle = {
Text(stringResource(R.string.app_name))
},
navigationIcon = {
FilledTonalIconButton(
onClick = onBack,
shapes = IconButtonDefaults.shapes(),
colors = IconButtonDefaults.filledTonalIconButtonColors(containerColor = listItemColors.containerColor)
) {
Icon(
painterResource(R.drawable.arrow_back),
null
)
}
},
colors = topBarColors,
scrollBehavior = scrollBehavior
)
},
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
) { innerPadding ->
val insets = mergePaddingValues(innerPadding, contentPadding)
LazyColumn(
verticalArrangement = Arrangement.spacedBy(2.dp),
contentPadding = insets,
modifier = Modifier
.background(topBarColors.containerColor)
.fillMaxSize()
.padding(horizontal = 16.dp)
) {
item {
Box(Modifier.background(listItemColors.containerColor, topListItemShape)) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(16.dp)
) {
Icon(
painterResource(R.drawable.ic_launcher_monochrome),
tint = colorScheme.onPrimaryContainer,
contentDescription = null,
modifier = Modifier
.size(64.dp)
.background(
colorScheme.primaryContainer,
MaterialShapes.Cookie12Sided.toShape()
)
)
Spacer(Modifier.width(16.dp))
Column {
Text(
if (!isPlus) stringResource(R.string.app_name)
else stringResource(R.string.app_name_plus),
color = colorScheme.onSurface,
style = typography.titleLarge,
fontFamily = googleFlex600
)
Text(
text = "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})",
style = typography.labelLarge,
color = colorScheme.primary
)
}
Spacer(Modifier.weight(1f))
Row(horizontalArrangement = Arrangement.spacedBy(2.dp)) {
FilledTonalIconButton(
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)
)
}
FilledTonalIconButton(
onClick = { uriHandler.openUri("https://github.com/nsh07/Tomato") },
shapes = IconButtonDefaults.shapes()
) {
Icon(
painterResource(R.drawable.github),
contentDescription = "GitHub",
modifier = Modifier.size(24.dp)
)
}
}
}
}
}
item {
Box(Modifier.background(listItemColors.containerColor, bottomListItemShape)) {
Column(modifier = Modifier.padding(16.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
painterResource(R.drawable.pfp),
tint = colorScheme.onSecondaryContainer,
contentDescription = null,
modifier = Modifier
.size(64.dp)
.background(
colorScheme.secondaryContainer,
MaterialShapes.Square.toShape()
)
.padding(8.dp)
)
Spacer(Modifier.width(16.dp))
Column {
Text(
"Nishant Mishra",
style = typography.titleLarge,
color = colorScheme.onSurface,
fontFamily = googleFlex600
)
Text(
"Developer",
style = typography.labelLarge,
color = colorScheme.secondary
)
}
Spacer(Modifier.weight(1f))
}
Spacer(Modifier.height(8.dp))
Row {
Spacer(Modifier.width((64 + 16).dp))
FlowRow(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
socialLinks.fastForEach {
FilledTonalIconButton(
onClick = { uriHandler.openUri(it.url) },
shapes = IconButtonDefaults.shapes(),
modifier = Modifier.width(52.dp)
) {
Icon(
painterResource(it.icon),
null,
modifier = Modifier.size(ButtonDefaults.SmallIconSize)
)
}
}
}
}
}
}
}
item { Spacer(Modifier.height(12.dp)) }
item { TopButton() }
item { BottomButton() }
}
}
}
@Preview
@Composable
private fun AboutScreenPreview() {
TomatoTheme(dynamicColor = false) {
AboutScreen(
contentPadding = PaddingValues(),
isPlus = true,
onBack = {}
)
}
}
data class SocialLink(
@param:DrawableRes val icon: Int,
val url: String
)

View File

@@ -30,8 +30,6 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxSize 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
@@ -60,7 +58,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
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.platform.LocalLayoutDirection
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
@@ -69,6 +66,7 @@ import androidx.core.net.toUri
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.nsh07.pomodoro.R import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.mergePaddingValues
import org.nsh07.pomodoro.ui.settingsScreen.SettingsSwitchItem import org.nsh07.pomodoro.ui.settingsScreen.SettingsSwitchItem
import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsAction import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsAction
import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsState import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsState
@@ -91,7 +89,6 @@ fun AlarmSettings(
) { ) {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
val context = LocalContext.current val context = LocalContext.current
val layoutDirection = LocalLayoutDirection.current
var alarmName by remember { mutableStateOf("...") } var alarmName by remember { mutableStateOf("...") }
@@ -181,12 +178,7 @@ fun AlarmSettings(
}, },
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection) modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
) { innerPadding -> ) { innerPadding ->
val insets = PaddingValues( val insets = mergePaddingValues(innerPadding, contentPadding)
bottom = contentPadding.calculateBottomPadding(),
top = innerPadding.calculateTopPadding(),
start = innerPadding.calculateStartPadding(layoutDirection),
end = innerPadding.calculateEndPadding(layoutDirection)
)
LazyColumn( LazyColumn(
verticalArrangement = Arrangement.spacedBy(2.dp), verticalArrangement = Arrangement.spacedBy(2.dp),
contentPadding = insets, contentPadding = insets,

View File

@@ -21,8 +21,6 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxSize 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
@@ -44,12 +42,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalLayoutDirection
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
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.nsh07.pomodoro.R import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.mergePaddingValues
import org.nsh07.pomodoro.ui.settingsScreen.SettingsSwitchItem import org.nsh07.pomodoro.ui.settingsScreen.SettingsSwitchItem
import org.nsh07.pomodoro.ui.settingsScreen.components.ColorSchemePickerListItem import org.nsh07.pomodoro.ui.settingsScreen.components.ColorSchemePickerListItem
import org.nsh07.pomodoro.ui.settingsScreen.components.PlusDivider import org.nsh07.pomodoro.ui.settingsScreen.components.PlusDivider
@@ -76,7 +74,6 @@ fun AppearanceSettings(
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
val layoutDirection = LocalLayoutDirection.current
Scaffold( Scaffold(
topBar = { topBar = {
@@ -105,12 +102,7 @@ fun AppearanceSettings(
}, },
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection) modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
) { innerPadding -> ) { innerPadding ->
val insets = PaddingValues( val insets = mergePaddingValues(innerPadding, contentPadding)
bottom = contentPadding.calculateBottomPadding(),
top = innerPadding.calculateTopPadding(),
start = innerPadding.calculateStartPadding(layoutDirection),
end = innerPadding.calculateEndPadding(layoutDirection)
)
LazyColumn( LazyColumn(
verticalArrangement = Arrangement.spacedBy(2.dp), verticalArrangement = Arrangement.spacedBy(2.dp),
contentPadding = insets, contentPadding = insets,

View File

@@ -30,8 +30,6 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
@@ -75,13 +73,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
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.platform.LocalLayoutDirection
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.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
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 org.nsh07.pomodoro.R import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.mergePaddingValues
import org.nsh07.pomodoro.ui.settingsScreen.SettingsSwitchItem import org.nsh07.pomodoro.ui.settingsScreen.SettingsSwitchItem
import org.nsh07.pomodoro.ui.settingsScreen.components.MinuteInputField import org.nsh07.pomodoro.ui.settingsScreen.components.MinuteInputField
import org.nsh07.pomodoro.ui.settingsScreen.components.PlusDivider import org.nsh07.pomodoro.ui.settingsScreen.components.PlusDivider
@@ -115,7 +113,6 @@ fun TimerSettings(
) { ) {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
val context = LocalContext.current val context = LocalContext.current
val layoutDirection = LocalLayoutDirection.current
val appName = stringResource(R.string.app_name) val appName = stringResource(R.string.app_name)
val notificationManagerService = val notificationManagerService =
remember { context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager } remember { context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager }
@@ -175,12 +172,7 @@ fun TimerSettings(
}, },
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection) modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
) { innerPadding -> ) { innerPadding ->
val insets = PaddingValues( val insets = mergePaddingValues(innerPadding, contentPadding)
bottom = contentPadding.calculateBottomPadding(),
top = innerPadding.calculateTopPadding(),
start = innerPadding.calculateStartPadding(layoutDirection),
end = innerPadding.calculateEndPadding(layoutDirection)
)
LazyColumn( LazyColumn(
verticalArrangement = Arrangement.spacedBy(2.dp), verticalArrangement = Arrangement.spacedBy(2.dp),
contentPadding = insets, contentPadding = insets,

View File

@@ -27,8 +27,6 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@@ -64,7 +62,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.rotate
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalFontFamilyResolver import androidx.compose.ui.platform.LocalFontFamilyResolver
import androidx.compose.ui.platform.LocalLayoutDirection
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
@@ -80,6 +77,7 @@ import com.patrykandpatrick.vico.core.common.data.ExtraStore
import org.nsh07.pomodoro.BuildConfig import org.nsh07.pomodoro.BuildConfig
import org.nsh07.pomodoro.R import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.data.Stat import org.nsh07.pomodoro.data.Stat
import org.nsh07.pomodoro.ui.mergePaddingValues
import org.nsh07.pomodoro.ui.statsScreen.viewModel.StatsViewModel import org.nsh07.pomodoro.ui.statsScreen.viewModel.StatsViewModel
import org.nsh07.pomodoro.ui.theme.AppFonts.googleFlex400 import org.nsh07.pomodoro.ui.theme.AppFonts.googleFlex400
import org.nsh07.pomodoro.ui.theme.AppFonts.googleFlex600 import org.nsh07.pomodoro.ui.theme.AppFonts.googleFlex600
@@ -133,7 +131,6 @@ fun StatsScreen(
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
val layoutDirection = LocalLayoutDirection.current
val hoursFormat = stringResource(R.string.hours_format) val hoursFormat = stringResource(R.string.hours_format)
val hoursMinutesFormat = stringResource(R.string.hours_and_minutes_format) val hoursMinutesFormat = stringResource(R.string.hours_and_minutes_format)
@@ -200,12 +197,7 @@ fun StatsScreen(
}, },
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection) modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
) { innerPadding -> ) { innerPadding ->
val insets = PaddingValues( val insets = mergePaddingValues(innerPadding, contentPadding)
bottom = contentPadding.calculateBottomPadding(),
top = innerPadding.calculateTopPadding(),
start = innerPadding.calculateStartPadding(layoutDirection),
end = innerPadding.calculateEndPadding(layoutDirection)
)
LazyColumn( LazyColumn(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
contentPadding = insets, contentPadding = insets,

View File

@@ -41,8 +41,6 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
@@ -87,7 +85,6 @@ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalLayoutDirection
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.text.TextStyle import androidx.compose.ui.text.TextStyle
@@ -98,6 +95,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.navigation3.ui.LocalNavAnimatedContentScope import androidx.navigation3.ui.LocalNavAnimatedContentScope
import org.nsh07.pomodoro.R import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.ui.mergePaddingValues
import org.nsh07.pomodoro.ui.theme.AppFonts.googleFlex600 import org.nsh07.pomodoro.ui.theme.AppFonts.googleFlex600
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
import org.nsh07.pomodoro.ui.theme.TomatoTheme import org.nsh07.pomodoro.ui.theme.TomatoTheme
@@ -118,7 +116,6 @@ fun SharedTransitionScope.TimerScreen(
) { ) {
val motionScheme = motionScheme val motionScheme = motionScheme
val haptic = LocalHapticFeedback.current val haptic = LocalHapticFeedback.current
val layoutDirection = LocalLayoutDirection.current
val color by animateColorAsState( val color by animateColorAsState(
if (timerState.timerMode == TimerMode.FOCUS) colorScheme.primary if (timerState.timerMode == TimerMode.FOCUS) colorScheme.primary
@@ -221,12 +218,7 @@ fun SharedTransitionScope.TimerScreen(
modifier = modifier modifier = modifier
.nestedScroll(scrollBehavior.nestedScrollConnection) .nestedScroll(scrollBehavior.nestedScrollConnection)
) { innerPadding -> ) { innerPadding ->
val insets = PaddingValues( val insets = mergePaddingValues(innerPadding, contentPadding)
bottom = contentPadding.calculateBottomPadding(),
top = innerPadding.calculateTopPadding(),
start = innerPadding.calculateStartPadding(layoutDirection),
end = innerPadding.calculateEndPadding(layoutDirection)
)
LazyColumn( LazyColumn(
verticalArrangement = Arrangement.Center, verticalArrangement = Arrangement.Center,
horizontalAlignment = CenterHorizontally, horizontalAlignment = CenterHorizontally,

View File

@@ -22,5 +22,5 @@
android:viewportHeight="960"> android:viewportHeight="960">
<path <path
android:fillColor="#e3e3e3" android:fillColor="#e3e3e3"
android:pathData="m321,880 l-71,-71 329,-329 -329,-329 71,-71 400,400L321,880Z" /> android:pathData="M579,480 L285,186q-15,-15 -14.5,-35.5T286,115q15,-15 35.5,-15t35.5,15l307,308q12,12 18,27t6,30q0,15 -6,30t-18,27L356,845q-15,15 -35,14.5T286,844q-15,-15 -15,-35.5t15,-35.5l293,-293Z" />
</vector> </vector>

View 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="M480,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,480v58q0,59 -40.5,100.5T740,680q-35,0 -66,-15t-52,-43q-29,29 -65.5,43.5T480,680q-83,0 -141.5,-58.5T280,480q0,-83 58.5,-141.5T480,280q83,0 141.5,58.5T680,480v58q0,26 17,44t43,18q26,0 43,-18t17,-44v-58q0,-134 -93,-227t-227,-93q-134,0 -227,93t-93,227q0,134 93,227t227,93h160q17,0 28.5,11.5T680,840q0,17 -11.5,28.5T640,880L480,880ZM480,600q50,0 85,-35t35,-85q0,-50 -35,-85t-85,-35q-50,0 -85,35t-35,85q0,50 35,85t85,35Z" />
</vector>

View 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="M480,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,880ZM480,800q134,0 227,-93t93,-227q0,-7 -0.5,-14.5T799,453q-5,29 -27,48t-52,19h-80q-33,0 -56.5,-23.5T560,440v-40L400,400v-80q0,-33 23.5,-56.5T480,240h40q0,-23 12.5,-40.5T563,171q-20,-5 -40.5,-8t-42.5,-3q-134,0 -227,93t-93,227h200q66,0 113,47t47,113v40L400,680v110q20,5 39.5,7.5T480,800Z" />
</vector>

View 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="M200,840q-33,0 -56.5,-23.5T120,760v-560q0,-33 23.5,-56.5T200,120h240q17,0 28.5,11.5T480,160q0,17 -11.5,28.5T440,200L200,200v560h560v-240q0,-17 11.5,-28.5T800,480q17,0 28.5,11.5T840,520v240q0,33 -23.5,56.5T760,840L200,840ZM760,256L416,600q-11,11 -28,11t-28,-11q-11,-11 -11,-28t11,-28l344,-344L600,200q-17,0 -28.5,-11.5T560,160q0,-17 11.5,-28.5T600,120h200q17,0 28.5,11.5T840,160v200q0,17 -11.5,28.5T800,400q-17,0 -28.5,-11.5T760,360v-104Z" />
</vector>

View 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="655.36dp"
android:height="655.36dp"
android:viewportWidth="655.36"
android:viewportHeight="655.36">
<path
android:fillColor="#000000"
android:pathData="m167.68,493.2c-2.01,-0.71 -4.85,-3.61 -5.55,-5.66 -0.5,-1.47 -0.54,-12.62 -0.54,-159.86 0,-147.24 0.04,-158.4 0.54,-159.86 0.36,-1.07 1.11,-2.15 2.32,-3.37 2.92,-2.92 2.87,-2.91 17.68,-2.78 11.96,0.11 12.67,0.15 14.42,0.81 4.82,1.8 6.26,3.01 15,12.56 4.43,4.83 78.74,85.46 136.27,147.85 22.97,24.91 55,59.65 71.17,77.19 22.69,24.62 29.65,31.98 30.48,32.25 1.94,0.64 5.11,-0.56 6.2,-2.35 0.62,-1.02 0.63,-2.21 0.55,-102.73l-0.08,-101.7 -1.17,-1.07c-1.65,-1.51 -4.07,-2.12 -5.8,-1.47 -0.42,0.16 -4.86,4.73 -9.86,10.16 -26.15,28.39 -31.85,34.48 -33.05,35.36 -2.05,1.49 -4.2,2.49 -6.84,3.16 -2.24,0.57 -3.65,0.62 -18.48,0.62H364.89l-1.06,-0.72c-1.52,-1.03 -2.55,-3.15 -2.55,-5.24v-1.7l43.41,-47.13c23.88,-25.92 44.67,-48.38 46.21,-49.91 2.14,-2.13 3.35,-3.04 5.21,-3.93 4.02,-1.93 5.35,-2.08 18.32,-2.09 13.56,-0.01 13.64,0.01 16.48,2.85 1.21,1.21 1.96,2.29 2.32,3.36 0.5,1.47 0.54,12.62 0.54,159.86 0,147.24 -0.04,158.4 -0.54,159.86 -0.36,1.07 -1.11,2.15 -2.32,3.37 -2.92,2.92 -2.87,2.91 -17.68,2.78 -13.77,-0.12 -13.42,-0.08 -17.7,-2.25 -2.57,-1.3 -4.16,-2.81 -12.2,-11.6 -4.19,-4.58 -25.41,-27.62 -47.15,-51.2 -73.9,-80.15 -92.94,-100.8 -109.6,-118.88 -9.15,-9.93 -27.87,-30.23 -41.6,-45.12C231.23,249.76 217.12,234.45 213.6,230.62c-4.68,-5.09 -6.67,-7.03 -7.4,-7.23 -2.07,-0.58 -5.15,0.57 -6.21,2.3 -0.62,1.01 -0.62,2.41 -0.62,101.98 0,99.66 0.01,100.97 0.63,101.99 1.09,1.78 4.27,2.99 6.2,2.35 0.82,-0.27 5.7,-5.37 20.84,-21.8 10.87,-11.79 20.39,-21.99 21.15,-22.66 1.94,-1.71 4.79,-3.15 7.68,-3.89 2.3,-0.59 3.59,-0.63 18.78,-0.63h16.31l1.21,1.21c1.63,1.63 2.5,4.42 1.86,5.99 -0.24,0.59 -7.73,8.97 -16.91,18.92 -18.82,20.39 -45.98,49.88 -59.79,64.91 -13.19,14.35 -14.75,15.9 -17.35,17.27 -4.27,2.25 -5.61,2.41 -18.99,2.38 -9.97,-0.02 -12.1,-0.11 -13.31,-0.53z" />
</vector>

View 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="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M14.234,10.162 L22.977,0h-2.072l-7.591,8.824L7.251,0L0.258,0l9.168,13.343L0.258,24L2.33,24l8.016,-9.318L16.749,24h6.993zM11.397,13.461 L10.468,12.132L3.076,1.56h3.182l5.965,8.532 0.929,1.329 7.754,11.09h-3.182z" />
</vector>

View File

@@ -45,7 +45,7 @@
<string name="focus">Focus</string> <string name="focus">Focus</string>
<string name="focus_per_day_avg">focus per day (avg)</string> <string name="focus_per_day_avg">focus per day (avg)</string>
<string name="get_plus">Get Tomato+</string> <string name="get_plus">Get Tomato+</string>
<string name="help_with_translation">Help with translation</string> <string name="help_with_translation">Help translate Tomato</string>
<string name="hours_and_minutes_format">%dh %dm</string> <string name="hours_and_minutes_format">%dh %dm</string>
<string name="hours_format">%dh</string> <string name="hours_format">%dh</string>
<string name="language">Language</string> <string name="language">Language</string>
@@ -97,4 +97,8 @@
<string name="vibrate">Vibration</string> <string name="vibrate">Vibration</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="about">About</string>
<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>
</resources> </resources>

View File

@@ -17,17 +17,12 @@
package org.nsh07.pomodoro.ui.settingsScreen.components package org.nsh07.pomodoro.ui.settingsScreen.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@@ -37,56 +32,43 @@ import org.nsh07.pomodoro.R
@OptIn(ExperimentalMaterial3ExpressiveApi::class) @OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable @Composable
fun TopButton( fun TopButton(modifier: Modifier = Modifier) {
buttonColors: ButtonColors,
modifier: Modifier = Modifier
) {
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
Button( ClickableListItem(
colors = buttonColors, leadingContent = {
onClick = { uriHandler.openUri("https://hosted.weblate.org/engage/tomato/") },
shapes = ButtonDefaults.shapes(),
modifier = modifier
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon( Icon(
painterResource(R.drawable.weblate), painterResource(R.drawable.weblate),
tint = colorScheme.primary,
contentDescription = null, contentDescription = null,
modifier = Modifier.size(24.dp) modifier = Modifier.size(24.dp)
) )
},
Text(text = stringResource(R.string.help_with_translation)) headlineContent = { Text(stringResource(R.string.help_with_translation)) },
} supportingContent = { Text(stringResource(R.string.help_with_translation_desc)) },
} trailingContent = { Icon(painterResource(R.drawable.open_in_browser), null) },
items = 2,
index = 0,
modifier = modifier
) { uriHandler.openUri("https://hosted.weblate.org/engage/tomato/") }
} }
@OptIn(ExperimentalMaterial3ExpressiveApi::class) @OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable @Composable
fun BottomButton( fun BottomButton(modifier: Modifier = Modifier) {
buttonColors: ButtonColors,
modifier: Modifier = Modifier
) {
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
Button( ClickableListItem(
colors = buttonColors, leadingContent = {
onClick = { uriHandler.openUri("https://play.google.com/store/apps/details?id=org.nsh07.pomodoro") },
shapes = ButtonDefaults.shapes(),
modifier = modifier
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon( Icon(
painterResource(R.drawable.play_store), painterResource(R.drawable.play_store),
tint = colorScheme.secondary,
contentDescription = null, contentDescription = null,
modifier = Modifier.size(24.dp) modifier = Modifier.size(24.dp)
) )
},
Text(text = stringResource(R.string.rate_on_google_play)) headlineContent = { Text(stringResource(R.string.rate_on_google_play)) },
} supportingContent = { Text(stringResource(R.string.rate_on_google_play_desc)) },
} items = 2,
index = 1,
modifier = modifier
) { uriHandler.openUri("https://play.google.com/store/apps/details?id=org.nsh07.pomodoro") }
} }