feat(ui): clean up stats screen for upcoming changes
This commit is contained in:
@@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2025 Nishant Mishra
|
|
||||||
*
|
|
||||||
* This file is part of Tomato - a minimalist pomodoro timer for Android.
|
|
||||||
*
|
|
||||||
* Tomato is free software: you can redistribute it and/or modify it under the terms of the GNU
|
|
||||||
* General Public License as published by the Free Software Foundation, either version 3 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Tomato is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
|
||||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
||||||
* Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with Tomato.
|
|
||||||
* If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.nsh07.pomodoro.ui.statsScreen
|
|
||||||
|
|
||||||
import android.graphics.Typeface
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
|
|
||||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
|
|
||||||
import org.nsh07.pomodoro.R
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ColumnScope.ProductivityGraph(
|
|
||||||
expanded: Boolean,
|
|
||||||
modelProducer: CartesianChartModelProducer,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
axisTypeface: Typeface = Typeface.DEFAULT,
|
|
||||||
markerTypeface: Typeface = Typeface.DEFAULT,
|
|
||||||
label: String = stringResource(R.string.productivity_analysis)
|
|
||||||
) {
|
|
||||||
AnimatedVisibility(expanded) {
|
|
||||||
Column(modifier = modifier) {
|
|
||||||
Text(label, style = typography.titleMedium)
|
|
||||||
Text(
|
|
||||||
stringResource(R.string.productivity_analysis_desc),
|
|
||||||
style = typography.bodySmall
|
|
||||||
)
|
|
||||||
Spacer(Modifier.height(8.dp))
|
|
||||||
TimeColumnChart(
|
|
||||||
modelProducer,
|
|
||||||
hoursFormat = stringResource(R.string.hours_format),
|
|
||||||
hoursMinutesFormat = stringResource(R.string.hours_and_minutes_format),
|
|
||||||
minutesFormat = stringResource(R.string.minutes_format),
|
|
||||||
axisTypeface = axisTypeface,
|
|
||||||
markerTypeface = markerTypeface,
|
|
||||||
xValueFormatter = CartesianValueFormatter { _, value, _ ->
|
|
||||||
when (value) {
|
|
||||||
0.0 -> "0 - 6"
|
|
||||||
1.0 -> "6 - 12"
|
|
||||||
2.0 -> "12 - 18"
|
|
||||||
3.0 -> "18 - 24"
|
|
||||||
else -> ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,16 +18,14 @@
|
|||||||
package org.nsh07.pomodoro.ui.statsScreen
|
package org.nsh07.pomodoro.ui.statsScreen
|
||||||
|
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
@@ -36,14 +34,10 @@ import androidx.compose.foundation.lazy.LazyColumn
|
|||||||
import androidx.compose.foundation.text.TextAutoSize
|
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.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.IconButtonDefaults
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
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.shapes
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
import androidx.compose.material3.MaterialTheme.typography
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
@@ -53,16 +47,12 @@ 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
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.rotate
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalFontFamilyResolver
|
import androidx.compose.ui.platform.LocalFontFamilyResolver
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@@ -82,6 +72,11 @@ import org.nsh07.pomodoro.ui.statsScreen.viewModel.StatsViewModel
|
|||||||
import org.nsh07.pomodoro.ui.theme.AppFonts.googleFlex400
|
import org.nsh07.pomodoro.ui.theme.AppFonts.googleFlex400
|
||||||
import org.nsh07.pomodoro.ui.theme.AppFonts.googleFlex600
|
import org.nsh07.pomodoro.ui.theme.AppFonts.googleFlex600
|
||||||
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
|
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
|
||||||
|
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
|
||||||
|
import org.nsh07.pomodoro.ui.theme.CustomColors.topBarColors
|
||||||
|
import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.bottomListItemShape
|
||||||
|
import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.middleListItemShape
|
||||||
|
import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.topListItemShape
|
||||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||||
import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes
|
import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes
|
||||||
|
|
||||||
@@ -130,15 +125,12 @@ fun StatsScreen(
|
|||||||
generateSampleData: () -> Unit,
|
generateSampleData: () -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
|
||||||
|
|
||||||
val hoursFormat = stringResource(R.string.hours_format)
|
val hoursFormat = stringResource(R.string.hours_format)
|
||||||
val hoursMinutesFormat = stringResource(R.string.hours_and_minutes_format)
|
val hoursMinutesFormat = stringResource(R.string.hours_and_minutes_format)
|
||||||
val minutesFormat = stringResource(R.string.minutes_format)
|
val minutesFormat = stringResource(R.string.minutes_format)
|
||||||
|
|
||||||
var lastWeekStatExpanded by rememberSaveable { mutableStateOf(false) }
|
|
||||||
var lastMonthStatExpanded by rememberSaveable { mutableStateOf(false) }
|
|
||||||
|
|
||||||
val lastWeekSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() }
|
val lastWeekSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() }
|
||||||
val lastMonthSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() }
|
val lastMonthSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() }
|
||||||
|
|
||||||
@@ -172,10 +164,7 @@ fun StatsScreen(
|
|||||||
fontFamily = robotoFlexTopBar,
|
fontFamily = robotoFlexTopBar,
|
||||||
fontSize = 32.sp,
|
fontSize = 32.sp,
|
||||||
lineHeight = 32.sp
|
lineHeight = 32.sp
|
||||||
),
|
)
|
||||||
modifier = Modifier
|
|
||||||
.padding(top = contentPadding.calculateTopPadding())
|
|
||||||
.padding(vertical = 14.dp)
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
actions = if (BuildConfig.DEBUG) {
|
actions = if (BuildConfig.DEBUG) {
|
||||||
@@ -192,34 +181,38 @@ fun StatsScreen(
|
|||||||
subtitle = {},
|
subtitle = {},
|
||||||
titleHorizontalAlignment = Alignment.CenterHorizontally,
|
titleHorizontalAlignment = Alignment.CenterHorizontally,
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
windowInsets = WindowInsets()
|
colors = topBarColors
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
|
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
val insets = mergePaddingValues(innerPadding, contentPadding)
|
val insets = mergePaddingValues(innerPadding, contentPadding)
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
contentPadding = insets,
|
contentPadding = insets,
|
||||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||||
|
modifier = Modifier
|
||||||
|
.background(topBarColors.containerColor)
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
) {
|
) {
|
||||||
item { Spacer(Modifier) }
|
item { Spacer(Modifier.height(14.dp)) }
|
||||||
|
|
||||||
item {
|
item {
|
||||||
Text(
|
Text(
|
||||||
stringResource(R.string.today),
|
stringResource(R.string.today),
|
||||||
style = typography.headlineSmall,
|
style = typography.headlineSmall,
|
||||||
modifier = Modifier
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item { Spacer(Modifier.height(12.dp)) }
|
||||||
|
|
||||||
item {
|
item {
|
||||||
Row(modifier = Modifier.padding(horizontal = 16.dp)) {
|
Row {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(
|
.background(
|
||||||
colorScheme.primaryContainer,
|
colorScheme.primaryContainer,
|
||||||
MaterialTheme.shapes.largeIncreased
|
shapes.largeIncreased
|
||||||
)
|
)
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
) {
|
) {
|
||||||
@@ -248,7 +241,7 @@ fun StatsScreen(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(
|
.background(
|
||||||
colorScheme.tertiaryContainer,
|
colorScheme.tertiaryContainer,
|
||||||
MaterialTheme.shapes.largeIncreased
|
shapes.largeIncreased
|
||||||
)
|
)
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
) {
|
) {
|
||||||
@@ -274,222 +267,165 @@ fun StatsScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item { Spacer(Modifier) }
|
|
||||||
|
item { Spacer(Modifier.height(12.dp)) }
|
||||||
|
|
||||||
item {
|
item {
|
||||||
Text(
|
|
||||||
stringResource(R.string.last_week),
|
|
||||||
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(lastWeekAverageFocusTimes) {
|
|
||||||
lastWeekAverageFocusTimes.sum().toLong()
|
|
||||||
},
|
|
||||||
hoursMinutesFormat
|
|
||||||
),
|
|
||||||
style = typography.displaySmall
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
stringResource(R.string.focus_per_day_avg),
|
|
||||||
style = typography.titleSmall,
|
|
||||||
modifier = Modifier.padding(bottom = 5.2.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
TimeColumnChart(
|
|
||||||
modelProducer = lastWeekSummaryChartData.first,
|
|
||||||
hoursFormat = hoursFormat,
|
|
||||||
hoursMinutesFormat = hoursMinutesFormat,
|
|
||||||
minutesFormat = minutesFormat,
|
|
||||||
modifier = Modifier.padding(start = 16.dp),
|
|
||||||
axisTypeface = axisTypeface,
|
|
||||||
markerTypeface = markerTypeface,
|
|
||||||
xValueFormatter = CartesianValueFormatter { context, x, _ ->
|
|
||||||
context.model.extraStore[lastWeekSummaryChartData.second][x.toInt()]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
val iconRotation by animateFloatAsState(
|
|
||||||
if (lastWeekStatExpanded) 180f else 0f,
|
|
||||||
animationSpec = motionScheme.defaultSpatialSpec()
|
|
||||||
)
|
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier
|
||||||
|
.clip(topListItemShape)
|
||||||
|
.background(listItemColors.containerColor)
|
||||||
|
.clickable {}
|
||||||
|
.padding(
|
||||||
|
start = 20.dp,
|
||||||
|
top = 20.dp,
|
||||||
|
bottom = 20.dp
|
||||||
|
) // end = 0 to let the chart touch the end
|
||||||
) {
|
) {
|
||||||
Spacer(Modifier.height(2.dp))
|
Text(
|
||||||
FilledTonalIconToggleButton(
|
stringResource(R.string.last_week),
|
||||||
checked = lastWeekStatExpanded,
|
style = typography.headlineSmall
|
||||||
onCheckedChange = { lastWeekStatExpanded = it },
|
)
|
||||||
shapes = IconButtonDefaults.toggleableShapes(),
|
|
||||||
modifier = Modifier
|
Row(
|
||||||
.padding(horizontal = 16.dp)
|
verticalAlignment = Alignment.Bottom,
|
||||||
.width(52.dp)
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
.align(Alignment.End)
|
|
||||||
) {
|
) {
|
||||||
Icon(
|
Text(
|
||||||
painterResource(R.drawable.arrow_down),
|
millisecondsToHoursMinutes(
|
||||||
stringResource(R.string.more_info),
|
remember(lastWeekAverageFocusTimes) {
|
||||||
modifier = Modifier.rotate(iconRotation)
|
lastWeekAverageFocusTimes.sum().toLong()
|
||||||
|
},
|
||||||
|
hoursMinutesFormat
|
||||||
|
),
|
||||||
|
style = typography.displaySmall
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
stringResource(R.string.focus_per_day_avg),
|
||||||
|
style = typography.titleSmall,
|
||||||
|
modifier = Modifier.padding(bottom = 5.2.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ProductivityGraph(
|
|
||||||
lastWeekStatExpanded,
|
TimeColumnChart(
|
||||||
lastWeekSummaryAnalysisModelProducer,
|
modelProducer = lastWeekSummaryChartData.first,
|
||||||
|
hoursFormat = hoursFormat,
|
||||||
|
hoursMinutesFormat = hoursMinutesFormat,
|
||||||
|
minutesFormat = minutesFormat,
|
||||||
axisTypeface = axisTypeface,
|
axisTypeface = axisTypeface,
|
||||||
markerTypeface = markerTypeface,
|
markerTypeface = markerTypeface,
|
||||||
label = stringResource(R.string.weekly_productivity_analysis),
|
xValueFormatter = CartesianValueFormatter { context, x, _ ->
|
||||||
modifier = Modifier.padding(horizontal = 32.dp)
|
context.model.extraStore[lastWeekSummaryChartData.second][x.toInt()]
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item { Spacer(Modifier) }
|
|
||||||
item {
|
item {
|
||||||
Text(
|
|
||||||
stringResource(R.string.last_month),
|
|
||||||
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(lastMonthAverageFocusTimes) {
|
|
||||||
lastMonthAverageFocusTimes.sum().toLong()
|
|
||||||
},
|
|
||||||
hoursMinutesFormat
|
|
||||||
),
|
|
||||||
style = typography.displaySmall
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.focus_per_day_avg),
|
|
||||||
style = typography.titleSmall,
|
|
||||||
modifier = Modifier.padding(bottom = 5.2.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
TimeColumnChart(
|
|
||||||
modelProducer = lastMonthSummaryChartData.first,
|
|
||||||
hoursFormat = hoursFormat,
|
|
||||||
hoursMinutesFormat = hoursMinutesFormat,
|
|
||||||
minutesFormat = minutesFormat,
|
|
||||||
modifier = Modifier.padding(start = 16.dp),
|
|
||||||
axisTypeface = axisTypeface,
|
|
||||||
markerTypeface = markerTypeface,
|
|
||||||
thickness = 8.dp,
|
|
||||||
xValueFormatter = CartesianValueFormatter { context, x, _ ->
|
|
||||||
context.model.extraStore[lastMonthSummaryChartData.second][x.toInt()]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
val iconRotation by animateFloatAsState(
|
|
||||||
if (lastMonthStatExpanded) 180f else 0f,
|
|
||||||
animationSpec = motionScheme.defaultSpatialSpec()
|
|
||||||
)
|
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier
|
||||||
|
.clip(middleListItemShape)
|
||||||
|
.background(listItemColors.containerColor)
|
||||||
|
.clickable {}
|
||||||
|
.padding(
|
||||||
|
start = 20.dp,
|
||||||
|
top = 20.dp,
|
||||||
|
bottom = 20.dp
|
||||||
|
) // end = 0 to let the chart touch the end
|
||||||
) {
|
) {
|
||||||
Spacer(Modifier.height(2.dp))
|
Text(
|
||||||
FilledTonalIconToggleButton(
|
stringResource(R.string.last_month),
|
||||||
checked = lastMonthStatExpanded,
|
style = typography.headlineSmall
|
||||||
onCheckedChange = { lastMonthStatExpanded = it },
|
)
|
||||||
shapes = IconButtonDefaults.toggleableShapes(),
|
|
||||||
modifier = Modifier
|
Row(
|
||||||
.padding(horizontal = 16.dp)
|
verticalAlignment = Alignment.Bottom,
|
||||||
.width(52.dp)
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
.align(Alignment.End)
|
|
||||||
) {
|
) {
|
||||||
Icon(
|
Text(
|
||||||
painterResource(R.drawable.arrow_down),
|
millisecondsToHoursMinutes(
|
||||||
stringResource(R.string.more_info),
|
remember(lastMonthAverageFocusTimes) {
|
||||||
modifier = Modifier.rotate(iconRotation)
|
lastMonthAverageFocusTimes.sum().toLong()
|
||||||
|
},
|
||||||
|
hoursMinutesFormat
|
||||||
|
),
|
||||||
|
style = typography.displaySmall
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.focus_per_day_avg),
|
||||||
|
style = typography.titleSmall,
|
||||||
|
modifier = Modifier.padding(bottom = 5.2.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ProductivityGraph(
|
|
||||||
lastMonthStatExpanded,
|
TimeColumnChart(
|
||||||
lastMonthSummaryAnalysisModelProducer,
|
modelProducer = lastMonthSummaryChartData.first,
|
||||||
|
hoursFormat = hoursFormat,
|
||||||
|
hoursMinutesFormat = hoursMinutesFormat,
|
||||||
|
minutesFormat = minutesFormat,
|
||||||
axisTypeface = axisTypeface,
|
axisTypeface = axisTypeface,
|
||||||
markerTypeface = markerTypeface,
|
markerTypeface = markerTypeface,
|
||||||
label = stringResource(R.string.monthly_productivity_analysis),
|
thickness = 8.dp,
|
||||||
modifier = Modifier.padding(horizontal = 32.dp)
|
xValueFormatter = CartesianValueFormatter { context, x, _ ->
|
||||||
|
context.model.extraStore[lastMonthSummaryChartData.second][x.toInt()]
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item { Spacer(Modifier) }
|
|
||||||
item {
|
item {
|
||||||
Text(
|
Column(
|
||||||
stringResource(R.string.last_year),
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
style = typography.headlineSmall,
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.clip(bottomListItemShape)
|
||||||
.padding(horizontal = 16.dp)
|
.background(listItemColors.containerColor)
|
||||||
)
|
.clickable {}
|
||||||
}
|
.padding(
|
||||||
item {
|
start = 20.dp,
|
||||||
Row(
|
top = 20.dp,
|
||||||
verticalAlignment = Alignment.Bottom,
|
bottom = 20.dp
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
) // end = 0 to let the chart touch the end
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
millisecondsToHoursMinutes(
|
stringResource(R.string.last_year),
|
||||||
remember(lastYearAverageFocusTimes) {
|
style = typography.headlineSmall
|
||||||
lastYearAverageFocusTimes.sum().toLong()
|
|
||||||
},
|
|
||||||
hoursMinutesFormat
|
|
||||||
),
|
|
||||||
style = typography.displaySmall
|
|
||||||
)
|
)
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.focus_per_day_avg),
|
Row(
|
||||||
style = typography.titleSmall,
|
verticalAlignment = Alignment.Bottom,
|
||||||
modifier = Modifier.padding(bottom = 5.2.dp)
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
millisecondsToHoursMinutes(
|
||||||
|
remember(lastYearAverageFocusTimes) {
|
||||||
|
lastYearAverageFocusTimes.sum().toLong()
|
||||||
|
},
|
||||||
|
hoursMinutesFormat
|
||||||
|
),
|
||||||
|
style = typography.displaySmall
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.focus_per_day_avg),
|
||||||
|
style = typography.titleSmall,
|
||||||
|
modifier = Modifier.padding(bottom = 5.2.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeLineChart(
|
||||||
|
modelProducer = lastYearSummaryChartData.first,
|
||||||
|
hoursFormat = hoursFormat,
|
||||||
|
hoursMinutesFormat = hoursMinutesFormat,
|
||||||
|
minutesFormat = minutesFormat,
|
||||||
|
axisTypeface = axisTypeface,
|
||||||
|
markerTypeface = markerTypeface,
|
||||||
|
xValueFormatter = CartesianValueFormatter { context, x, _ ->
|
||||||
|
context.model.extraStore[lastYearSummaryChartData.second][x.toInt()]
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item {
|
|
||||||
TimeLineChart(
|
|
||||||
modelProducer = lastYearSummaryChartData.first,
|
|
||||||
hoursFormat = hoursFormat,
|
|
||||||
hoursMinutesFormat = hoursMinutesFormat,
|
|
||||||
minutesFormat = minutesFormat,
|
|
||||||
modifier = Modifier.padding(start = 16.dp),
|
|
||||||
axisTypeface = axisTypeface,
|
|
||||||
markerTypeface = markerTypeface,
|
|
||||||
xValueFormatter = CartesianValueFormatter { context, x, _ ->
|
|
||||||
context.model.extraStore[lastYearSummaryChartData.second][x.toInt()]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
item { Spacer(Modifier.height(16.dp)) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user