Merge branch 'dev'
This commit is contained in:
BIN
.github/repo_photos/inter-banner.png
vendored
Normal file
BIN
.github/repo_photos/inter-banner.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
BIN
.github/repo_photos/open-runde-banner.png
vendored
BIN
.github/repo_photos/open-runde-banner.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB |
11
README.md
11
README.md
@@ -94,9 +94,8 @@ translating this project into languages you know.
|
||||
|
||||
## Download
|
||||
|
||||
- **Google Play Store** (recommended): Tomato will soon be available (currently in closed testing)
|
||||
on the Google Play Store.
|
||||
[You can find it through this link](https://play.google.com/store/apps/details?id=org.nsh07.pomodoro).
|
||||
- **Google Play Store** (recommended): Tomato is available on the Google Play Store.
|
||||
[You can download it through this link](https://play.google.com/store/apps/details?id=org.nsh07.pomodoro).
|
||||
- **F-Droid** (recommended): Tomato is available on the official F-Droid repository. Simply open
|
||||
your preferred F-Droid app and search for Tomato. Updates on F-Droid are generally a week late. To
|
||||
get faster updates, you can install it through
|
||||
@@ -109,7 +108,7 @@ translating this project into languages you know.
|
||||
> To [verify](https://developer.android.com/studio/command-line/apksigner#usage-verify) the APK
|
||||
> downloaded from GitHub, use the following signing certificate fingerprints:
|
||||
> ```
|
||||
> SHA1: B1:4E:17:93:11:E8:DB:D5:35:EF:8D:E9:FB:8F:FF:08:F8:EC:65:08
|
||||
> SHA1: B1:4E:17:93:11:E8:DB:D5:35:EF:8D:E9:FB:8F:FF:08:F8:EC:65:08
|
||||
> SHA256: 07:BE:F3:05:81:BA:EE:8F:45:EC:93:E4:7E:E6:8E:F2:08:74:E5:0E:F5:70:9C:78:B2:EE:67:AC:86:BE:4C:3D
|
||||
> ```
|
||||
> The SHA256 and MD5 hashes of the individual APK files are also available in the `checksum.txt`
|
||||
@@ -143,8 +142,8 @@ This app was made possible by the following libraries:
|
||||
- [Roboto Flex](https://fonts.google.com/specimen/Roboto+Flex) by
|
||||
Google<br/><img src=".github/repo_photos/roboto-flex-banner.jpg" width="400">
|
||||
|
||||
- [Open Runde](https://github.com/lauridskern/open-runde) by Laurids
|
||||
Kern<br/><img src=".github/repo_photos/open-runde-banner.png" width="400">
|
||||
- [Inter](https://rsms.me/inter/) by
|
||||
Rasmus Andersson<br/><img src=".github/repo_photos/inter-banner.png" width="400">
|
||||
|
||||
## Star History
|
||||
|
||||
|
||||
@@ -43,10 +43,14 @@ android {
|
||||
applicationId = "org.nsh07.pomodoro"
|
||||
minSdk = 27
|
||||
targetSdk = 36
|
||||
versionCode = 17
|
||||
versionName = "1.6.2"
|
||||
versionCode = 18
|
||||
versionName = "1.6.3"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
androidResources {
|
||||
generateLocaleConfig = true
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
@@ -78,7 +78,7 @@ fun TomatoPlusPaywallDialog(
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Button(onClick = { uriHandler.openUri("https://coff.ee/nsh07") }) {
|
||||
Text("Buy Me A Coffee")
|
||||
Text(stringResource(R.string.bmc))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.platform.LocalWindowInfo
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Density
|
||||
@@ -65,7 +64,7 @@ import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.navigation3.ui.LocalNavAnimatedContentScope
|
||||
import kotlinx.coroutines.delay
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.openRundeClock
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.interClock
|
||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||
import org.nsh07.pomodoro.ui.timerScreen.TimerScreen
|
||||
import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerMode
|
||||
@@ -249,10 +248,10 @@ fun SharedTransitionScope.AlwaysOnDisplay(
|
||||
Text(
|
||||
text = timerState.timeStr,
|
||||
style = TextStyle(
|
||||
fontFamily = openRundeClock,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontFamily = interClock,
|
||||
fontSize = 56.sp,
|
||||
letterSpacing = (-2).sp
|
||||
letterSpacing = (-2).sp,
|
||||
fontFeatureSettings = "tnum"
|
||||
),
|
||||
textAlign = TextAlign.Center,
|
||||
color = onSurface,
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
package org.nsh07.pomodoro.ui.settingsScreen
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.LocaleManager
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.slideInHorizontally
|
||||
@@ -46,8 +48,10 @@ import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -68,6 +72,7 @@ import org.nsh07.pomodoro.service.TimerService
|
||||
import org.nsh07.pomodoro.ui.Screen
|
||||
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.AlarmSettings
|
||||
import org.nsh07.pomodoro.ui.settingsScreen.screens.AppearanceSettings
|
||||
@@ -76,6 +81,7 @@ import org.nsh07.pomodoro.ui.settingsScreen.viewModel.PreferencesState
|
||||
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.CustomColors.listItemColors
|
||||
import org.nsh07.pomodoro.ui.theme.CustomColors.topBarColors
|
||||
|
||||
|
||||
@@ -182,6 +188,22 @@ private fun SettingsScreen(
|
||||
val context = LocalContext.current
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
|
||||
val currentLocales =
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
context
|
||||
.getSystemService(LocaleManager::class.java)
|
||||
.applicationLocales
|
||||
} else null
|
||||
val currentLocalesSize = currentLocales?.size() ?: 0
|
||||
|
||||
var showLocaleSheet by remember { mutableStateOf(false) }
|
||||
|
||||
if (showLocaleSheet && currentLocales != null)
|
||||
LocaleBottomSheet(
|
||||
currentLocales = currentLocales,
|
||||
setShowSheet = { showLocaleSheet = it }
|
||||
)
|
||||
|
||||
NavDisplay(
|
||||
backStack = backStack,
|
||||
onBack = backStack::removeLastOrNull,
|
||||
@@ -266,6 +288,30 @@ private fun SettingsScreen(
|
||||
}
|
||||
|
||||
item { Spacer(Modifier.height(12.dp)) }
|
||||
|
||||
if (currentLocales != null)
|
||||
item {
|
||||
ClickableListItem(
|
||||
leadingContent = {
|
||||
Icon(
|
||||
painterResource(R.drawable.language),
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
headlineContent = { Text(stringResource(R.string.language)) },
|
||||
supportingContent = {
|
||||
Text(
|
||||
if (currentLocalesSize > 0) currentLocales.get(0).displayName
|
||||
else stringResource(R.string.system_default)
|
||||
)
|
||||
},
|
||||
colors = listItemColors,
|
||||
items = 1,
|
||||
index = 0
|
||||
) { showLocaleSheet = true }
|
||||
}
|
||||
|
||||
item { Spacer(Modifier.height(12.dp)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,11 +129,11 @@ fun AboutCard(
|
||||
) {
|
||||
Icon(
|
||||
painterResource(R.drawable.bmc),
|
||||
contentDescription = "Buy me a coffee",
|
||||
contentDescription = null,
|
||||
modifier = Modifier.height(24.dp)
|
||||
)
|
||||
|
||||
Text(text = "Buy me a coffee")
|
||||
Text(text = stringResource(R.string.bmc))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,11 +147,11 @@ fun AboutCard(
|
||||
) {
|
||||
Icon(
|
||||
painterResource(R.drawable.play_store),
|
||||
contentDescription = "Rate on Google Play",
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
|
||||
Text(text = "Rate on Google Play")
|
||||
Text(text = stringResource(R.string.rate_on_google_play))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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.app.LocaleConfig
|
||||
import android.app.LocaleManager
|
||||
import android.os.Build
|
||||
import android.os.LocaleList
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.ListItemDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||
import androidx.compose.material3.MaterialTheme.shapes
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
import org.nsh07.pomodoro.R
|
||||
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
|
||||
import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.bottomListItemShape
|
||||
import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.middleListItemShape
|
||||
import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.topListItemShape
|
||||
import java.util.Locale
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun LocaleBottomSheet(
|
||||
currentLocales: LocaleList,
|
||||
setShowSheet: (Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
val supportedLocales = remember {
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
LocaleConfig(context).supportedLocales
|
||||
} else null
|
||||
}
|
||||
val supportedLocalesSize = supportedLocales?.size() ?: 0
|
||||
|
||||
val supportedLocalesList: List<AppLocale>? = remember {
|
||||
if (supportedLocales != null) {
|
||||
buildList {
|
||||
for (i in 0 until supportedLocalesSize) {
|
||||
add(AppLocale(supportedLocales.get(i), supportedLocales.get(i).displayName))
|
||||
}
|
||||
sortWith(compareBy { it.name })
|
||||
}
|
||||
} else null
|
||||
}
|
||||
|
||||
val bottomSheetState = rememberModalBottomSheetState()
|
||||
val listState = rememberLazyListState()
|
||||
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = { setShowSheet(false) },
|
||||
sheetState = bottomSheetState,
|
||||
modifier = modifier
|
||||
) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text(
|
||||
text = stringResource(R.string.choose_language),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
modifier = Modifier.padding(bottom = 16.dp)
|
||||
)
|
||||
if (supportedLocalesList != null) {
|
||||
LazyColumn(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
state = listState,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.clip(shapes.largeIncreased)
|
||||
) {
|
||||
item {
|
||||
ListItem(
|
||||
headlineContent = {
|
||||
Text(stringResource(R.string.system_default))
|
||||
},
|
||||
trailingContent = {
|
||||
if (currentLocales.isEmpty)
|
||||
Icon(
|
||||
painterResource(R.drawable.check),
|
||||
contentDescription = stringResource(R.string.selected)
|
||||
)
|
||||
},
|
||||
colors =
|
||||
if (currentLocales.isEmpty)
|
||||
ListItemDefaults.colors(
|
||||
containerColor = colorScheme.primaryContainer.copy(
|
||||
0.3f
|
||||
)
|
||||
)
|
||||
else listItemColors,
|
||||
modifier = Modifier
|
||||
.clip(if (currentLocales.isEmpty) CircleShape else shapes.largeIncreased)
|
||||
.clickable(
|
||||
onClick = {
|
||||
scope
|
||||
.launch { bottomSheetState.hide() }
|
||||
.invokeOnCompletion {
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
context
|
||||
.getSystemService(LocaleManager::class.java)
|
||||
.applicationLocales = LocaleList()
|
||||
}
|
||||
setShowSheet(false)
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
item {
|
||||
Spacer(Modifier.height(12.dp))
|
||||
}
|
||||
itemsIndexed(
|
||||
supportedLocalesList,
|
||||
key = { _: Int, it: AppLocale -> it.name }
|
||||
) { index, it ->
|
||||
ListItem(
|
||||
headlineContent = {
|
||||
Text(it.name)
|
||||
},
|
||||
trailingContent = {
|
||||
if (!currentLocales.isEmpty && it.locale == currentLocales.get(0))
|
||||
Icon(
|
||||
painterResource(R.drawable.check),
|
||||
tint = colorScheme.primary,
|
||||
contentDescription = stringResource(R.string.selected)
|
||||
)
|
||||
},
|
||||
colors =
|
||||
if (!currentLocales.isEmpty && it.locale == currentLocales.get(0))
|
||||
ListItemDefaults.colors(containerColor = colorScheme.primaryContainer)
|
||||
else listItemColors,
|
||||
modifier = Modifier
|
||||
.clip(
|
||||
if (!currentLocales.isEmpty && it.locale == currentLocales.get(0))
|
||||
CircleShape
|
||||
else when (index) {
|
||||
0 -> topListItemShape
|
||||
supportedLocalesSize - 1 -> bottomListItemShape
|
||||
else -> middleListItemShape
|
||||
}
|
||||
)
|
||||
.clickable(
|
||||
onClick = {
|
||||
scope
|
||||
.launch { bottomSheetState.hide() }
|
||||
.invokeOnCompletion { _ ->
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
context.getSystemService(LocaleManager::class.java)
|
||||
.applicationLocales =
|
||||
LocaleList(it.locale)
|
||||
}
|
||||
setShowSheet(false)
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class AppLocale(
|
||||
val locale: Locale,
|
||||
val name: String
|
||||
)
|
||||
@@ -34,13 +34,12 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.openRundeClock
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.interClock
|
||||
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@@ -61,8 +60,7 @@ fun MinuteInputField(
|
||||
imeAction = imeAction
|
||||
),
|
||||
textStyle = TextStyle(
|
||||
fontFamily = openRundeClock,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontFamily = interClock,
|
||||
fontSize = 57.sp,
|
||||
letterSpacing = (-2).sp,
|
||||
color = colorScheme.onSurfaceVariant,
|
||||
|
||||
@@ -33,10 +33,9 @@ object MinutesInputTransformation : InputTransformation {
|
||||
|
||||
object MinutesOutputTransformation : OutputTransformation {
|
||||
override fun TextFieldBuffer.transformOutput() {
|
||||
if (this.length == 0) {
|
||||
insert(0, "00")
|
||||
} else if (this.toString().toInt() < 10) {
|
||||
insert(0, "0")
|
||||
when (this.length) {
|
||||
0 -> insert(0, "00")
|
||||
1 -> insert(0, "0")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Nishant Mishra
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
* 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.statsScreen
|
||||
@@ -65,7 +75,7 @@ import org.nsh07.pomodoro.BuildConfig
|
||||
import org.nsh07.pomodoro.R
|
||||
import org.nsh07.pomodoro.data.Stat
|
||||
import org.nsh07.pomodoro.ui.statsScreen.viewModel.StatsViewModel
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.openRundeClock
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.interClock
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
|
||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||
import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes
|
||||
@@ -209,7 +219,7 @@ fun StatsScreen(
|
||||
millisecondsToHoursMinutes(todayStat?.totalFocusTime() ?: 0)
|
||||
},
|
||||
style = typography.displaySmall,
|
||||
fontFamily = openRundeClock,
|
||||
fontFamily = interClock,
|
||||
color = colorScheme.onPrimaryContainer,
|
||||
maxLines = 1,
|
||||
autoSize = TextAutoSize.StepBased(maxFontSize = typography.displaySmall.fontSize)
|
||||
@@ -236,7 +246,7 @@ fun StatsScreen(
|
||||
millisecondsToHoursMinutes(todayStat?.breakTime ?: 0)
|
||||
},
|
||||
style = typography.displaySmall,
|
||||
fontFamily = openRundeClock,
|
||||
fontFamily = interClock,
|
||||
color = colorScheme.onTertiaryContainer,
|
||||
maxLines = 1,
|
||||
autoSize = TextAutoSize.StepBased(maxFontSize = typography.displaySmall.fontSize)
|
||||
@@ -270,7 +280,7 @@ fun StatsScreen(
|
||||
}
|
||||
),
|
||||
style = typography.displaySmall,
|
||||
fontFamily = openRundeClock
|
||||
fontFamily = interClock
|
||||
)
|
||||
Text(
|
||||
stringResource(R.string.focus_per_day_avg),
|
||||
@@ -346,7 +356,7 @@ fun StatsScreen(
|
||||
}
|
||||
),
|
||||
style = typography.displaySmall,
|
||||
fontFamily = openRundeClock
|
||||
fontFamily = interClock
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.focus_per_day_avg),
|
||||
@@ -423,7 +433,7 @@ fun StatsScreen(
|
||||
}
|
||||
),
|
||||
style = typography.displaySmall,
|
||||
fontFamily = openRundeClock
|
||||
fontFamily = interClock
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.focus_per_day_avg),
|
||||
|
||||
@@ -1,59 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Nishant Mishra
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
* 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.theme
|
||||
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.ui.text.ExperimentalTextApi
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.Font
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontVariation
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
import org.nsh07.pomodoro.R
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.interBody
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.interLabel
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexHeadline
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTitle
|
||||
|
||||
val TYPOGRAPHY = Typography()
|
||||
|
||||
// Set of Material typography styles to start with
|
||||
val Typography = Typography(
|
||||
bodyLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
),
|
||||
headlineSmall = TextStyle(
|
||||
fontFamily = robotoFlexHeadline,
|
||||
fontSize = 24.sp,
|
||||
lineHeight = 32.sp,
|
||||
letterSpacing = 0.sp,
|
||||
),
|
||||
titleMedium = TextStyle(
|
||||
fontFamily = robotoFlexTitle,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.15.sp,
|
||||
),
|
||||
titleSmall = TextStyle(
|
||||
fontFamily = robotoFlexTitle,
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 20.sp,
|
||||
letterSpacing = 0.1.sp
|
||||
)
|
||||
displayLarge = TYPOGRAPHY.displayLarge.copy(fontFamily = robotoFlexHeadline),
|
||||
displayMedium = TYPOGRAPHY.displayMedium.copy(fontFamily = robotoFlexHeadline),
|
||||
displaySmall = TYPOGRAPHY.displaySmall.copy(fontFamily = robotoFlexHeadline),
|
||||
headlineLarge = TYPOGRAPHY.headlineLarge.copy(fontFamily = robotoFlexHeadline),
|
||||
headlineMedium = TYPOGRAPHY.headlineMedium.copy(fontFamily = robotoFlexHeadline),
|
||||
headlineSmall = TYPOGRAPHY.headlineSmall.copy(fontFamily = robotoFlexHeadline),
|
||||
titleLarge = TYPOGRAPHY.titleLarge.copy(fontFamily = robotoFlexTitle),
|
||||
titleMedium = TYPOGRAPHY.titleMedium.copy(fontFamily = robotoFlexTitle),
|
||||
titleSmall = TYPOGRAPHY.titleSmall.copy(fontFamily = robotoFlexTitle),
|
||||
bodyLarge = TYPOGRAPHY.bodyLarge.copy(fontFamily = interBody),
|
||||
bodyMedium = TYPOGRAPHY.bodyMedium.copy(fontFamily = interBody),
|
||||
bodySmall = TYPOGRAPHY.bodySmall.copy(fontFamily = interBody),
|
||||
labelLarge = TYPOGRAPHY.labelLarge.copy(fontFamily = interLabel),
|
||||
labelMedium = TYPOGRAPHY.labelMedium.copy(fontFamily = interLabel),
|
||||
labelSmall = TYPOGRAPHY.labelSmall.copy(fontFamily = interLabel)
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalTextApi::class)
|
||||
object AppFonts {
|
||||
val openRundeClock = FontFamily(
|
||||
Font(R.font.open_runde_bold_clock_only, FontWeight.Bold)
|
||||
val interClock = FontFamily(
|
||||
Font(
|
||||
R.font.inter_variable, variationSettings = FontVariation.Settings(
|
||||
FontWeight.Bold,
|
||||
FontStyle.Normal
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val interBody = FontFamily(
|
||||
Font(
|
||||
R.font.inter_variable, variationSettings = FontVariation.Settings(
|
||||
FontWeight.Normal,
|
||||
FontStyle.Normal
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val interLabel = FontFamily(
|
||||
Font(
|
||||
R.font.inter_variable, variationSettings = FontVariation.Settings(
|
||||
FontWeight.Medium,
|
||||
FontStyle.Normal
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalTextApi::class)
|
||||
val robotoFlexTopBar = FontFamily(
|
||||
Font(
|
||||
R.font.roboto_flex_variable,
|
||||
@@ -73,7 +99,6 @@ object AppFonts {
|
||||
)
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalTextApi::class)
|
||||
val robotoFlexHeadline = FontFamily(
|
||||
Font(
|
||||
R.font.roboto_flex_variable,
|
||||
@@ -85,7 +110,6 @@ object AppFonts {
|
||||
)
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalTextApi::class)
|
||||
val robotoFlexTitle = FontFamily(
|
||||
Font(
|
||||
R.font.roboto_flex_variable,
|
||||
|
||||
@@ -17,29 +17,35 @@
|
||||
|
||||
package org.nsh07.pomodoro.ui.timerScreen
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
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.wrapContentHeight
|
||||
import androidx.compose.foundation.layout.wrapContentWidth
|
||||
import androidx.compose.material3.AlertDialogDefaults
|
||||
import androidx.compose.material3.BasicAlertDialog
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||
import androidx.compose.material3.MaterialTheme.typography
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import org.nsh07.pomodoro.R
|
||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -47,42 +53,57 @@ fun AlarmDialog(
|
||||
modifier: Modifier = Modifier,
|
||||
stopAlarm: () -> Unit
|
||||
) {
|
||||
BasicAlertDialog(
|
||||
Dialog(
|
||||
onDismissRequest = stopAlarm,
|
||||
modifier = modifier
|
||||
properties = DialogProperties(
|
||||
usePlatformDefaultWidth = false,
|
||||
decorFitsSystemWindows = false
|
||||
)
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.wrapContentWidth()
|
||||
.wrapContentHeight()
|
||||
.clickable(onClick = stopAlarm),
|
||||
shape = MaterialTheme.shapes.extraLarge,
|
||||
tonalElevation = AlertDialogDefaults.TonalElevation,
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.background(colorScheme.primaryContainer)
|
||||
.clickable(onClick = stopAlarm)
|
||||
) {
|
||||
Column(modifier = Modifier.padding(24.dp)) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.alarm),
|
||||
contentDescription = stringResource(R.string.alarm),
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Text(
|
||||
text = stringResource(R.string.stop_alarm_question),
|
||||
style = typography.headlineSmall,
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Text(
|
||||
text = stringResource(R.string.stop_alarm_dialog_text)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
TextButton(
|
||||
onClick = stopAlarm,
|
||||
modifier = Modifier.align(Alignment.End),
|
||||
) {
|
||||
Text(stringResource(R.string.stop_alarm))
|
||||
CompositionLocalProvider(LocalContentColor provides colorScheme.onPrimaryContainer) {
|
||||
Column(modifier = Modifier.padding(24.dp)) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.alarm),
|
||||
contentDescription = stringResource(R.string.alarm),
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.size(40.dp)
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Text(
|
||||
text = stringResource(R.string.stop_alarm_question),
|
||||
style = typography.headlineSmall,
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Text(
|
||||
text = stringResource(R.string.stop_alarm_dialog_text),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
Button(
|
||||
onClick = stopAlarm,
|
||||
modifier = Modifier.align(Alignment.End),
|
||||
) {
|
||||
Text(stringResource(R.string.stop_alarm))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun AlarmDialogPreview() {
|
||||
TomatoTheme {
|
||||
AlarmDialog(stopAlarm = {})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,6 @@ import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
@@ -95,7 +94,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.navigation3.ui.LocalNavAnimatedContentScope
|
||||
import org.nsh07.pomodoro.R
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.openRundeClock
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.interClock
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
|
||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||
import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerAction
|
||||
@@ -283,10 +282,10 @@ fun SharedTransitionScope.TimerScreen(
|
||||
Text(
|
||||
text = timerState.timeStr,
|
||||
style = TextStyle(
|
||||
fontFamily = openRundeClock,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontFamily = interClock,
|
||||
fontSize = 72.sp,
|
||||
letterSpacing = (-2).sp
|
||||
letterSpacing = (-2).sp,
|
||||
fontFeatureSettings = "tnum"
|
||||
),
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 1,
|
||||
@@ -308,7 +307,7 @@ fun SharedTransitionScope.TimerScreen(
|
||||
timerState.currentFocusCount,
|
||||
timerState.totalFocusCount
|
||||
),
|
||||
fontFamily = openRundeClock,
|
||||
fontFamily = interClock,
|
||||
style = typography.titleLarge,
|
||||
color = colorScheme.outline
|
||||
)
|
||||
@@ -498,8 +497,7 @@ fun SharedTransitionScope.TimerScreen(
|
||||
Text(
|
||||
it,
|
||||
style = TextStyle(
|
||||
fontFamily = openRundeClock,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontFamily = interClock,
|
||||
fontSize = 22.sp,
|
||||
lineHeight = 28.sp,
|
||||
color = if (timerState.nextTimerMode == TimerMode.FOCUS) colorScheme.primary else colorScheme.tertiary,
|
||||
|
||||
26
app/src/main/res/drawable/language.xml
Normal file
26
app/src/main/res/drawable/language.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="M480,880q-82,0 -155,-31.5t-127.5,-86Q143,708 111.5,635T80,480q0,-83 31.5,-155.5t86,-127Q252,143 325,111.5T480,80q83,0 155.5,31.5t127,86q54.5,54.5 86,127T880,480q0,82 -31.5,155t-86,127.5q-54.5,54.5 -127,86T480,880ZM480,798q26,-36 45,-75t31,-83L404,640q12,44 31,83t45,75ZM376,782q-18,-33 -31.5,-68.5T322,640L204,640q29,50 72.5,87t99.5,55ZM584,782q56,-18 99.5,-55t72.5,-87L638,640q-9,38 -22.5,73.5T584,782ZM170,560h136q-3,-20 -4.5,-39.5T300,480q0,-21 1.5,-40.5T306,400L170,400q-5,20 -7.5,39.5T160,480q0,21 2.5,40.5T170,560ZM386,560h188q3,-20 4.5,-39.5T580,480q0,-21 -1.5,-40.5T574,400L386,400q-3,20 -4.5,39.5T380,480q0,21 1.5,40.5T386,560ZM654,560h136q5,-20 7.5,-39.5T800,480q0,-21 -2.5,-40.5T790,400L654,400q3,20 4.5,39.5T660,480q0,21 -1.5,40.5T654,560ZM638,320h118q-29,-50 -72.5,-87T584,178q18,33 31.5,68.5T638,320ZM404,320h152q-12,-44 -31,-83t-45,-75q-26,36 -45,75t-31,83ZM204,320h118q9,-38 22.5,-73.5T376,178q-56,18 -99.5,55T204,320Z" />
|
||||
</vector>
|
||||
BIN
app/src/main/res/font/inter_variable.ttf
Normal file
BIN
app/src/main/res/font/inter_variable.ttf
Normal file
Binary file not shown.
Binary file not shown.
17
app/src/main/res/resources.properties
Normal file
17
app/src/main/res/resources.properties
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
unqualifiedResLocale=en
|
||||
@@ -57,11 +57,20 @@
|
||||
<string name="timer">Timer</string>
|
||||
<string name="timer_progress">Timer-Fortschritt</string>
|
||||
<string name="always_on_display">Always-On Display</string>
|
||||
<string name="always_on_display_desc">Tippe irgendwo, während der Timer angezeigt wird, um in den AOD-Modus zu wechseln.</string>
|
||||
<string name="always_on_display_desc">Tippe irgendwo, während der Timer angezeigt wird, um in den AOD-Modus zu wechseln</string>
|
||||
<string name="last_year">Letztes Jahr</string>
|
||||
<string name="appearance">Aussehen</string>
|
||||
<string name="durations">Dauer</string>
|
||||
<string name="sound">Sound</string>
|
||||
<string name="dnd">Bitte nicht stören</string>
|
||||
<string name="dnd_desc">‚Bitte nicht stören‘ aktivieren, wenn ein Fokus-Timer läuft</string>
|
||||
<string name="get_plus">Hole dir Tomato+</string>
|
||||
<string name="dynamic_color">Dynamische Farben</string>
|
||||
<string name="dynamic_color_desc">Design an Hintergrundbild anpassen</string>
|
||||
<string name="tomato_foss">Tomato FOSS</string>
|
||||
<string name="tomato_foss_desc">In dieser Version sind alle Funktionen freigeschaltet. Wenn dir die App gefällt, kannst du mich gerne mit einer Spende auf %1$s unterstützen.</string>
|
||||
<string name="language">Sprache</string>
|
||||
<string name="choose_language">Sprache wählen</string>
|
||||
<string name="rate_on_google_play">Im Play Store bewerten</string>
|
||||
<string name="selected">Ausgewählt</string>
|
||||
</resources>
|
||||
|
||||
@@ -66,8 +66,12 @@
|
||||
<string name="dnd_desc">Activer le mode ne pas déranger pendant un minuteur de concentration</string>
|
||||
<string name="dynamic_color">Couleur dynamique</string>
|
||||
<string name="dynamic_color_desc">Adapter les couleurs à celles de votre fond d\'écran</string>
|
||||
<string name="tomato_foss_desc">Toutes les fonctionnalités sont déverrouillées dans cette version. Si mon application a fait une différence dans votre vie, veuillez envisager de me soutenir en faisant un don de %1$s.</string>
|
||||
<string name="tomato_foss_desc">Toutes les fonctionnalités sont déverrouillées dans cette version. Si mon application a fait une différence dans votre vie, veuillez envisager de me soutenir en faisant un don sur %1$s.</string>
|
||||
<string name="app_name_plus">Tomato+</string>
|
||||
<string name="get_plus">Obtenir Tomato+</string>
|
||||
<string name="tomato_foss">Tomato FOSS</string>
|
||||
<string name="language">Langue</string>
|
||||
<string name="choose_language">Choisissez la langue</string>
|
||||
<string name="rate_on_google_play">Noter sur Google Play</string>
|
||||
<string name="selected">Selectionné</string>
|
||||
</resources>
|
||||
|
||||
3
app/src/main/res/values-ko/strings.xml
Normal file
3
app/src/main/res/values-ko/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
@@ -18,7 +18,7 @@
|
||||
<string name="color_scheme">Esquema de cores</string>
|
||||
<string name="dynamic">Dinâmico</string>
|
||||
<string name="color">Cor</string>
|
||||
<string name="system_default">Padrão do sistema</string>
|
||||
<string name="system_default">Sistema</string>
|
||||
<string name="alarm">Alarme</string>
|
||||
<string name="light">Claro</string>
|
||||
<string name="dark">Escuro</string>
|
||||
@@ -29,7 +29,7 @@
|
||||
<string name="black_theme">Tema escuro</string>
|
||||
<string name="black_theme_desc">Use um tema preto escuro puro</string>
|
||||
<string name="alarm_desc">Tocar o alarme quando um timer for concluído</string>
|
||||
<string name="vibrate">Vibrar</string>
|
||||
<string name="vibrate">Vibração</string>
|
||||
<string name="vibrate_desc">Vibrar quanto um timer for concluído</string>
|
||||
<string name="theme">Tema</string>
|
||||
<string name="settings">Configurações</string>
|
||||
@@ -56,4 +56,21 @@
|
||||
<string name="up_next">Próximo</string>
|
||||
<string name="timer">Timer</string>
|
||||
<string name="timer_progress">Progresso do timer</string>
|
||||
<string name="always_on_display">Always On Display</string>
|
||||
<string name="always_on_display_desc">Toque em qualquer lugar da tela enquanto visualiza o cronômetro para alternar para o modo Always On Display</string>
|
||||
<string name="last_year">Último ano</string>
|
||||
<string name="appearance">Aparência</string>
|
||||
<string name="durations">Durações</string>
|
||||
<string name="sound">Som</string>
|
||||
<string name="dnd">Não perturbar</string>
|
||||
<string name="dnd_desc">Ative o modo Não Perturbe ao usar o cronômetro de foco</string>
|
||||
<string name="get_plus">Obtenha o Tomato+</string>
|
||||
<string name="dynamic_color">Cor dinâmica</string>
|
||||
<string name="dynamic_color_desc">Adapte as cores do tema à partir do seu papel de parede</string>
|
||||
<string name="tomato_foss">Tomato FOSS</string>
|
||||
<string name="tomato_foss_desc">Todos os recursos estão desbloqueados nesta versão. Se meu app fez a diferença na sua vida, considere me apoiar fazendo uma doação em %1$s.</string>
|
||||
<string name="language">Idioma</string>
|
||||
<string name="choose_language">Escolher idioma</string>
|
||||
<string name="rate_on_google_play">Avalie no Google Play</string>
|
||||
<string name="selected">Selecionado</string>
|
||||
</resources>
|
||||
|
||||
76
app/src/main/res/values-ru/strings.xml
Normal file
76
app/src/main/res/values-ru/strings.xml
Normal file
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="alarm">Сигнал</string>
|
||||
<string name="alarm_desc">Воспроизвести сигнал по окончании таймера</string>
|
||||
<string name="alarm_sound">Звук сигнала</string>
|
||||
<string name="always_on_display">Всегда Включенный Экран</string>
|
||||
<string name="always_on_display_desc">Переходить в режим Всегда Включенный Экран при нажатии на любое место при просмотре таймера</string>
|
||||
<string name="black_theme">Чёрная тема</string>
|
||||
<string name="black_theme_desc">Использовать чёрный цвет в тёмной теме</string>
|
||||
<string name="break_">Перерыв</string>
|
||||
<string name="choose_color_scheme">Выбрать цветовую схему</string>
|
||||
<string name="choose_theme">Выбрать тему</string>
|
||||
<string name="color">Цвет</string>
|
||||
<string name="color_scheme">Цветовая схема</string>
|
||||
<string name="completed">Готово</string>
|
||||
<string name="dark">Тёмная</string>
|
||||
<string name="dynamic">Динамическая</string>
|
||||
<string name="exit">Выход</string>
|
||||
<string name="focus">Фокус</string>
|
||||
<string name="focus_per_day_avg">Фокусировок в день (среднее)</string>
|
||||
<string name="last_month">Последний месяц</string>
|
||||
<string name="last_week">Последняя неделя</string>
|
||||
<string name="last_year">Последний год</string>
|
||||
<string name="light">Светлая</string>
|
||||
<string name="long_break">Долгий перерыв</string>
|
||||
<string name="min_remaining_notification">%1$s минут осталось</string>
|
||||
<string name="monthly_productivity_analysis">Анализ месячной продуктивности</string>
|
||||
<string name="more">Ещё</string>
|
||||
<string name="more_info">Больше информации</string>
|
||||
<string name="ok">Ок</string>
|
||||
<string name="pause">Пауза</string>
|
||||
<string name="paused">Приостановлено</string>
|
||||
<string name="play">Пуск</string>
|
||||
<string name="pomodoro_info">Сессия — это последовательность интервалов помодоро, которые содержат интервалы фокусировки, короткие интервалы перерыва и длинный интервал перерыва. Последний перерыв в сеансе — всегда долгий перерыв.</string>
|
||||
<string name="productivity_analysis">Анализ продуктивности</string>
|
||||
<string name="productivity_analysis_desc">Продолжительность фокусировки в разное время дня</string>
|
||||
<string name="restart">Перезапуск</string>
|
||||
<string name="session_length">Длинна сессии</string>
|
||||
<string name="session_length_desc">Интервалы фокусировки в одной сессии: %1$d</string>
|
||||
<string name="settings">Настройки</string>
|
||||
<string name="short_break">Короткий перерыв</string>
|
||||
<string name="skip">Пропустить</string>
|
||||
<string name="skip_to_next">Перейти далее</string>
|
||||
<string name="start">Начать</string>
|
||||
<string name="start_next">Начать далее</string>
|
||||
<string name="stats">Статистика</string>
|
||||
<string name="stop">Стоп</string>
|
||||
<string name="stop_alarm">Сигнал остановки</string>
|
||||
<string name="stop_alarm_dialog_text">Текущая сессия завершена. Нажмите в любое место для остановки сигнала.</string>
|
||||
<string name="stop_alarm_question">Остановить сигнал?</string>
|
||||
<string name="system_default">Система</string>
|
||||
<string name="theme">Тема</string>
|
||||
<string name="timer">Таймер</string>
|
||||
<string name="timer_progress">Прогресс таймера</string>
|
||||
<string name="timer_session_count">%1$d из %2$d</string>
|
||||
<string name="today">Сегодня</string>
|
||||
<string name="up_next">Далее</string>
|
||||
<string name="up_next_notification">Далее: %1$s (%2$s)</string>
|
||||
<string name="vibrate">Вибрация</string>
|
||||
<string name="vibrate_desc">Вибрация при завершении таймера</string>
|
||||
<string name="weekly_productivity_analysis">Анализ недельной продуктивности</string>
|
||||
<string name="sound">Звук</string>
|
||||
<string name="dnd">Не беспокоить</string>
|
||||
<string name="dnd_desc">Включить режим Не беспокоить во время таймера фокусировки</string>
|
||||
<string name="get_plus">Получить Tomato+</string>
|
||||
<string name="dynamic_color">Динамические цвета</string>
|
||||
<string name="dynamic_color_desc">Использовать цвета темы в соответствии с вашими обоями</string>
|
||||
<string name="tomato_foss_desc">В этой версии разблокированы все функции. Если моё приложение изменило вашу жизнь, пожалуйста, рассмотрите возможность поддержать меня, сделав пожертвование на %1$s.</string>
|
||||
<string name="language">Язык</string>
|
||||
<string name="choose_language">Выбрать язык</string>
|
||||
<string name="rate_on_google_play">Оценить в Google Play</string>
|
||||
<string name="selected">Выбрано</string>
|
||||
<string name="durations">Длительности</string>
|
||||
<string name="appearance">Отображение</string>
|
||||
<string name="tomato_foss">Tomato (свободное и открытое программное обеспечение)</string>
|
||||
</resources>
|
||||
@@ -64,4 +64,13 @@
|
||||
<string name="sound">Ses</string>
|
||||
<string name="dnd">Rahatsız Etmeyin</string>
|
||||
<string name="dnd_desc">Odaklanma sayacı çalışırken RE\'yi aç</string>
|
||||
<string name="get_plus">Tomato+ edin</string>
|
||||
<string name="dynamic_color">Dinamik renk</string>
|
||||
<string name="dynamic_color_desc">Tema renklerini duvar kağıdınızdan alın</string>
|
||||
<string name="tomato_foss">Tomato FOSS</string>
|
||||
<string name="tomato_foss_desc">Bu sürümde tüm özelliklerin kilidi açılmıştır. Uygulamam hayatınızda bir fark yarattıysa, lütfen %1$s üzerinden bağış yaparak beni desteklemeyi düşünün.</string>
|
||||
<string name="language">Dil</string>
|
||||
<string name="choose_language">Dil seç</string>
|
||||
<string name="rate_on_google_play">Google Play\'de değerlendir</string>
|
||||
<string name="selected">Seçilen</string>
|
||||
</resources>
|
||||
|
||||
@@ -70,4 +70,8 @@
|
||||
<string name="dynamic_color_desc">Адаптуйте кольори теми зі своїх шпалер</string>
|
||||
<string name="tomato_foss">Tomato FOSS</string>
|
||||
<string name="tomato_foss_desc">Усі функції розблоковано в цій версії. Якщо мій додаток допоміг Вам у житті, будь ласка, підтримайте мене, зробивши пожертву на %1$s.</string>
|
||||
<string name="language">Мова</string>
|
||||
<string name="choose_language">Вибрати мову</string>
|
||||
<string name="rate_on_google_play">Оцінити на Google Play</string>
|
||||
<string name="selected">Обрано</string>
|
||||
</resources>
|
||||
|
||||
@@ -64,4 +64,13 @@
|
||||
<string name="sound">声音</string>
|
||||
<string name="dnd">勿扰模式</string>
|
||||
<string name="dnd_desc">运行「专注」计时器时打开勿扰</string>
|
||||
<string name="get_plus">获取 Tomato+</string>
|
||||
<string name="dynamic_color">动态颜色</string>
|
||||
<string name="dynamic_color_desc">从你的壁纸中提取主题色</string>
|
||||
<string name="tomato_foss">Tomato FOSS</string>
|
||||
<string name="tomato_foss_desc">所有功能在此版本中处于解锁状态。如果我的应用让你的生活有所不同,请考虑在 %1$s 上捐款支持我。</string>
|
||||
<string name="language">语言</string>
|
||||
<string name="choose_language">选择语言</string>
|
||||
<string name="rate_on_google_play">在 Google Play 上评价</string>
|
||||
<string name="selected">已选中</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,73 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="start">開始</string>
|
||||
<string name="stop">停止</string>
|
||||
<string name="focus">專注</string>
|
||||
<string name="short_break">短休息</string>
|
||||
<string name="long_break">長休息</string>
|
||||
<string name="exit">退出</string>
|
||||
<string name="skip">跳過</string>
|
||||
<string name="stop_alarm">停止鬧鐘</string>
|
||||
<string name="min_remaining_notification">剩餘%1$s</string>
|
||||
<string name="paused">已暫停</string>
|
||||
<string name="completed">已完成</string>
|
||||
<string name="up_next_notification">下一個: %1$s (%2$s)</string>
|
||||
<string name="start_next">開始下一個</string>
|
||||
<string name="choose_color_scheme">選擇配色方案</string>
|
||||
<string name="ok">好的</string>
|
||||
<string name="color_scheme">配色方案</string>
|
||||
<string name="dynamic">動態</string>
|
||||
<string name="color">顏色</string>
|
||||
<string name="system_default">系統</string>
|
||||
<string name="alarm">鬧鐘</string>
|
||||
<string name="light">亮色</string>
|
||||
<string name="dark">暗色</string>
|
||||
<string name="choose_theme">選擇主題</string>
|
||||
<string name="productivity_analysis">生產力分析</string>
|
||||
<string name="productivity_analysis_desc">一天中不同時間的專注持續時間</string>
|
||||
<string name="alarm_sound">鬧鐘鈴聲</string>
|
||||
<string name="alarm_desc">計時器結束時響鈴</string>
|
||||
<string name="alarm_sound">鬧鐘聲音</string>
|
||||
<string name="always_on_display">螢幕長亮模式</string>
|
||||
<string name="always_on_display_desc">在計時畫面任意點擊以切換至螢幕長亮模式</string>
|
||||
<string name="app_name">Tomato</string>
|
||||
<string name="black_theme">純黑主題</string>
|
||||
<string name="black_theme_desc">使用純黑色主題</string>
|
||||
<string name="alarm_desc">計時器完成時響起鬧鈴</string>
|
||||
<string name="vibrate">振動</string>
|
||||
<string name="vibrate_desc">當計時器完成時震動</string>
|
||||
<string name="theme">主题</string>
|
||||
<string name="settings">设置</string>
|
||||
<string name="session_length">会话时长</string>
|
||||
<string name="session_length_desc">单次专注时间间隔: %1$d</string>
|
||||
<string name="pomodoro_info">一个“会话”是由多个番茄钟组成的序列,其中包含专注时间段、短休息和长休息。一个会话中的最后一次休息必然是长休息。</string>
|
||||
<string name="stats">统计</string>
|
||||
<string name="today">今天</string>
|
||||
<string name="black_theme_desc">使用純黑的深色主題</string>
|
||||
<string name="break_">休息</string>
|
||||
<string name="last_week">上周</string>
|
||||
<string name="focus_per_day_avg">每天平均專注時間</string>
|
||||
<string name="more_info">更多資訊</string>
|
||||
<string name="weekly_productivity_analysis">每週生產力分析</string>
|
||||
<string name="last_month">上月</string>
|
||||
<string name="monthly_productivity_analysis">每月生产力分析</string>
|
||||
<string name="stop_alarm_question">停止鬧鐘?</string>
|
||||
<string name="stop_alarm_dialog_text">當前計時器會話已經完成。 點擊任意位置停止鬧鐘。</string>
|
||||
<string name="timer_session_count">%1$d of %2$d</string>
|
||||
<string name="choose_color_scheme">選擇配色方案</string>
|
||||
<string name="choose_theme">選擇主題</string>
|
||||
<string name="color">顏色</string>
|
||||
<string name="color_scheme">配色方案</string>
|
||||
<string name="completed">已完成</string>
|
||||
<string name="dark">深色</string>
|
||||
<string name="dynamic">動態</string>
|
||||
<string name="exit">離開</string>
|
||||
<string name="focus">專注</string>
|
||||
<string name="focus_per_day_avg">每日平均專注次數</string>
|
||||
<string name="last_month">上個月</string>
|
||||
<string name="last_week">上週</string>
|
||||
<string name="last_year">去年</string>
|
||||
<string name="light">淺色</string>
|
||||
<string name="long_break">長休息</string>
|
||||
<string name="min_remaining_notification">剩餘 %1$s 分鐘</string>
|
||||
<string name="monthly_productivity_analysis">每月生產力分析</string>
|
||||
<string name="more">更多</string>
|
||||
<string name="pause">暂停</string>
|
||||
<string name="play">开始</string>
|
||||
<string name="restart">重置</string>
|
||||
<string name="skip_to_next">跳至下一个</string>
|
||||
<string name="up_next">接下来</string>
|
||||
<string name="timer">计时</string>
|
||||
<string name="timer_progress">计时进度</string>
|
||||
<string name="last_year">上年</string>
|
||||
<string name="always_on_display">熄屏模式</string>
|
||||
<string name="more_info">更多資訊</string>
|
||||
<string name="ok">確定</string>
|
||||
<string name="pause">暫停</string>
|
||||
<string name="paused">已暫停</string>
|
||||
<string name="play">開始</string>
|
||||
<string name="pomodoro_info">「循環」是一系列番茄工作階段的組合,包含專注時間、短休息與長休息。每個循環的最後一段休息都是長休息。</string>
|
||||
<string name="productivity_analysis">生產力分析</string>
|
||||
<string name="productivity_analysis_desc">分析一天中不同時段的專注時長</string>
|
||||
<string name="restart">重新開始</string>
|
||||
<string name="session_length">循環長度</string>
|
||||
<string name="session_length_desc">每個循環中的專注次數:%1$d</string>
|
||||
<string name="settings">設定</string>
|
||||
<string name="short_break">短休息</string>
|
||||
<string name="skip">跳過</string>
|
||||
<string name="skip_to_next">跳至下一個</string>
|
||||
<string name="start">開始</string>
|
||||
<string name="start_next">開始下一個</string>
|
||||
<string name="stats">統計</string>
|
||||
<string name="stop">停止</string>
|
||||
<string name="stop_alarm">停止鬧鐘</string>
|
||||
<string name="stop_alarm_dialog_text">目前的計時已完成。輕觸螢幕任意位置以停止鬧鐘。</string>
|
||||
<string name="stop_alarm_question">要停止鬧鐘嗎?</string>
|
||||
<string name="system_default">系統預設</string>
|
||||
<string name="theme">主題</string>
|
||||
<string name="timer">計時器</string>
|
||||
<string name="timer_progress">計時進度</string>
|
||||
<string name="timer_session_count">第 %1$d / 共 %2$d</string>
|
||||
<string name="today">今天</string>
|
||||
<string name="up_next">下一個</string>
|
||||
<string name="up_next_notification">下一個:%1$s(%2$s)</string>
|
||||
<string name="vibrate">震動</string>
|
||||
<string name="vibrate_desc">計時器結束時震動提醒</string>
|
||||
<string name="weekly_productivity_analysis">每週生產力分析</string>
|
||||
<string name="appearance">外觀</string>
|
||||
<string name="always_on_display_desc">在查看計時器時,點擊任意位置即可切換至熄屏模式</string>
|
||||
<string name="durations">持續時間</string>
|
||||
<string name="durations">時長</string>
|
||||
<string name="sound">聲音</string>
|
||||
<string name="dnd">請勿打擾</string>
|
||||
<string name="dnd_desc">在執行專注計時器時開啟勿擾模式</string>
|
||||
<string name="get_plus">獲取 Tomato+</string>
|
||||
<string name="dnd_desc">執行專注計時器時自動開啟請勿打擾模式</string>
|
||||
<string name="app_name_plus">Tomato+</string>
|
||||
<string name="dynamic_color">動態顔色</string>
|
||||
<string name="dynamic_color_desc">調整主題顏色為你的壁紙顔色</string>
|
||||
<string name="get_plus">取得 Tomato+</string>
|
||||
<string name="dynamic_color">動態配色</string>
|
||||
<string name="dynamic_color_desc">根據桌布自動調整主題顏色</string>
|
||||
<string name="tomato_foss">Tomato FOSS</string>
|
||||
<string name="tomato_foss_desc">所有功能在此版本中均已解鎖。如果我的應用程式改變了您的生活,請考慮透過捐贈 %1$s 來支持我。</string>
|
||||
<string name="tomato_foss_desc">此版本已解鎖所有功能。若這個 App 對你有所幫助,歡迎至 %1$s 贊助支持開發者。</string>
|
||||
<string name="language">語言</string>
|
||||
<string name="choose_language">選擇語言</string>
|
||||
<string name="rate_on_google_play">在 Google Play 上評分</string>
|
||||
<string name="selected">已選擇</string>
|
||||
</resources>
|
||||
|
||||
@@ -87,4 +87,9 @@
|
||||
<string name="dynamic_color_desc">Adapt theme colors from your wallpaper</string>
|
||||
<string name="tomato_foss">Tomato FOSS</string>
|
||||
<string name="tomato_foss_desc">All features are unlocked in this version. If my app made a difference in your life, please consider supporting me by donating on %1$s.</string>
|
||||
<string name="language">Language</string>
|
||||
<string name="choose_language">Choose language</string>
|
||||
<string name="rate_on_google_play">Rate on Google Play</string>
|
||||
<string name="bmc">BuyMeACoffee</string>
|
||||
<string name="selected">Selected</string>
|
||||
</resources>
|
||||
@@ -1,6 +1,6 @@
|
||||
<i>Tomato</i> ist ein minimalistischer Pomodoro-Timer für Android, der auf Material 3 Expressive basiert.
|
||||
|
||||
Tomato ist vollständig kostenlos und Open Source, für immer. Unter https://github.com/nsh07/Tomato finden Sie den Quellcode und können Fehler melden oder Funktionen vorschlagen
|
||||
Tomato ist vollständig kostenlos und Open Source, für immer. Unter https://github.com/nsh07/Tomato finden Sie den Quellcode und können Fehler melden oder Funktionen vorschlagen
|
||||
|
||||
<b>Funktionen:</b>
|
||||
-Einfache, minimalistische Benutzeroberfläche, die auf den neuesten Material 3 Expressive-Richtlinien basiert
|
||||
|
||||
11
fastlane/metadata/android/en-US/changelogs/18.txt
Normal file
11
fastlane/metadata/android/en-US/changelogs/18.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
New features:
|
||||
- New redesigned alarm screen
|
||||
- New font used across the UI
|
||||
- Language selection for Android 13+
|
||||
|
||||
Fixes:
|
||||
- Fixed a crash that occurred when editing the time in settings
|
||||
- Clock now stays in place even when the time changes
|
||||
|
||||
Enhancements:
|
||||
- Updated translations
|
||||
@@ -1 +1,12 @@
|
||||
<p><i>Tomato</i> é um timer Pomodoro minimalista para Android baseado em Material 3 Expressive.</p><p><br><b>Funções:</b></p><ul><li>Simples, interface minimalista baseada nas últimas diretrizes do Material 3 Expressive</li><li>Estatísticas detalhadas de tempo de trabalho/estudo de um jeito fácil de entender<ul><li>Estatísticas do dia atual visíveis num relance</li><li>Estatísticas da última semana e do último mês mostrados de um jeito fácil de ler em um gráfico limpo</li><li>Estatísticas adicionais da última semana e mês mostrando que hora do dia você é mais produtivo</li></ul></li><li>Parâmetros do timer customizáveis</li></ul>
|
||||
<i>Tomato</i> é um timer Pomodoro minimalista para Android baseado em Material 3 Expressive.
|
||||
|
||||
Tomato é totalmente gratuito e de código aberto, para sempre. Você pode encontrar o código-fonte e reportar bugs ou sugerir melhorias em https://github.com/nsh07/Tomato
|
||||
|
||||
<b>Funções:</b>
|
||||
- Simples, interface minimalista baseada nas últimas diretrizes do Material 3 Expressive
|
||||
- Estatísticas detalhadas de tempo de trabalho/estudo de um jeito fácil de entender
|
||||
- Estatísticas do dia atual visíveis num relance
|
||||
- Estatísticas da última semana e do último mês mostrados de um jeito fácil de ler em um gráfico limpo
|
||||
- Estatísticas adicionais da última semana e mês mostrando que hora do dia você é mais produtivo
|
||||
- Parâmetros do timer customizáveis
|
||||
- Suporte para as últimas atualizações do Android 16
|
||||
|
||||
12
fastlane/metadata/android/ru-RU/full_description.txt
Normal file
12
fastlane/metadata/android/ru-RU/full_description.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
<i>Tomato</i> — это минималистичный помодоро таймер для Android, основанный на Material 3 Expressive.
|
||||
|
||||
Tomato полностью бесплатный и open-source для всех. Вы можете найти исходный код и сообщить о проблемах или предложить функции на https://github.com/nsh07/Tomato
|
||||
|
||||
<b>Особенности:</b>
|
||||
- Простой и минималистичный интерфейс, основанный на последних рекомендациях Material 3 Expressive
|
||||
- Детальная статистика времени работы/учёбы в лёгкой для понимания форме
|
||||
- Статистика текущего дня видна сразу
|
||||
- Статистика за последнюю неделю и месяц показана на легко читаемом, чистом графике
|
||||
- Дополнительная статистика за последнюю неделю и месяц, показывающая, в какое время дня вы наиболее продуктивны
|
||||
- Настраиваемые параметры таймера
|
||||
- Поддержка Android 16 Live Updates
|
||||
1
fastlane/metadata/android/ru-RU/short_description.txt
Normal file
1
fastlane/metadata/android/ru-RU/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Минималистичный помодоро таймер
|
||||
@@ -1,6 +1,6 @@
|
||||
<i>Tomato</i> - мінімалістичний Pomodoro таймер для Android на базі Material 3 Expressive.
|
||||
|
||||
Tomato повністю безкоштовний та з відкритим вихідним кодом. Ви можете знайти вихідний код і повідомляти про помилки й пропонувати функції на GitHub: https://github.com/nsh07/Tomato.
|
||||
Tomato повністю безкоштовний та з відкритим вихідним кодом, назавжди. Ви можете знайти вихідний код і повідомляти про помилки й пропонувати функції на GitHub: https://github.com/nsh07/Tomato.
|
||||
|
||||
<b>Особливості:</b>
|
||||
- Простий, мінімалістичний інтерфейс на основі останніх рекомендацій Material 3 Expressive
|
||||
|
||||
Reference in New Issue
Block a user