Merge branch 'dev'
This commit is contained in:
@@ -33,8 +33,8 @@ android {
|
||||
applicationId = "org.nsh07.pomodoro"
|
||||
minSdk = 26
|
||||
targetSdk = 36
|
||||
versionCode = 11
|
||||
versionName = "1.4.3"
|
||||
versionCode = 12
|
||||
versionName = "1.5.0-alpha01"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class TomatoApplication : Application() {
|
||||
val notificationChannel = NotificationChannel(
|
||||
"timer",
|
||||
getString(R.string.timer_progress),
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
NotificationManager.IMPORTANCE_DEFAULT
|
||||
)
|
||||
|
||||
container.notificationManager.createNotificationChannel(notificationChannel)
|
||||
|
||||
@@ -68,7 +68,7 @@ fun AppScreen(
|
||||
val motionScheme = motionScheme
|
||||
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
|
||||
|
||||
val backStack = rememberNavBackStack<Screen>(Screen.Timer)
|
||||
val backStack = rememberNavBackStack(Screen.Timer)
|
||||
|
||||
if (uiState.alarmRinging)
|
||||
AlarmDialog {
|
||||
|
||||
@@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.text.TextAutoSize
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.FilledTonalIconToggleButton
|
||||
@@ -31,10 +32,12 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||
import androidx.compose.material3.MaterialTheme.motionScheme
|
||||
import androidx.compose.material3.MaterialTheme.typography
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -46,7 +49,6 @@ import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@@ -55,14 +57,14 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.columnSeries
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.lineSeries
|
||||
import com.patrykandpatrick.vico.core.common.data.ExtraStore
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.nsh07.pomodoro.R
|
||||
import org.nsh07.pomodoro.data.Stat
|
||||
import org.nsh07.pomodoro.data.StatFocusTime
|
||||
import org.nsh07.pomodoro.ui.statsScreen.viewModel.StatsViewModel
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.openRundeClock
|
||||
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
|
||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||
import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes
|
||||
|
||||
@Composable
|
||||
@@ -72,20 +74,25 @@ fun StatsScreenRoot(
|
||||
viewModel: StatsViewModel = viewModel(factory = StatsViewModel.Factory)
|
||||
) {
|
||||
val todayStat by viewModel.todayStat.collectAsStateWithLifecycle(null)
|
||||
val lastWeekAverageFocusTimes by viewModel
|
||||
.lastWeekAverageFocusTimes.collectAsStateWithLifecycle(null)
|
||||
val lastMonthAverageFocusTimes by viewModel
|
||||
.lastMonthAverageFocusTimes.collectAsStateWithLifecycle(null)
|
||||
|
||||
val lastWeekSummaryChartData by viewModel.lastWeekSummaryChartData.collectAsStateWithLifecycle()
|
||||
val lastWeekAnalysisValues by viewModel.lastWeekAverageFocusTimes.collectAsStateWithLifecycle()
|
||||
|
||||
val lastMonthSummaryChartData by viewModel.lastMonthSummaryChartData.collectAsStateWithLifecycle()
|
||||
val lastMonthAnalysisValues by viewModel.lastMonthAverageFocusTimes.collectAsStateWithLifecycle()
|
||||
|
||||
val lastYearSummaryChartData by viewModel.lastYearSummaryChartData.collectAsStateWithLifecycle()
|
||||
val lastYearAnalysisValues by viewModel.lastYearAverageFocusTimes.collectAsStateWithLifecycle()
|
||||
|
||||
StatsScreen(
|
||||
contentPadding = contentPadding,
|
||||
lastWeekSummaryChartData = remember { viewModel.lastWeekSummaryChartData },
|
||||
lastWeekSummaryAnalysisModelProducer = remember { viewModel.lastWeekSummaryAnalysisModelProducer },
|
||||
lastMonthSummaryChartData = remember { viewModel.lastMonthSummaryChartData },
|
||||
lastMonthSummaryAnalysisModelProducer = remember { viewModel.lastMonthSummaryAnalysisModelProducer },
|
||||
lastWeekSummaryChartData = lastWeekSummaryChartData,
|
||||
lastMonthSummaryChartData = lastMonthSummaryChartData,
|
||||
lastYearSummaryChartData = lastYearSummaryChartData,
|
||||
todayStat = todayStat,
|
||||
lastWeekAverageFocusTimes = lastWeekAverageFocusTimes,
|
||||
lastMonthAverageFocusTimes = lastMonthAverageFocusTimes,
|
||||
lastWeekAverageFocusTimes = lastWeekAnalysisValues,
|
||||
lastMonthAverageFocusTimes = lastMonthAnalysisValues,
|
||||
lastYearAverageFocusTimes = lastYearAnalysisValues,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
@@ -95,12 +102,12 @@ fun StatsScreenRoot(
|
||||
fun StatsScreen(
|
||||
contentPadding: PaddingValues,
|
||||
lastWeekSummaryChartData: Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>,
|
||||
lastWeekSummaryAnalysisModelProducer: CartesianChartModelProducer,
|
||||
lastMonthSummaryChartData: Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>,
|
||||
lastMonthSummaryAnalysisModelProducer: CartesianChartModelProducer,
|
||||
lastYearSummaryChartData: Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>,
|
||||
todayStat: Stat?,
|
||||
lastWeekAverageFocusTimes: StatFocusTime?,
|
||||
lastMonthAverageFocusTimes: StatFocusTime?,
|
||||
lastWeekAverageFocusTimes: List<Int>,
|
||||
lastMonthAverageFocusTimes: List<Int>,
|
||||
lastYearAverageFocusTimes: List<Int>,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
@@ -108,6 +115,25 @@ fun StatsScreen(
|
||||
var lastWeekStatExpanded by rememberSaveable { mutableStateOf(false) }
|
||||
var lastMonthStatExpanded by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
val lastWeekSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() }
|
||||
val lastMonthSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() }
|
||||
|
||||
LaunchedEffect(lastWeekAverageFocusTimes) {
|
||||
lastWeekSummaryAnalysisModelProducer.runTransaction {
|
||||
columnSeries {
|
||||
series(lastWeekAverageFocusTimes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(lastMonthAverageFocusTimes) {
|
||||
lastMonthSummaryAnalysisModelProducer.runTransaction {
|
||||
columnSeries {
|
||||
series(lastMonthAverageFocusTimes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
@@ -168,7 +194,9 @@ fun StatsScreen(
|
||||
},
|
||||
style = typography.displaySmall,
|
||||
fontFamily = openRundeClock,
|
||||
color = colorScheme.onPrimaryContainer
|
||||
color = colorScheme.onPrimaryContainer,
|
||||
maxLines = 1,
|
||||
autoSize = TextAutoSize.StepBased(maxFontSize = typography.displaySmall.fontSize)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -193,7 +221,9 @@ fun StatsScreen(
|
||||
},
|
||||
style = typography.displaySmall,
|
||||
fontFamily = openRundeClock,
|
||||
color = colorScheme.onTertiaryContainer
|
||||
color = colorScheme.onTertiaryContainer,
|
||||
maxLines = 1,
|
||||
autoSize = TextAutoSize.StepBased(maxFontSize = typography.displaySmall.fontSize)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -218,7 +248,11 @@ fun StatsScreen(
|
||||
.padding(horizontal = 16.dp)
|
||||
) {
|
||||
Text(
|
||||
millisecondsToHoursMinutes(lastWeekAverageFocusTimes?.total() ?: 0),
|
||||
millisecondsToHoursMinutes(
|
||||
remember(lastWeekAverageFocusTimes) {
|
||||
lastWeekAverageFocusTimes.sum().toLong()
|
||||
}
|
||||
),
|
||||
style = typography.displaySmall,
|
||||
fontFamily = openRundeClock
|
||||
)
|
||||
@@ -290,7 +324,11 @@ fun StatsScreen(
|
||||
.padding(horizontal = 16.dp)
|
||||
) {
|
||||
Text(
|
||||
millisecondsToHoursMinutes(lastMonthAverageFocusTimes?.total() ?: 0),
|
||||
millisecondsToHoursMinutes(
|
||||
remember(lastMonthAverageFocusTimes) {
|
||||
lastMonthAverageFocusTimes.sum().toLong()
|
||||
}
|
||||
),
|
||||
style = typography.displaySmall,
|
||||
fontFamily = openRundeClock
|
||||
)
|
||||
@@ -343,36 +381,85 @@ fun StatsScreen(
|
||||
modifier = Modifier.padding(horizontal = 32.dp)
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.height(16.dp))
|
||||
}
|
||||
item { Spacer(Modifier) }
|
||||
item {
|
||||
Text(
|
||||
stringResource(R.string.last_year),
|
||||
style = typography.headlineSmall,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp)
|
||||
)
|
||||
}
|
||||
item {
|
||||
Row(
|
||||
verticalAlignment = Alignment.Bottom,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp)
|
||||
) {
|
||||
Text(
|
||||
millisecondsToHoursMinutes(
|
||||
remember(lastYearAverageFocusTimes) {
|
||||
lastYearAverageFocusTimes.sum().toLong()
|
||||
}
|
||||
),
|
||||
style = typography.displaySmall,
|
||||
fontFamily = openRundeClock
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.focus_per_day_avg),
|
||||
style = typography.titleSmall,
|
||||
modifier = Modifier.padding(bottom = 6.3.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
TimeLineChart(
|
||||
lastYearSummaryChartData.first,
|
||||
modifier = Modifier.padding(start = 16.dp),
|
||||
xValueFormatter = CartesianValueFormatter { context, x, _ ->
|
||||
context.model.extraStore[lastYearSummaryChartData.second][x.toInt()]
|
||||
}
|
||||
)
|
||||
}
|
||||
item { Spacer(Modifier.height(16.dp)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(
|
||||
showSystemUi = true,
|
||||
device = Devices.PIXEL_9_PRO
|
||||
widthDp = 400
|
||||
)
|
||||
@Composable
|
||||
fun StatsScreenPreview() {
|
||||
val modelProducer = remember { CartesianChartModelProducer() }
|
||||
val keys = remember { ExtraStore.Key<List<String>>() }
|
||||
|
||||
runBlocking {
|
||||
LaunchedEffect(Unit) {
|
||||
modelProducer.runTransaction {
|
||||
columnSeries {
|
||||
series(5, 6, 5, 2, 11, 8, 5, 2, 15, 11, 8, 13, 12, 10, 2, 7)
|
||||
series(5, 6, 5, 2, 11, 8, 5)
|
||||
}
|
||||
lineSeries {}
|
||||
extras { it[keys] = listOf("M", "T", "W", "T", "F", "S", "S") }
|
||||
}
|
||||
}
|
||||
|
||||
StatsScreen(
|
||||
PaddingValues(),
|
||||
Pair(modelProducer, ExtraStore.Key()),
|
||||
modelProducer,
|
||||
Pair(modelProducer, ExtraStore.Key()),
|
||||
modelProducer,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
TomatoTheme {
|
||||
Surface {
|
||||
StatsScreen(
|
||||
PaddingValues(),
|
||||
Pair(modelProducer, keys),
|
||||
Pair(modelProducer, keys),
|
||||
Pair(modelProducer, keys),
|
||||
null,
|
||||
listOf(0, 0, 0, 0),
|
||||
listOf(0, 0, 0, 0),
|
||||
listOf(0, 0, 0, 0)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,12 @@ package org.nsh07.pomodoro.ui.statsScreen
|
||||
import androidx.compose.animation.core.AnimationSpec
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialTheme.motionScheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost
|
||||
@@ -25,20 +29,23 @@ import com.patrykandpatrick.vico.compose.common.component.rememberLineComponent
|
||||
import com.patrykandpatrick.vico.compose.common.fill
|
||||
import com.patrykandpatrick.vico.compose.common.vicoTheme
|
||||
import com.patrykandpatrick.vico.compose.m3.common.rememberM3VicoTheme
|
||||
import com.patrykandpatrick.vico.core.cartesian.FadingEdges
|
||||
import com.patrykandpatrick.vico.core.cartesian.Zoom
|
||||
import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis
|
||||
import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.columnSeries
|
||||
import com.patrykandpatrick.vico.core.cartesian.layer.ColumnCartesianLayer
|
||||
import com.patrykandpatrick.vico.core.common.Fill
|
||||
import com.patrykandpatrick.vico.core.common.shape.CorneredShape
|
||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||
import org.nsh07.pomodoro.utils.millisecondsToHours
|
||||
import org.nsh07.pomodoro.utils.millisecondsToMinutes
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
internal fun TimeColumnChart(
|
||||
fun TimeColumnChart(
|
||||
modelProducer: CartesianChartModelProducer,
|
||||
modifier: Modifier = Modifier,
|
||||
thickness: Dp = 40.dp,
|
||||
@@ -80,7 +87,8 @@ internal fun TimeColumnChart(
|
||||
tick = rememberLineComponent(Fill.Transparent),
|
||||
guideline = rememberLineComponent(Fill.Transparent),
|
||||
valueFormatter = xValueFormatter
|
||||
)
|
||||
),
|
||||
fadingEdges = FadingEdges()
|
||||
),
|
||||
modelProducer = modelProducer,
|
||||
zoomState = rememberVicoZoomState(
|
||||
@@ -92,4 +100,26 @@ internal fun TimeColumnChart(
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun TimeColumnChartPreview() {
|
||||
val modelProducer = remember { CartesianChartModelProducer() }
|
||||
val values = mutableListOf<Int>()
|
||||
LaunchedEffect(Unit) {
|
||||
repeat(30) {
|
||||
values.add((0..120).random() * 60 * 1000)
|
||||
}
|
||||
modelProducer.runTransaction {
|
||||
columnSeries {
|
||||
series(values)
|
||||
}
|
||||
}
|
||||
}
|
||||
TomatoTheme {
|
||||
Surface {
|
||||
TimeColumnChart(thickness = 8.dp, modelProducer = modelProducer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package org.nsh07.pomodoro.ui.statsScreen
|
||||
|
||||
import androidx.compose.animation.core.AnimationSpec
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialTheme.motionScheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost
|
||||
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberBottom
|
||||
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberStart
|
||||
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLine
|
||||
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLayer
|
||||
import com.patrykandpatrick.vico.compose.cartesian.rememberCartesianChart
|
||||
import com.patrykandpatrick.vico.compose.cartesian.rememberVicoZoomState
|
||||
import com.patrykandpatrick.vico.compose.common.ProvideVicoTheme
|
||||
import com.patrykandpatrick.vico.compose.common.component.rememberLineComponent
|
||||
import com.patrykandpatrick.vico.compose.common.fill
|
||||
import com.patrykandpatrick.vico.compose.common.vicoTheme
|
||||
import com.patrykandpatrick.vico.compose.m3.common.rememberM3VicoTheme
|
||||
import com.patrykandpatrick.vico.core.cartesian.FadingEdges
|
||||
import com.patrykandpatrick.vico.core.cartesian.Zoom
|
||||
import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis
|
||||
import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.lineSeries
|
||||
import com.patrykandpatrick.vico.core.cartesian.layer.LineCartesianLayer
|
||||
import com.patrykandpatrick.vico.core.cartesian.layer.LineCartesianLayer.LineFill.Companion.single
|
||||
import com.patrykandpatrick.vico.core.common.Fill
|
||||
import com.patrykandpatrick.vico.core.common.shader.ShaderProvider
|
||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||
import org.nsh07.pomodoro.utils.millisecondsToHours
|
||||
import org.nsh07.pomodoro.utils.millisecondsToMinutes
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun TimeLineChart(
|
||||
modelProducer: CartesianChartModelProducer,
|
||||
modifier: Modifier = Modifier,
|
||||
thickness: Float = 2f,
|
||||
pointSpacing: Dp = 12.dp,
|
||||
xValueFormatter: CartesianValueFormatter = CartesianValueFormatter.Default,
|
||||
yValueFormatter: CartesianValueFormatter = CartesianValueFormatter { _, value, _ ->
|
||||
if (value >= 60 * 60 * 1000) {
|
||||
millisecondsToHours(value.toLong())
|
||||
} else {
|
||||
millisecondsToMinutes(value.toLong())
|
||||
}
|
||||
},
|
||||
animationSpec: AnimationSpec<Float>? = motionScheme.slowEffectsSpec()
|
||||
) {
|
||||
ProvideVicoTheme(rememberM3VicoTheme()) {
|
||||
CartesianChartHost(
|
||||
chart =
|
||||
rememberCartesianChart(
|
||||
rememberLineCartesianLayer(
|
||||
LineCartesianLayer.LineProvider.series(
|
||||
vicoTheme.lineCartesianLayerColors.map { color ->
|
||||
LineCartesianLayer.rememberLine(
|
||||
fill = single(fill(color)),
|
||||
stroke = LineCartesianLayer.LineStroke.Continuous(
|
||||
thicknessDp = thickness,
|
||||
),
|
||||
areaFill = LineCartesianLayer.AreaFill.single(
|
||||
fill(
|
||||
ShaderProvider.verticalGradient(
|
||||
color.toArgb(),
|
||||
Color.Transparent.toArgb()
|
||||
)
|
||||
)
|
||||
),
|
||||
pointConnector = LineCartesianLayer.PointConnector.cubic(0.5f)
|
||||
)
|
||||
}
|
||||
),
|
||||
pointSpacing = pointSpacing
|
||||
),
|
||||
startAxis = VerticalAxis.rememberStart(
|
||||
line = rememberLineComponent(Fill.Transparent),
|
||||
tick = rememberLineComponent(Fill.Transparent),
|
||||
guideline = rememberLineComponent(Fill.Transparent),
|
||||
valueFormatter = yValueFormatter
|
||||
),
|
||||
bottomAxis = HorizontalAxis.rememberBottom(
|
||||
rememberLineComponent(Fill.Transparent),
|
||||
tick = rememberLineComponent(Fill.Transparent),
|
||||
guideline = rememberLineComponent(Fill.Transparent),
|
||||
valueFormatter = xValueFormatter
|
||||
),
|
||||
fadingEdges = FadingEdges()
|
||||
),
|
||||
modelProducer = modelProducer,
|
||||
zoomState = rememberVicoZoomState(
|
||||
zoomEnabled = true,
|
||||
initialZoom = Zoom.fixed(),
|
||||
minZoom = Zoom.min(Zoom.Content, Zoom.fixed())
|
||||
),
|
||||
animationSpec = animationSpec,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Preview
|
||||
@Composable
|
||||
private fun TimeLineChartPreview() {
|
||||
val modelProducer = remember { CartesianChartModelProducer() }
|
||||
val values = mutableListOf<Int>()
|
||||
LaunchedEffect(Unit) {
|
||||
repeat(365) {
|
||||
values.add((0..120).random() * 60 * 1000)
|
||||
}
|
||||
modelProducer.runTransaction {
|
||||
lineSeries {
|
||||
series(values)
|
||||
}
|
||||
}
|
||||
}
|
||||
TomatoTheme {
|
||||
Surface {
|
||||
TimeLineChart(modelProducer = modelProducer)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,16 @@ import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.columnSeries
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.lineSeries
|
||||
import com.patrykandpatrick.vico.core.common.data.ExtraStore
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import org.nsh07.pomodoro.TomatoApplication
|
||||
import org.nsh07.pomodoro.data.StatRepository
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.format.TextStyle
|
||||
import java.util.Locale
|
||||
|
||||
@@ -29,83 +33,123 @@ class StatsViewModel(
|
||||
) : ViewModel() {
|
||||
|
||||
val todayStat = statRepository.getTodayStat().distinctUntilChanged()
|
||||
private val lastWeekStatsSummary = statRepository.getLastNDaysStatsSummary(7)
|
||||
val lastWeekAverageFocusTimes =
|
||||
statRepository.getLastNDaysAverageFocusTimes(7).distinctUntilChanged()
|
||||
private val lastMonthStatsSummary = statRepository.getLastNDaysStatsSummary(30)
|
||||
val lastMonthAverageFocusTimes =
|
||||
statRepository.getLastNDaysAverageFocusTimes(30).distinctUntilChanged()
|
||||
|
||||
val lastWeekSummaryChartData =
|
||||
private val lastWeekSummary =
|
||||
Pair(CartesianChartModelProducer(), ExtraStore.Key<List<String>>())
|
||||
val lastWeekSummaryAnalysisModelProducer = CartesianChartModelProducer()
|
||||
|
||||
val lastMonthSummaryChartData =
|
||||
private val lastMonthSummary =
|
||||
Pair(CartesianChartModelProducer(), ExtraStore.Key<List<String>>())
|
||||
private val lastYearSummary =
|
||||
Pair(CartesianChartModelProducer(), ExtraStore.Key<List<String>>())
|
||||
val lastMonthSummaryAnalysisModelProducer = CartesianChartModelProducer()
|
||||
|
||||
init {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
lastWeekStatsSummary
|
||||
.collect { list ->
|
||||
// reversing is required because we need ascending order while the DB returns descending order
|
||||
val reversed = list.reversed()
|
||||
val keys = reversed.map {
|
||||
it.date.dayOfWeek.getDisplayName(
|
||||
TextStyle.NARROW,
|
||||
Locale.getDefault()
|
||||
)
|
||||
}
|
||||
val values = reversed.map { it.focusTime }
|
||||
lastWeekSummaryChartData.first.runTransaction {
|
||||
columnSeries { series(values) }
|
||||
extras { it[lastWeekSummaryChartData.second] = keys }
|
||||
}
|
||||
private val yearDayFormatter = DateTimeFormatter.ofPattern("d MMM")
|
||||
|
||||
val lastWeekSummaryChartData: StateFlow<Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>> =
|
||||
statRepository.getLastNDaysStatsSummary(7)
|
||||
.map { list ->
|
||||
// reversing is required because we need ascending order while the DB returns descending order
|
||||
val reversed = list.reversed()
|
||||
val keys = reversed.map {
|
||||
it.date.dayOfWeek.getDisplayName(
|
||||
TextStyle.NARROW,
|
||||
Locale.getDefault()
|
||||
)
|
||||
}
|
||||
}
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
lastWeekAverageFocusTimes
|
||||
.collect {
|
||||
lastWeekSummaryAnalysisModelProducer.runTransaction {
|
||||
columnSeries {
|
||||
series(
|
||||
it?.focusTimeQ1 ?: 0,
|
||||
it?.focusTimeQ2 ?: 0,
|
||||
it?.focusTimeQ3 ?: 0,
|
||||
it?.focusTimeQ4 ?: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
val values = reversed.map { it.focusTime }
|
||||
lastWeekSummary.first.runTransaction {
|
||||
columnSeries { series(values) }
|
||||
extras { it[lastWeekSummary.second] = keys }
|
||||
}
|
||||
}
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
lastMonthStatsSummary
|
||||
.collect { list ->
|
||||
val reversed = list.reversed()
|
||||
val keys = reversed.map { it.date.dayOfMonth.toString() }
|
||||
val values = reversed.map { it.focusTime }
|
||||
lastMonthSummaryChartData.first.runTransaction {
|
||||
columnSeries { series(values) }
|
||||
extras { it[lastMonthSummaryChartData.second] = keys }
|
||||
}
|
||||
lastWeekSummary
|
||||
}
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5000),
|
||||
initialValue = lastWeekSummary
|
||||
)
|
||||
|
||||
val lastWeekAverageFocusTimes: StateFlow<List<Int>> =
|
||||
statRepository.getLastNDaysAverageFocusTimes(7)
|
||||
.map {
|
||||
listOf(
|
||||
it?.focusTimeQ1?.toInt() ?: 0,
|
||||
it?.focusTimeQ2?.toInt() ?: 0,
|
||||
it?.focusTimeQ3?.toInt() ?: 0,
|
||||
it?.focusTimeQ4?.toInt() ?: 0
|
||||
)
|
||||
}
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5000),
|
||||
initialValue = listOf(0, 0, 0, 0)
|
||||
)
|
||||
|
||||
val lastMonthSummaryChartData: StateFlow<Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>> =
|
||||
statRepository.getLastNDaysStatsSummary(30)
|
||||
.map { list ->
|
||||
val reversed = list.reversed()
|
||||
val keys = reversed.map { it.date.dayOfMonth.toString() }
|
||||
val values = reversed.map { it.focusTime }
|
||||
lastMonthSummary.first.runTransaction {
|
||||
columnSeries { series(values) }
|
||||
extras { it[lastMonthSummary.second] = keys }
|
||||
}
|
||||
}
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
lastMonthAverageFocusTimes
|
||||
.collect {
|
||||
lastMonthSummaryAnalysisModelProducer.runTransaction {
|
||||
columnSeries {
|
||||
series(
|
||||
it?.focusTimeQ1 ?: 0,
|
||||
it?.focusTimeQ2 ?: 0,
|
||||
it?.focusTimeQ3 ?: 0,
|
||||
it?.focusTimeQ4 ?: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
lastMonthSummary
|
||||
}
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5000),
|
||||
initialValue = lastMonthSummary
|
||||
)
|
||||
|
||||
val lastMonthAverageFocusTimes: StateFlow<List<Int>> =
|
||||
statRepository.getLastNDaysAverageFocusTimes(30)
|
||||
.map {
|
||||
listOf(
|
||||
it?.focusTimeQ1?.toInt() ?: 0,
|
||||
it?.focusTimeQ2?.toInt() ?: 0,
|
||||
it?.focusTimeQ3?.toInt() ?: 0,
|
||||
it?.focusTimeQ4?.toInt() ?: 0
|
||||
)
|
||||
}
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5000),
|
||||
initialValue = listOf(0, 0, 0, 0)
|
||||
)
|
||||
|
||||
val lastYearSummaryChartData: StateFlow<Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>> =
|
||||
statRepository.getLastNDaysStatsSummary(365)
|
||||
.map { list ->
|
||||
val reversed = list.reversed()
|
||||
val keys = reversed.map { it.date.format(yearDayFormatter) }
|
||||
val values = reversed.map { it.focusTime }
|
||||
lastYearSummary.first.runTransaction {
|
||||
lineSeries { series(values) }
|
||||
extras { it[lastYearSummary.second] = keys }
|
||||
}
|
||||
}
|
||||
}
|
||||
lastYearSummary
|
||||
}
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5000),
|
||||
initialValue = lastYearSummary
|
||||
)
|
||||
|
||||
val lastYearAverageFocusTimes: StateFlow<List<Int>> =
|
||||
statRepository.getLastNDaysAverageFocusTimes(365)
|
||||
.map {
|
||||
listOf(
|
||||
it?.focusTimeQ1?.toInt() ?: 0,
|
||||
it?.focusTimeQ2?.toInt() ?: 0,
|
||||
it?.focusTimeQ3?.toInt() ?: 0,
|
||||
it?.focusTimeQ4?.toInt() ?: 0
|
||||
)
|
||||
}
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5000),
|
||||
initialValue = listOf(0, 0, 0, 0)
|
||||
)
|
||||
|
||||
companion object {
|
||||
val Factory: ViewModelProvider.Factory = viewModelFactory {
|
||||
|
||||
@@ -35,7 +35,10 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.ButtonGroup
|
||||
import androidx.compose.material3.ButtonGroupDefaults
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.CircularWavyProgressIndicator
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
@@ -49,8 +52,10 @@ import androidx.compose.material3.MaterialTheme.colorScheme
|
||||
import androidx.compose.material3.MaterialTheme.motionScheme
|
||||
import androidx.compose.material3.MaterialTheme.shapes
|
||||
import androidx.compose.material3.MaterialTheme.typography
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -64,6 +69,7 @@ import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.StrokeCap
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.res.painterResource
|
||||
@@ -115,7 +121,9 @@ fun TimerScreen(
|
||||
onResult = {}
|
||||
)
|
||||
|
||||
Column(modifier = modifier) {
|
||||
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||
|
||||
Column(modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) {
|
||||
TopAppBar(
|
||||
title = {
|
||||
AnimatedContent(
|
||||
@@ -140,7 +148,7 @@ fun TimerScreen(
|
||||
fontFamily = robotoFlexTopBar,
|
||||
fontSize = 32.sp,
|
||||
lineHeight = 32.sp,
|
||||
color = colorScheme.onErrorContainer
|
||||
color = colorScheme.error
|
||||
),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.width(210.dp)
|
||||
@@ -153,7 +161,7 @@ fun TimerScreen(
|
||||
fontFamily = robotoFlexTopBar,
|
||||
fontSize = 32.sp,
|
||||
lineHeight = 32.sp,
|
||||
color = colorScheme.onPrimaryContainer
|
||||
color = colorScheme.primary
|
||||
),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.width(210.dp)
|
||||
@@ -165,7 +173,7 @@ fun TimerScreen(
|
||||
fontFamily = robotoFlexTopBar,
|
||||
fontSize = 32.sp,
|
||||
lineHeight = 32.sp,
|
||||
color = colorScheme.onTertiaryContainer
|
||||
color = colorScheme.tertiary
|
||||
),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.width(210.dp)
|
||||
@@ -177,7 +185,7 @@ fun TimerScreen(
|
||||
fontFamily = robotoFlexTopBar,
|
||||
fontSize = 32.sp,
|
||||
lineHeight = 32.sp,
|
||||
color = colorScheme.onTertiaryContainer
|
||||
color = colorScheme.tertiary
|
||||
),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.width(210.dp)
|
||||
@@ -186,13 +194,16 @@ fun TimerScreen(
|
||||
}
|
||||
},
|
||||
subtitle = {},
|
||||
titleHorizontalAlignment = CenterHorizontally
|
||||
titleHorizontalAlignment = CenterHorizontally,
|
||||
scrollBehavior = scrollBehavior
|
||||
)
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = CenterHorizontally,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
Column(horizontalAlignment = CenterHorizontally) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
@@ -277,27 +288,11 @@ fun TimerScreen(
|
||||
val interactionSources = remember { List(3) { MutableInteractionSource() } }
|
||||
ButtonGroup(
|
||||
overflowIndicator = { state ->
|
||||
FilledTonalIconButton(
|
||||
onClick = {
|
||||
if (state.isExpanded) {
|
||||
state.dismiss()
|
||||
} else {
|
||||
state.show()
|
||||
}
|
||||
},
|
||||
colors = IconButtonDefaults.filledTonalIconButtonColors(
|
||||
containerColor = colorContainer
|
||||
),
|
||||
shapes = IconButtonDefaults.shapes(),
|
||||
modifier = Modifier
|
||||
.size(64.dp, 96.dp)
|
||||
) {
|
||||
Icon(
|
||||
painterResource(R.drawable.more_vert_large),
|
||||
contentDescription = stringResource(R.string.more),
|
||||
modifier = Modifier.size(32.dp)
|
||||
)
|
||||
}
|
||||
ButtonGroupDefaults.OverflowIndicator(
|
||||
state,
|
||||
colors = IconButtonDefaults.filledTonalIconButtonColors(),
|
||||
modifier = Modifier.size(64.dp, 96.dp)
|
||||
)
|
||||
},
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
@@ -509,6 +504,8 @@ fun TimerScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(16.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,10 +520,12 @@ fun TimerScreenPreview() {
|
||||
timeStr = "03:34", nextTimeStr = "5:00", timerMode = TimerMode.FOCUS, timerRunning = true
|
||||
)
|
||||
TomatoTheme {
|
||||
TimerScreen(
|
||||
timerState,
|
||||
{ 0.3f },
|
||||
{}
|
||||
)
|
||||
Surface {
|
||||
TimerScreen(
|
||||
timerState,
|
||||
{ 0.3f },
|
||||
{}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
3
app/src/main/res/values-ar/strings.xml
Normal file
3
app/src/main/res/values-ar/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
38
app/src/main/res/values-b+nan+Hant/strings.xml
Normal file
38
app/src/main/res/values-b+nan+Hant/strings.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?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="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="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="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>
|
||||
</resources>
|
||||
39
app/src/main/res/values-ckb/strings.xml
Normal file
39
app/src/main/res/values-ckb/strings.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?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="ok">باشە</string>
|
||||
<string name="color_scheme">ڕەنگی رووکار</string>
|
||||
<string name="dynamic">داینامیکی</string>
|
||||
<string name="color">ڕەنگ</string>
|
||||
<string name="choose_color_scheme">ڕەنگی ڕووکار هەڵبژێرە</string>
|
||||
<string name="system_default">وەک سیستەم</string>
|
||||
<string name="alarm">زەنگی ئاگادارکردنەوە</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="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="light">ڕووناک</string>
|
||||
<string name="theme">ڕووکار</string>
|
||||
<string name="settings">ڕێکخستنەکان</string>
|
||||
<string name="today">ئەمڕۆ</string>
|
||||
<string name="break_">پشوو</string>
|
||||
<string name="last_week">هەفتەی ڕابردوو</string>
|
||||
<string name="more">زیاتر</string>
|
||||
<string name="stats">ئامار</string>
|
||||
<string name="more_info">زانیاری زیاتر</string>
|
||||
<string name="pause">وەستاندن</string>
|
||||
</resources>
|
||||
5
app/src/main/res/values-cs/strings.xml
Normal file
5
app/src/main/res/values-cs/strings.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="start">Zapnout</string>
|
||||
<string name="stop">Zastavit</string>
|
||||
</resources>
|
||||
59
app/src/main/res/values-de/strings.xml
Normal file
59
app/src/main/res/values-de/strings.xml
Normal file
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="start">Start</string>
|
||||
<string name="stop">Stop</string>
|
||||
<string name="focus">Fokus</string>
|
||||
<string name="short_break">Kurze Pause</string>
|
||||
<string name="long_break">Lange Pause</string>
|
||||
<string name="exit">Abbrechen</string>
|
||||
<string name="skip">Überspringen</string>
|
||||
<string name="stop_alarm">Alarm beenden</string>
|
||||
<string name="min_remaining_notification">%1$s min verbleibend</string>
|
||||
<string name="paused">Pausiert</string>
|
||||
<string name="completed">Abgeschlossen</string>
|
||||
<string name="up_next_notification">Als nächstes: %1$s (%2$s)</string>
|
||||
<string name="start_next">Weiter</string>
|
||||
<string name="choose_color_scheme">Farbschema auswählen</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="color_scheme">Farbschema</string>
|
||||
<string name="dynamic">Dynamisch</string>
|
||||
<string name="color">Farbe</string>
|
||||
<string name="system_default">Systemstandard</string>
|
||||
<string name="alarm">Alarm</string>
|
||||
<string name="light">Hell</string>
|
||||
<string name="dark">Dunkel</string>
|
||||
<string name="choose_theme">Erscheinungsbild wählen</string>
|
||||
<string name="productivity_analysis">Produktivitätsanalyse</string>
|
||||
<string name="productivity_analysis_desc">Fokusdauer zu verschiedenen Tageszeiten</string>
|
||||
<string name="alarm_sound">Alarmton</string>
|
||||
<string name="black_theme">Schwarzes Design</string>
|
||||
<string name="black_theme_desc">Echten Schwarzmodus verwenden</string>
|
||||
<string name="alarm_desc">Alarmton bei Ablauf des Timers</string>
|
||||
<string name="vibrate">Vibration</string>
|
||||
<string name="vibrate_desc">Vibrieren, wenn ein Timer abgelaufen ist</string>
|
||||
<string name="theme">Design</string>
|
||||
<string name="settings">Einstellungen</string>
|
||||
<string name="session_length">Fokusphasen</string>
|
||||
<string name="session_length_desc">Fokusintervalle pro Sitzung:%1$d</string>
|
||||
<string name="pomodoro_info">Eine „Sitzung“ ist eine Abfolge von Pomodoro-Intervallen, die Fokusintervalle, kurze Pausenintervalle und ein langes Pausenintervall enthalten. Die letzte Pause einer Sitzung ist immer eine lange Pause.</string>
|
||||
<string name="stats">Statistik</string>
|
||||
<string name="today">Heute</string>
|
||||
<string name="break_">Pause</string>
|
||||
<string name="last_week">Letzte Woche</string>
|
||||
<string name="focus_per_day_avg">Fokus pro Tag (⌀)</string>
|
||||
<string name="more_info">Weitere Infos</string>
|
||||
<string name="weekly_productivity_analysis">Wöchentliche Produktivität</string>
|
||||
<string name="last_month">Letzter Monat</string>
|
||||
<string name="monthly_productivity_analysis">Monatliche Produktivität</string>
|
||||
<string name="stop_alarm_question">Alarm stoppen?</string>
|
||||
<string name="stop_alarm_dialog_text">Die aktuelle Timer-Sitzung ist beendet. Tippen Sie auf eine beliebige Stelle, um den Alarm zu stoppen.</string>
|
||||
<string name="timer_session_count">%1$d von %2$d</string>
|
||||
<string name="more">Mehr</string>
|
||||
<string name="pause">Pausieren</string>
|
||||
<string name="play">Fortsetzen</string>
|
||||
<string name="restart">Neustarten</string>
|
||||
<string name="skip_to_next">Zum nächsten springen</string>
|
||||
<string name="up_next">Als nächstes</string>
|
||||
<string name="timer">Timer</string>
|
||||
<string name="timer_progress">Timer-Fortschritt</string>
|
||||
</resources>
|
||||
59
app/src/main/res/values-es/strings.xml
Normal file
59
app/src/main/res/values-es/strings.xml
Normal file
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="start">Iniciar</string>
|
||||
<string name="stop">Detener</string>
|
||||
<string name="focus">Concentración</string>
|
||||
<string name="short_break">Pequeño descanso</string>
|
||||
<string name="long_break">Descanso extenso</string>
|
||||
<string name="exit">Salir</string>
|
||||
<string name="skip">Omitir</string>
|
||||
<string name="stop_alarm">Parar alarma</string>
|
||||
<string name="paused">En pausa</string>
|
||||
<string name="system_default">Predeterminado del sistema</string>
|
||||
<string name="alarm">Alarma</string>
|
||||
<string name="choose_theme">Elige tema</string>
|
||||
<string name="productivity_analysis">Análisis de productividad</string>
|
||||
<string name="productivity_analysis_desc">Duración de la concentración en diferentes momentos del día</string>
|
||||
<string name="alarm_sound">Sonido de la alarma</string>
|
||||
<string name="black_theme">Tema negro</string>
|
||||
<string name="black_theme_desc">Utiliza un tema oscuro negro puro</string>
|
||||
<string name="alarm_desc">Sonar alarma cuando el temporizador finalice</string>
|
||||
<string name="vibrate">Vibrar</string>
|
||||
<string name="vibrate_desc">Vibrar cuando el temporizador finalice</string>
|
||||
<string name="theme">Tema</string>
|
||||
<string name="settings">Configuración</string>
|
||||
<string name="session_length">Duración de la sesión</string>
|
||||
<string name="session_length_desc">Intervalos de concentración en una sesión: %1$d</string>
|
||||
<string name="pomodoro_info">Una \"sesión\" es una secuencia de intervalos Pomodoro que contiene intervalos de concentración, intervalos de descanso cortos y un intervalo de descanso largo. El último descanso de una sesión es siempre un descanso largo.</string>
|
||||
<string name="stats">Estadísticas</string>
|
||||
<string name="today">Hoy</string>
|
||||
<string name="break_">Descanso</string>
|
||||
<string name="last_week">Semana pasada</string>
|
||||
<string name="focus_per_day_avg">concentración por día (avg)</string>
|
||||
<string name="more_info">Más informes</string>
|
||||
<string name="weekly_productivity_analysis">Análisis de productividad semanal</string>
|
||||
<string name="last_month">Mes pasado</string>
|
||||
<string name="monthly_productivity_analysis">Análisis de productividad mensual</string>
|
||||
<string name="stop_alarm_question">Parar alarma?</string>
|
||||
<string name="stop_alarm_dialog_text">La sesión actual del temporizador ha finalizado. Toque en cualquier lugar para detener la alarma.</string>
|
||||
<string name="timer_session_count">%1$d de %2$d</string>
|
||||
<string name="more">Más</string>
|
||||
<string name="pause">Pausa</string>
|
||||
<string name="play">Empezar</string>
|
||||
<string name="restart">Reiniciar</string>
|
||||
<string name="skip_to_next">Pasar al siguiente</string>
|
||||
<string name="up_next">A continuación</string>
|
||||
<string name="timer">Temporizador</string>
|
||||
<string name="timer_progress">Pregreso del temporizador</string>
|
||||
<string name="min_remaining_notification">%1$s minutos restantes</string>
|
||||
<string name="completed">Completado</string>
|
||||
<string name="up_next_notification">A continuación: %1$s (%2$s)</string>
|
||||
<string name="start_next">Empezar siguiente</string>
|
||||
<string name="choose_color_scheme">Elige la combinación de colores</string>
|
||||
<string name="ok">Ok</string>
|
||||
<string name="color_scheme">Esquema de colores</string>
|
||||
<string name="dynamic">Dinámica</string>
|
||||
<string name="color">Color</string>
|
||||
<string name="light">Luz</string>
|
||||
<string name="dark">Oscuro</string>
|
||||
</resources>
|
||||
59
app/src/main/res/values-hu/strings.xml
Normal file
59
app/src/main/res/values-hu/strings.xml
Normal file
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="start">Indít</string>
|
||||
<string name="stop">Leállít</string>
|
||||
<string name="focus">Fókuszálás</string>
|
||||
<string name="short_break">Rövid szünet</string>
|
||||
<string name="long_break">Hosszú szünet</string>
|
||||
<string name="exit">Kilépés</string>
|
||||
<string name="skip">Átugrás</string>
|
||||
<string name="stop_alarm">Jelzés leállítása</string>
|
||||
<string name="min_remaining_notification">%1$s perc van hátra</string>
|
||||
<string name="paused">Megállítva</string>
|
||||
<string name="completed">Befejezve</string>
|
||||
<string name="up_next_notification">Következő: %1$s (%2$s)</string>
|
||||
<string name="start_next">Következő indítása</string>
|
||||
<string name="choose_color_scheme">Válassz színsémát</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="color_scheme">Színséma</string>
|
||||
<string name="dynamic">Dinamikus</string>
|
||||
<string name="color">Szín</string>
|
||||
<string name="system_default">Rendszer alapértelmezés</string>
|
||||
<string name="alarm">Jelzés</string>
|
||||
<string name="light">Világos</string>
|
||||
<string name="dark">Sötét</string>
|
||||
<string name="choose_theme">Válassz témát</string>
|
||||
<string name="productivity_analysis">Produktivitás elemzése</string>
|
||||
<string name="productivity_analysis_desc">Fókuszálás időtartama a nap különböző szakaszaiban</string>
|
||||
<string name="alarm_sound">Jelzés hangja</string>
|
||||
<string name="black_theme">Fekete téma</string>
|
||||
<string name="black_theme_desc">Használjon teljesen fekete sötét témát</string>
|
||||
<string name="alarm_desc">Csengőhang, amikor az időzítő lejár</string>
|
||||
<string name="vibrate">Rezgés</string>
|
||||
<string name="vibrate_desc">Rezgés, amikor az időzítő lejár</string>
|
||||
<string name="theme">Téma</string>
|
||||
<string name="settings">Beállítások</string>
|
||||
<string name="session_length">Munkamenet hossza</string>
|
||||
<string name="session_length_desc">Fókusz-intervallumok száma: %1$d</string>
|
||||
<string name="pomodoro_info">Egy „munkamenet” egy sor pomodoro-intervallumból áll, amely fókusz-intervallumokat, rövid szüneteket és egy hosszú szünetet tartalmaz. A munkamenet utolsó szünete mindig hosszú szünet.</string>
|
||||
<string name="stats">Statisztikák</string>
|
||||
<string name="today">Ma</string>
|
||||
<string name="break_">Szünet</string>
|
||||
<string name="last_week">Múlt hét</string>
|
||||
<string name="focus_per_day_avg">naponta átlagosan fókuszált idő</string>
|
||||
<string name="more_info">További információk</string>
|
||||
<string name="weekly_productivity_analysis">Heti produktivitás elemzés</string>
|
||||
<string name="last_month">Múlt hónap</string>
|
||||
<string name="monthly_productivity_analysis">Havi produktivitás elemzés</string>
|
||||
<string name="stop_alarm_question">Jelzés leállítása?</string>
|
||||
<string name="stop_alarm_dialog_text">A jelenlegi időzítő munkamenet befejeződött. Érintse meg a képernyőt bárhol, hogy leállítsa a jelzést.</string>
|
||||
<string name="timer_session_count">%1$d a %2$d-ből</string>
|
||||
<string name="more">Több</string>
|
||||
<string name="pause">Megállít</string>
|
||||
<string name="play">Indítás</string>
|
||||
<string name="restart">Újraindítás</string>
|
||||
<string name="skip_to_next">Ugrás a következőre</string>
|
||||
<string name="up_next">Következik</string>
|
||||
<string name="timer">Időzítő</string>
|
||||
<string name="timer_progress">Időzítő állása</string>
|
||||
</resources>
|
||||
59
app/src/main/res/values-it/strings.xml
Normal file
59
app/src/main/res/values-it/strings.xml
Normal file
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="start">Inizia</string>
|
||||
<string name="stop">Ferma</string>
|
||||
<string name="focus">Concentrati</string>
|
||||
<string name="short_break">Pausa breve</string>
|
||||
<string name="long_break">Pausa lunga</string>
|
||||
<string name="exit">Esci</string>
|
||||
<string name="skip">Salta</string>
|
||||
<string name="stop_alarm">Ferma sveglia</string>
|
||||
<string name="min_remaining_notification">%1$s min rimanenti</string>
|
||||
<string name="paused">In pausa</string>
|
||||
<string name="completed">Completato</string>
|
||||
<string name="up_next_notification">Prossimo: %1$s (%2$s)</string>
|
||||
<string name="start_next">Inizia il prossimo</string>
|
||||
<string name="choose_color_scheme">Scegli schema colori</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="color_scheme">Schema colori</string>
|
||||
<string name="dynamic">Dinamico</string>
|
||||
<string name="color">Colore</string>
|
||||
<string name="system_default">Segui sistema</string>
|
||||
<string name="alarm">Sveglia</string>
|
||||
<string name="light">Chiaro</string>
|
||||
<string name="dark">Scuro</string>
|
||||
<string name="choose_theme">Scegli tema</string>
|
||||
<string name="productivity_analysis">Analisi produttività</string>
|
||||
<string name="productivity_analysis_desc">Durata della concentrazione in diverse ore del giorno</string>
|
||||
<string name="alarm_sound">Suono sveglia</string>
|
||||
<string name="black_theme">Tema nero</string>
|
||||
<string name="black_theme_desc">Tema scuro completamente nero</string>
|
||||
<string name="alarm_desc">Suona la sveglia quando il timer scade</string>
|
||||
<string name="vibrate">Vibrazione</string>
|
||||
<string name="vibrate_desc">Vibra il telefono quando il timer scade</string>
|
||||
<string name="theme">Tema</string>
|
||||
<string name="settings">Impostazioni</string>
|
||||
<string name="session_length">Lunghezza sessione</string>
|
||||
<string name="session_length_desc">Intervalli di concentrazione per sessione: %1$d</string>
|
||||
<string name="pomodoro_info">Una \"sessione\" è una sequenza di intervalli \"pomodoro\" che include intervalli di concentrazione, di pausa breve, e di pausa lunga. L\'ultima pausa di una sessione è sempre una pausa lunga.</string>
|
||||
<string name="stats">Statistiche</string>
|
||||
<string name="today">Oggi</string>
|
||||
<string name="break_">Pausa</string>
|
||||
<string name="last_week">Ultima settimana</string>
|
||||
<string name="focus_per_day_avg">concentrazione al giorno (media)</string>
|
||||
<string name="more_info">Più informazioni</string>
|
||||
<string name="weekly_productivity_analysis">Analisi produttività settimanale</string>
|
||||
<string name="last_month">Ultimo mese</string>
|
||||
<string name="monthly_productivity_analysis">Analisi produttività mensile</string>
|
||||
<string name="stop_alarm_question">Ferma allarme?</string>
|
||||
<string name="stop_alarm_dialog_text">Il timer per la sessione corrente è scaduto. Tocca in qualsiasi punto per fermare la sveglia.</string>
|
||||
<string name="timer_session_count">%1$d di %2$d</string>
|
||||
<string name="more">Altro</string>
|
||||
<string name="pause">Pausa</string>
|
||||
<string name="play">Inizia</string>
|
||||
<string name="restart">Reinizia</string>
|
||||
<string name="skip_to_next">Salta al prossimo</string>
|
||||
<string name="up_next">Prossimo</string>
|
||||
<string name="timer">Timer</string>
|
||||
<string name="timer_progress">Progresso timer</string>
|
||||
</resources>
|
||||
59
app/src/main/res/values-ja/strings.xml
Normal file
59
app/src/main/res/values-ja/strings.xml
Normal file
@@ -0,0 +1,59 @@
|
||||
<?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">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="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="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の%2$d</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>
|
||||
</resources>
|
||||
59
app/src/main/res/values-pt-rBR/strings.xml
Normal file
59
app/src/main/res/values-pt-rBR/strings.xml
Normal file
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="start">Começar</string>
|
||||
<string name="stop">Parar</string>
|
||||
<string name="focus">Focar</string>
|
||||
<string name="short_break">Pausa curta</string>
|
||||
<string name="long_break">Pausa longa</string>
|
||||
<string name="exit">Sair</string>
|
||||
<string name="skip">Pular</string>
|
||||
<string name="stop_alarm">Parar alarme</string>
|
||||
<string name="min_remaining_notification">%1$s minutos restantes</string>
|
||||
<string name="paused">Pausado</string>
|
||||
<string name="completed">Concluído</string>
|
||||
<string name="up_next_notification">A seguir: %1$s (%2$s)</string>
|
||||
<string name="start_next">Começar o próximo</string>
|
||||
<string name="choose_color_scheme">Escolha o esquema de cores</string>
|
||||
<string name="ok">OK</string>
|
||||
<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="alarm">Alarme</string>
|
||||
<string name="light">Claro</string>
|
||||
<string name="dark">Escuro</string>
|
||||
<string name="choose_theme">Escolher tema</string>
|
||||
<string name="productivity_analysis">Análise de produtividade</string>
|
||||
<string name="productivity_analysis_desc">Duração do foco em diferentes horas do dia</string>
|
||||
<string name="alarm_sound">Som de alarme</string>
|
||||
<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_desc">Vibrar quanto um timer for concluído</string>
|
||||
<string name="theme">Tema</string>
|
||||
<string name="settings">Configurações</string>
|
||||
<string name="session_length">Duração da sessão</string>
|
||||
<string name="session_length_desc">Intervalos de foco em uma sessão: %1$d</string>
|
||||
<string name="pomodoro_info">Uma \"sessão\" é uma sequência de intervalos Pomodoro que contém intervalos de foco, intervalos de pausa curta e um intervalo de pausa longa. A última pausa de uma sessão é sempre uma pausa longa.</string>
|
||||
<string name="stats">Estatísticas</string>
|
||||
<string name="today">Hoje</string>
|
||||
<string name="break_">Pausa</string>
|
||||
<string name="last_week">Última semana</string>
|
||||
<string name="focus_per_day_avg">foco por dia (média)</string>
|
||||
<string name="more_info">Mais informações</string>
|
||||
<string name="weekly_productivity_analysis">Análise de produtividade semanal</string>
|
||||
<string name="last_month">Último mês</string>
|
||||
<string name="monthly_productivity_analysis">Análise de produtividade mensal</string>
|
||||
<string name="stop_alarm_question">Parar Alarme?</string>
|
||||
<string name="stop_alarm_dialog_text">A sessão atual do timer foi concluída. Toque em qualquer lugar para interromper o alarme.</string>
|
||||
<string name="timer_session_count">%1$d de %2$d</string>
|
||||
<string name="more">Mais</string>
|
||||
<string name="pause">Pausar</string>
|
||||
<string name="play">Começar</string>
|
||||
<string name="restart">Reiniciar</string>
|
||||
<string name="skip_to_next">Pular para o próximo</string>
|
||||
<string name="up_next">Próximo</string>
|
||||
<string name="timer">Timer</string>
|
||||
<string name="timer_progress">Progresso do timer</string>
|
||||
</resources>
|
||||
@@ -56,4 +56,5 @@
|
||||
<string name="up_next">Up next</string>
|
||||
<string name="timer">Timer</string>
|
||||
<string name="timer_progress">Timer progress</string>
|
||||
<string name="last_year">Last year</string>
|
||||
</resources>
|
||||
1
fastlane/metadata/android/ckb/short_description.txt
Normal file
1
fastlane/metadata/android/ckb/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
کاتگرەوەیەکی چکۆلانەی پۆمۆدۆرە
|
||||
1
fastlane/metadata/android/de-DE/full_description.txt
Normal file
1
fastlane/metadata/android/de-DE/full_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
<p><i>Tomato</i> ist ein minimalistischer Pomodoro-Timer für Android, der auf Material 3 Expressive basiert. </p><p><br><b>Funktionen:</b></p><ul><li>Einfache, minimalistische Benutzeroberfläche, die auf den neuesten Material 3 Expressive-Richtlinien basiert</li><li>Detaillierte Statistiken zu Arbeits-/Lernzeiten in leicht verständlicher Form<ul><li>Statistiken für den aktuellen Tag auf einen Blick sichtbar</li><li>Statistiken für die letzte Woche und den letzten Monat in einer übersichtlichen und sauberen Grafik dargestellt</li><li>Zusätzliche Statistiken für die letzte Woche und den letzten Monat zeigen, zu welcher Tageszeit Sie am produktivsten sind</li></ul></li><li>Anpassbare Timer Voreinstellungen</li></ul>
|
||||
1
fastlane/metadata/android/de-DE/short_description.txt
Normal file
1
fastlane/metadata/android/de-DE/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Minimalistischer Pomodoro-Timer
|
||||
12
fastlane/metadata/android/en-US/changelogs/12.txt
Normal file
12
fastlane/metadata/android/en-US/changelogs/12.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
New features:
|
||||
- The Stats screen now contains the data for the past year
|
||||
- Charts now have fading edges to indicate scrollable content
|
||||
|
||||
Fixes:
|
||||
- Improved Stats screen performance
|
||||
- Notification now does not pop up on your screen
|
||||
- Fixed low contrast on the Timer screen heading
|
||||
- Improve app usability on smaller screens
|
||||
|
||||
Translators on Weblate added support for:
|
||||
Arabic, Czech, German, Hungarian, Italian, Japanese, Kurdish (Central), Minnan (Traditional), Portuguese (Brazil), Spanish
|
||||
1
fastlane/metadata/android/es-ES/full_description.txt
Normal file
1
fastlane/metadata/android/es-ES/full_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
<p><i>Tomato</i> es un temporizador Pomodoro minimalista para Android basado en "Material 3 Expressive". </p><p><br><b>Características:</b></p><ul><li>Interfaz de usuario sencilla y minimalista basada en las últimas directrices de "Material 3 Expressive".</li><li>Estadísticas detalladas e intuitivas en los tiempos de trabajo/estudio.<ul><li>Estadísticas simples y accesibles del día en curso.</li><li>Estadísticas de la última semana y del último mes mostradas en un gráfico sencillo.</li><li>Estadísticas adicionales de la última semana y del último mes que muestran a qué hora del día eres más productivo.</li></ul></li><li>Parámetros de temporizador personalizables.</li></ul>
|
||||
1
fastlane/metadata/android/es-ES/short_description.txt
Normal file
1
fastlane/metadata/android/es-ES/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Temporizador Pomodoro minimalista
|
||||
1
fastlane/metadata/android/hu-HU/full_description.txt
Normal file
1
fastlane/metadata/android/hu-HU/full_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
<p>A <i>Tomato</i> egy minimalista Pomodoro időzítő Androidra, ami Material 3 Expressive alapú.</p><p><br><b>Funkciók:</b></p><ul><li>Egyszerű, minimalista felhasználói felület, a legújabb Material 3 Expressive irányelvek alapján.</li><li>Részletes statisztikák a munka/tanulási időkről, könnyen érthető módon<ul><li>A mai nap statisztikái egy pillanat alatt áttekinthetők</li><li>Az elmúlt hét és hónap statisztikái könnyen olvasható, letisztult grafikonon</li><li>A múlt hét és hónap további statisztikái, amelyekből kiderül, hogy a nap melyik szakaszában vagy a legproduktívabb</li></ul></li><li>Testreszabható időzítő paraméterek</li></ul>
|
||||
1
fastlane/metadata/android/hu-HU/short_description.txt
Normal file
1
fastlane/metadata/android/hu-HU/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Minimalista Pomodoro időzítő
|
||||
1
fastlane/metadata/android/it-IT/full_description.txt
Normal file
1
fastlane/metadata/android/it-IT/full_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
<p><i>Tomato</i> è un timer Pomodoro minimalista per Android con design Material 3 Expressive.</p><p><br><b>Features:</b></p><ul><li>UI semplice e minimalista basata sulle ultime linee guida Material 3 Expressive</li><li>Statistiche dettagliate dei tempi di studio/lavoro in modo semplice da comprendere<ul><li>Statistiche per il giorno attuale visibili a colpo d'occhio</li><li>Statistiche per l'ultima settimana e ultimo mese visibili in un chiaro grafico di semplice lettura</li><li>Statistiche aggiuntive per l'ultima settimana e ultimo mese che mostrano a quale ora del giorno sei più produttivo</li></ul></li><li>Parametri del timer personalizzabili</li></ul>
|
||||
1
fastlane/metadata/android/it-IT/short_description.txt
Normal file
1
fastlane/metadata/android/it-IT/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Timer Pomodoro Minimalista
|
||||
1
fastlane/metadata/android/ja-JP/full_description.txt
Normal file
1
fastlane/metadata/android/ja-JP/full_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
<p><i>Tomato</i> は、Material 3 Expressive をベースにしたミニマルな Android 向けポモドーロ・タイマーです。</p><p><br><b>主な機能:</b></p><ul><li>最新の Material 3 Expressive ガイドラインに基づいたシンプルでミニマルなUI</li><li>作業・学習時間をわかりやすく可視化した詳細な統計<ul><li>当日の統計をひと目で確認可能</li><li>過去1週間・1か月分の統計を見やすく整理されたグラフで表示</li><li>さらに、先週・先月の統計から一日のうち最も集中できる時間帯を確認可能</li></ul></li><li>タイマー設定を自由にカスタマイズ可能</li></ul>
|
||||
1
fastlane/metadata/android/ja-JP/short_description.txt
Normal file
1
fastlane/metadata/android/ja-JP/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
シンプルなポモドーロタイマー
|
||||
9
fastlane/metadata/android/nan-Hant/full_description.txt
Normal file
9
fastlane/metadata/android/nan-Hant/full_description.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
<p><i>Tomato</i> 是一个簡單的柑仔蜜鐘計時器,設計的風格是根據 Material 3 Expressive。</p><p><br><b>功能:</b></p><ul>
|
||||
<li>簡單、極簡的使用介面,遵照最新的 Material 3 Expressive 指引</li>
|
||||
<li>提供詳細的工作/讀書時間統計,容易看懂<ul>
|
||||
<li>當日的統計一目了然</li>
|
||||
<li>上禮拜佮上個月的統計,以簡潔 ê 圖表呈現</li>
|
||||
<li>閣有額外 ê 統計,顯示你上生產力的時段(上禮拜佮上個月)</li>
|
||||
</ul></li>
|
||||
<li>計時參數會當自由調整</li>
|
||||
</ul>
|
||||
1
fastlane/metadata/android/nan-Hant/short_description.txt
Normal file
1
fastlane/metadata/android/nan-Hant/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
簡潔柑仔蜜計時器
|
||||
1
fastlane/metadata/android/pt-BR/full_description.txt
Normal file
1
fastlane/metadata/android/pt-BR/full_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
<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>
|
||||
1
fastlane/metadata/android/pt-BR/short_description.txt
Normal file
1
fastlane/metadata/android/pt-BR/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Timer minimalista Pomodoro
|
||||
@@ -2,18 +2,18 @@
|
||||
activityCompose = "1.11.0"
|
||||
adaptive = "1.1.0"
|
||||
agp = "8.11.2"
|
||||
composeBom = "2025.09.01"
|
||||
composeBom = "2025.10.00"
|
||||
coreKtx = "1.17.0"
|
||||
espressoCore = "3.7.0"
|
||||
junit = "4.13.2"
|
||||
junitVersion = "1.3.0"
|
||||
kotlin = "2.2.20"
|
||||
ksp = "2.2.20-2.0.3"
|
||||
ksp = "2.2.20-2.0.4"
|
||||
lifecycleRuntimeKtx = "2.9.4"
|
||||
materialKolor = "3.0.1"
|
||||
navigation3 = "1.0.0-alpha10"
|
||||
room = "2.8.1"
|
||||
vico = "2.2.0"
|
||||
navigation3 = "1.0.0-alpha11"
|
||||
room = "2.8.2"
|
||||
vico = "2.2.1"
|
||||
|
||||
[libraries]
|
||||
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
3
gradlew
vendored
3
gradlew
vendored
@@ -114,7 +114,6 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -172,7 +171,6 @@ fi
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
|
||||
3
gradlew.bat
vendored
3
gradlew.bat
vendored
@@ -70,11 +70,10 @@ goto fail
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
Reference in New Issue
Block a user