Merge branch 'dev'

This commit is contained in:
Nishant Mishra
2025-10-16 12:41:14 +05:30
39 changed files with 930 additions and 159 deletions

View File

@@ -33,8 +33,8 @@ android {
applicationId = "org.nsh07.pomodoro" applicationId = "org.nsh07.pomodoro"
minSdk = 26 minSdk = 26
targetSdk = 36 targetSdk = 36
versionCode = 11 versionCode = 12
versionName = "1.4.3" versionName = "1.5.0-alpha01"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }

View File

@@ -15,7 +15,7 @@ class TomatoApplication : Application() {
val notificationChannel = NotificationChannel( val notificationChannel = NotificationChannel(
"timer", "timer",
getString(R.string.timer_progress), getString(R.string.timer_progress),
NotificationManager.IMPORTANCE_HIGH NotificationManager.IMPORTANCE_DEFAULT
) )
container.notificationManager.createNotificationChannel(notificationChannel) container.notificationManager.createNotificationChannel(notificationChannel)

View File

@@ -68,7 +68,7 @@ fun AppScreen(
val motionScheme = motionScheme val motionScheme = motionScheme
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
val backStack = rememberNavBackStack<Screen>(Screen.Timer) val backStack = rememberNavBackStack(Screen.Timer)
if (uiState.alarmRinging) if (uiState.alarmRinging)
AlarmDialog { AlarmDialog {

View File

@@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.TextAutoSize
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FilledTonalIconToggleButton 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.colorScheme
import androidx.compose.material3.MaterialTheme.motionScheme import androidx.compose.material3.MaterialTheme.motionScheme
import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember 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.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@@ -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.CartesianChartModelProducer
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
import com.patrykandpatrick.vico.core.cartesian.data.columnSeries 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 com.patrykandpatrick.vico.core.common.data.ExtraStore
import kotlinx.coroutines.runBlocking
import org.nsh07.pomodoro.R import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.data.Stat import org.nsh07.pomodoro.data.Stat
import org.nsh07.pomodoro.data.StatFocusTime
import org.nsh07.pomodoro.ui.statsScreen.viewModel.StatsViewModel import org.nsh07.pomodoro.ui.statsScreen.viewModel.StatsViewModel
import org.nsh07.pomodoro.ui.theme.AppFonts.openRundeClock import org.nsh07.pomodoro.ui.theme.AppFonts.openRundeClock
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
import org.nsh07.pomodoro.ui.theme.TomatoTheme
import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes
@Composable @Composable
@@ -72,20 +74,25 @@ fun StatsScreenRoot(
viewModel: StatsViewModel = viewModel(factory = StatsViewModel.Factory) viewModel: StatsViewModel = viewModel(factory = StatsViewModel.Factory)
) { ) {
val todayStat by viewModel.todayStat.collectAsStateWithLifecycle(null) val todayStat by viewModel.todayStat.collectAsStateWithLifecycle(null)
val lastWeekAverageFocusTimes by viewModel
.lastWeekAverageFocusTimes.collectAsStateWithLifecycle(null) val lastWeekSummaryChartData by viewModel.lastWeekSummaryChartData.collectAsStateWithLifecycle()
val lastMonthAverageFocusTimes by viewModel val lastWeekAnalysisValues by viewModel.lastWeekAverageFocusTimes.collectAsStateWithLifecycle()
.lastMonthAverageFocusTimes.collectAsStateWithLifecycle(null)
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( StatsScreen(
contentPadding = contentPadding, contentPadding = contentPadding,
lastWeekSummaryChartData = remember { viewModel.lastWeekSummaryChartData }, lastWeekSummaryChartData = lastWeekSummaryChartData,
lastWeekSummaryAnalysisModelProducer = remember { viewModel.lastWeekSummaryAnalysisModelProducer }, lastMonthSummaryChartData = lastMonthSummaryChartData,
lastMonthSummaryChartData = remember { viewModel.lastMonthSummaryChartData }, lastYearSummaryChartData = lastYearSummaryChartData,
lastMonthSummaryAnalysisModelProducer = remember { viewModel.lastMonthSummaryAnalysisModelProducer },
todayStat = todayStat, todayStat = todayStat,
lastWeekAverageFocusTimes = lastWeekAverageFocusTimes, lastWeekAverageFocusTimes = lastWeekAnalysisValues,
lastMonthAverageFocusTimes = lastMonthAverageFocusTimes, lastMonthAverageFocusTimes = lastMonthAnalysisValues,
lastYearAverageFocusTimes = lastYearAnalysisValues,
modifier = modifier modifier = modifier
) )
} }
@@ -95,12 +102,12 @@ fun StatsScreenRoot(
fun StatsScreen( fun StatsScreen(
contentPadding: PaddingValues, contentPadding: PaddingValues,
lastWeekSummaryChartData: Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>, lastWeekSummaryChartData: Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>,
lastWeekSummaryAnalysisModelProducer: CartesianChartModelProducer,
lastMonthSummaryChartData: Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>, lastMonthSummaryChartData: Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>,
lastMonthSummaryAnalysisModelProducer: CartesianChartModelProducer, lastYearSummaryChartData: Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>,
todayStat: Stat?, todayStat: Stat?,
lastWeekAverageFocusTimes: StatFocusTime?, lastWeekAverageFocusTimes: List<Int>,
lastMonthAverageFocusTimes: StatFocusTime?, lastMonthAverageFocusTimes: List<Int>,
lastYearAverageFocusTimes: List<Int>,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
@@ -108,6 +115,25 @@ fun StatsScreen(
var lastWeekStatExpanded by rememberSaveable { mutableStateOf(false) } var lastWeekStatExpanded by rememberSaveable { mutableStateOf(false) }
var lastMonthStatExpanded 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( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection) modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
@@ -168,7 +194,9 @@ fun StatsScreen(
}, },
style = typography.displaySmall, style = typography.displaySmall,
fontFamily = openRundeClock, 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, style = typography.displaySmall,
fontFamily = openRundeClock, 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) .padding(horizontal = 16.dp)
) { ) {
Text( Text(
millisecondsToHoursMinutes(lastWeekAverageFocusTimes?.total() ?: 0), millisecondsToHoursMinutes(
remember(lastWeekAverageFocusTimes) {
lastWeekAverageFocusTimes.sum().toLong()
}
),
style = typography.displaySmall, style = typography.displaySmall,
fontFamily = openRundeClock fontFamily = openRundeClock
) )
@@ -290,7 +324,11 @@ fun StatsScreen(
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)
) { ) {
Text( Text(
millisecondsToHoursMinutes(lastMonthAverageFocusTimes?.total() ?: 0), millisecondsToHoursMinutes(
remember(lastMonthAverageFocusTimes) {
lastMonthAverageFocusTimes.sum().toLong()
}
),
style = typography.displaySmall, style = typography.displaySmall,
fontFamily = openRundeClock fontFamily = openRundeClock
) )
@@ -343,36 +381,85 @@ fun StatsScreen(
modifier = Modifier.padding(horizontal = 32.dp) 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( @Preview(
showSystemUi = true, widthDp = 400
device = Devices.PIXEL_9_PRO
) )
@Composable @Composable
fun StatsScreenPreview() { fun StatsScreenPreview() {
val modelProducer = remember { CartesianChartModelProducer() } val modelProducer = remember { CartesianChartModelProducer() }
val keys = remember { ExtraStore.Key<List<String>>() }
runBlocking { LaunchedEffect(Unit) {
modelProducer.runTransaction { modelProducer.runTransaction {
columnSeries { 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( TomatoTheme {
PaddingValues(), Surface {
Pair(modelProducer, ExtraStore.Key()), StatsScreen(
modelProducer, PaddingValues(),
Pair(modelProducer, ExtraStore.Key()), Pair(modelProducer, keys),
modelProducer, Pair(modelProducer, keys),
null, Pair(modelProducer, keys),
null, null,
null listOf(0, 0, 0, 0),
) listOf(0, 0, 0, 0),
} listOf(0, 0, 0, 0)
)
}
}
}

View File

@@ -10,8 +10,12 @@ package org.nsh07.pomodoro.ui.statsScreen
import androidx.compose.animation.core.AnimationSpec import androidx.compose.animation.core.AnimationSpec
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.MaterialTheme.motionScheme import androidx.compose.material3.MaterialTheme.motionScheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier 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 androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost 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.fill
import com.patrykandpatrick.vico.compose.common.vicoTheme import com.patrykandpatrick.vico.compose.common.vicoTheme
import com.patrykandpatrick.vico.compose.m3.common.rememberM3VicoTheme 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.Zoom
import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis
import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter 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.cartesian.layer.ColumnCartesianLayer
import com.patrykandpatrick.vico.core.common.Fill import com.patrykandpatrick.vico.core.common.Fill
import com.patrykandpatrick.vico.core.common.shape.CorneredShape 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.millisecondsToHours
import org.nsh07.pomodoro.utils.millisecondsToMinutes import org.nsh07.pomodoro.utils.millisecondsToMinutes
@OptIn(ExperimentalMaterial3ExpressiveApi::class) @OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable @Composable
internal fun TimeColumnChart( fun TimeColumnChart(
modelProducer: CartesianChartModelProducer, modelProducer: CartesianChartModelProducer,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
thickness: Dp = 40.dp, thickness: Dp = 40.dp,
@@ -80,7 +87,8 @@ internal fun TimeColumnChart(
tick = rememberLineComponent(Fill.Transparent), tick = rememberLineComponent(Fill.Transparent),
guideline = rememberLineComponent(Fill.Transparent), guideline = rememberLineComponent(Fill.Transparent),
valueFormatter = xValueFormatter valueFormatter = xValueFormatter
) ),
fadingEdges = FadingEdges()
), ),
modelProducer = modelProducer, modelProducer = modelProducer,
zoomState = rememberVicoZoomState( zoomState = rememberVicoZoomState(
@@ -92,4 +100,26 @@ internal fun TimeColumnChart(
modifier = modifier, 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)
}
}
}

View File

@@ -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)
}
}
}

View File

@@ -15,12 +15,16 @@ import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory import androidx.lifecycle.viewmodel.viewModelFactory
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
import com.patrykandpatrick.vico.core.cartesian.data.columnSeries 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 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.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.TomatoApplication
import org.nsh07.pomodoro.data.StatRepository import org.nsh07.pomodoro.data.StatRepository
import java.time.format.DateTimeFormatter
import java.time.format.TextStyle import java.time.format.TextStyle
import java.util.Locale import java.util.Locale
@@ -29,83 +33,123 @@ class StatsViewModel(
) : ViewModel() { ) : ViewModel() {
val todayStat = statRepository.getTodayStat().distinctUntilChanged() 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>>()) Pair(CartesianChartModelProducer(), ExtraStore.Key<List<String>>())
val lastWeekSummaryAnalysisModelProducer = CartesianChartModelProducer() private val lastMonthSummary =
Pair(CartesianChartModelProducer(), ExtraStore.Key<List<String>>())
val lastMonthSummaryChartData = private val lastYearSummary =
Pair(CartesianChartModelProducer(), ExtraStore.Key<List<String>>()) Pair(CartesianChartModelProducer(), ExtraStore.Key<List<String>>())
val lastMonthSummaryAnalysisModelProducer = CartesianChartModelProducer()
init { private val yearDayFormatter = DateTimeFormatter.ofPattern("d MMM")
viewModelScope.launch(Dispatchers.IO) {
lastWeekStatsSummary val lastWeekSummaryChartData: StateFlow<Pair<CartesianChartModelProducer, ExtraStore.Key<List<String>>>> =
.collect { list -> statRepository.getLastNDaysStatsSummary(7)
// reversing is required because we need ascending order while the DB returns descending order .map { list ->
val reversed = list.reversed() // reversing is required because we need ascending order while the DB returns descending order
val keys = reversed.map { val reversed = list.reversed()
it.date.dayOfWeek.getDisplayName( val keys = reversed.map {
TextStyle.NARROW, it.date.dayOfWeek.getDisplayName(
Locale.getDefault() TextStyle.NARROW,
) Locale.getDefault()
} )
val values = reversed.map { it.focusTime }
lastWeekSummaryChartData.first.runTransaction {
columnSeries { series(values) }
extras { it[lastWeekSummaryChartData.second] = keys }
}
} }
} val values = reversed.map { it.focusTime }
viewModelScope.launch(Dispatchers.IO) { lastWeekSummary.first.runTransaction {
lastWeekAverageFocusTimes columnSeries { series(values) }
.collect { extras { it[lastWeekSummary.second] = keys }
lastWeekSummaryAnalysisModelProducer.runTransaction {
columnSeries {
series(
it?.focusTimeQ1 ?: 0,
it?.focusTimeQ2 ?: 0,
it?.focusTimeQ3 ?: 0,
it?.focusTimeQ4 ?: 0
)
}
}
} }
} lastWeekSummary
viewModelScope.launch(Dispatchers.IO) { }
lastMonthStatsSummary .stateIn(
.collect { list -> scope = viewModelScope,
val reversed = list.reversed() started = SharingStarted.WhileSubscribed(5000),
val keys = reversed.map { it.date.dayOfMonth.toString() } initialValue = lastWeekSummary
val values = reversed.map { it.focusTime } )
lastMonthSummaryChartData.first.runTransaction {
columnSeries { series(values) } val lastWeekAverageFocusTimes: StateFlow<List<Int>> =
extras { it[lastMonthSummaryChartData.second] = keys } 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 }
} }
} lastMonthSummary
viewModelScope.launch(Dispatchers.IO) { }
lastMonthAverageFocusTimes .stateIn(
.collect { scope = viewModelScope,
lastMonthSummaryAnalysisModelProducer.runTransaction { started = SharingStarted.WhileSubscribed(5000),
columnSeries { initialValue = lastMonthSummary
series( )
it?.focusTimeQ1 ?: 0,
it?.focusTimeQ2 ?: 0, val lastMonthAverageFocusTimes: StateFlow<List<Int>> =
it?.focusTimeQ3 ?: 0, statRepository.getLastNDaysAverageFocusTimes(30)
it?.focusTimeQ4 ?: 0 .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 { companion object {
val Factory: ViewModelProvider.Factory = viewModelFactory { val Factory: ViewModelProvider.Factory = viewModelFactory {

View File

@@ -35,7 +35,10 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn 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.ButtonGroup
import androidx.compose.material3.ButtonGroupDefaults
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.CircularWavyProgressIndicator import androidx.compose.material3.CircularWavyProgressIndicator
import androidx.compose.material3.DropdownMenuItem 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.motionScheme
import androidx.compose.material3.MaterialTheme.shapes import androidx.compose.material3.MaterialTheme.shapes
import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue 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.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@@ -115,7 +121,9 @@ fun TimerScreen(
onResult = {} onResult = {}
) )
Column(modifier = modifier) { val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Column(modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) {
TopAppBar( TopAppBar(
title = { title = {
AnimatedContent( AnimatedContent(
@@ -140,7 +148,7 @@ fun TimerScreen(
fontFamily = robotoFlexTopBar, fontFamily = robotoFlexTopBar,
fontSize = 32.sp, fontSize = 32.sp,
lineHeight = 32.sp, lineHeight = 32.sp,
color = colorScheme.onErrorContainer color = colorScheme.error
), ),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp) modifier = Modifier.width(210.dp)
@@ -153,7 +161,7 @@ fun TimerScreen(
fontFamily = robotoFlexTopBar, fontFamily = robotoFlexTopBar,
fontSize = 32.sp, fontSize = 32.sp,
lineHeight = 32.sp, lineHeight = 32.sp,
color = colorScheme.onPrimaryContainer color = colorScheme.primary
), ),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp) modifier = Modifier.width(210.dp)
@@ -165,7 +173,7 @@ fun TimerScreen(
fontFamily = robotoFlexTopBar, fontFamily = robotoFlexTopBar,
fontSize = 32.sp, fontSize = 32.sp,
lineHeight = 32.sp, lineHeight = 32.sp,
color = colorScheme.onTertiaryContainer color = colorScheme.tertiary
), ),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp) modifier = Modifier.width(210.dp)
@@ -177,7 +185,7 @@ fun TimerScreen(
fontFamily = robotoFlexTopBar, fontFamily = robotoFlexTopBar,
fontSize = 32.sp, fontSize = 32.sp,
lineHeight = 32.sp, lineHeight = 32.sp,
color = colorScheme.onTertiaryContainer color = colorScheme.tertiary
), ),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.width(210.dp) modifier = Modifier.width(210.dp)
@@ -186,13 +194,16 @@ fun TimerScreen(
} }
}, },
subtitle = {}, subtitle = {},
titleHorizontalAlignment = CenterHorizontally titleHorizontalAlignment = CenterHorizontally,
scrollBehavior = scrollBehavior
) )
Column( Column(
verticalArrangement = Arrangement.Center, verticalArrangement = Arrangement.Center,
horizontalAlignment = CenterHorizontally, horizontalAlignment = CenterHorizontally,
modifier = Modifier.fillMaxSize() modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
) { ) {
Column(horizontalAlignment = CenterHorizontally) { Column(horizontalAlignment = CenterHorizontally) {
Box(contentAlignment = Alignment.Center) { Box(contentAlignment = Alignment.Center) {
@@ -277,27 +288,11 @@ fun TimerScreen(
val interactionSources = remember { List(3) { MutableInteractionSource() } } val interactionSources = remember { List(3) { MutableInteractionSource() } }
ButtonGroup( ButtonGroup(
overflowIndicator = { state -> overflowIndicator = { state ->
FilledTonalIconButton( ButtonGroupDefaults.OverflowIndicator(
onClick = { state,
if (state.isExpanded) { colors = IconButtonDefaults.filledTonalIconButtonColors(),
state.dismiss() modifier = Modifier.size(64.dp, 96.dp)
} 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)
)
}
}, },
modifier = Modifier.padding(16.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 timeStr = "03:34", nextTimeStr = "5:00", timerMode = TimerMode.FOCUS, timerRunning = true
) )
TomatoTheme { TomatoTheme {
TimerScreen( Surface {
timerState, TimerScreen(
{ 0.3f }, timerState,
{} { 0.3f },
) {}
)
}
} }
} }

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>

View 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>

View 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>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="start">Zapnout</string>
<string name="stop">Zastavit</string>
</resources>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View File

@@ -56,4 +56,5 @@
<string name="up_next">Up next</string> <string name="up_next">Up next</string>
<string name="timer">Timer</string> <string name="timer">Timer</string>
<string name="timer_progress">Timer progress</string> <string name="timer_progress">Timer progress</string>
<string name="last_year">Last year</string>
</resources> </resources>

View File

@@ -0,0 +1 @@
کاتگرەوەیەکی چکۆلانەی پۆمۆدۆرە

View 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>

View File

@@ -0,0 +1 @@
Minimalistischer Pomodoro-Timer

View 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

View 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>

View File

@@ -0,0 +1 @@
Temporizador Pomodoro minimalista

View 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>

View File

@@ -0,0 +1 @@
Minimalista Pomodoro időzítő

View 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>

View File

@@ -0,0 +1 @@
Timer Pomodoro Minimalista

View 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>

View File

@@ -0,0 +1 @@
シンプルなポモドーロタイマー

View 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>

View File

@@ -0,0 +1 @@
簡潔柑仔蜜計時器

View 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>

View File

@@ -0,0 +1 @@
Timer minimalista Pomodoro

View File

@@ -2,18 +2,18 @@
activityCompose = "1.11.0" activityCompose = "1.11.0"
adaptive = "1.1.0" adaptive = "1.1.0"
agp = "8.11.2" agp = "8.11.2"
composeBom = "2025.09.01" composeBom = "2025.10.00"
coreKtx = "1.17.0" coreKtx = "1.17.0"
espressoCore = "3.7.0" espressoCore = "3.7.0"
junit = "4.13.2" junit = "4.13.2"
junitVersion = "1.3.0" junitVersion = "1.3.0"
kotlin = "2.2.20" kotlin = "2.2.20"
ksp = "2.2.20-2.0.3" ksp = "2.2.20-2.0.4"
lifecycleRuntimeKtx = "2.9.4" lifecycleRuntimeKtx = "2.9.4"
materialKolor = "3.0.1" materialKolor = "3.0.1"
navigation3 = "1.0.0-alpha10" navigation3 = "1.0.0-alpha11"
room = "2.8.1" room = "2.8.2"
vico = "2.2.0" vico = "2.2.1"
[libraries] [libraries]
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

3
gradlew vendored
View File

@@ -114,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;; NONSTOP* ) nonstop=true ;;
esac esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM. # 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 # For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" ) JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@" "$@"

3
gradlew.bat vendored
View File

@@ -70,11 +70,10 @@ goto fail
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=
@rem Execute Gradle @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 :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell