diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/components/FocusBreakdownTooltip.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/components/FocusBreakdownTooltip.kt new file mode 100644 index 0000000..8425184 --- /dev/null +++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/components/FocusBreakdownTooltip.kt @@ -0,0 +1,97 @@ +/* + * 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 . + */ + +package org.nsh07.pomodoro.ui.statsScreen.components + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme.colorScheme +import androidx.compose.material3.MaterialTheme.shapes +import androidx.compose.material3.MaterialTheme.typography +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Popup +import org.nsh07.pomodoro.R +import org.nsh07.pomodoro.data.Stat +import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes +import java.time.format.DateTimeFormatter +import kotlin.math.roundToInt + +@Composable +fun FocusBreakdownTooltip( + item: Stat, + rankList: List, + dateFormat: DateTimeFormatter, + onDismissRequest: (() -> Unit) +) { + val tooltipOffset = with(LocalDensity.current) { + (16 * 2 + // Vertical padding in the tooltip card + typography.titleSmall.lineHeight.value + 4 + // Heading + typography.bodyMedium.lineHeight.value + 8 + // Text + HORIZONTAL_STACKED_BAR_HEIGHT.value + // Obvious + 8).dp.toPx().roundToInt() + } + val values = listOf( + item.focusTimeQ1, + item.focusTimeQ2, + item.focusTimeQ3, + item.focusTimeQ4 + ) + Popup( + alignment = Alignment.TopCenter, + offset = IntOffset(0, -tooltipOffset), + onDismissRequest = onDismissRequest + ) { + Surface( + shape = shapes.large, + color = colorScheme.surfaceContainer, + contentColor = colorScheme.onSurfaceVariant, + shadowElevation = 3.dp, + tonalElevation = 3.dp, + modifier = Modifier.padding(horizontal = 16.dp) + ) { + Column(Modifier.padding(16.dp)) { + Text( + text = item.date.format(dateFormat), + style = typography.titleSmall + ) + Spacer(Modifier.height(4.dp)) + Text( + text = millisecondsToHoursMinutes( + item.totalFocusTime(), + stringResource(R.string.hours_and_minutes_format) + ), + style = typography.bodyMedium + ) + Spacer(Modifier.height(8.dp)) + HorizontalStackedBar( + values = values, + rankList = rankList + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/components/FocusHistoryCalendar.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/components/FocusHistoryCalendar.kt index aeaa0c4..8c8a6ce 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/components/FocusHistoryCalendar.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/components/FocusHistoryCalendar.kt @@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -46,28 +45,21 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEach import androidx.compose.ui.util.fastForEachIndexed -import androidx.compose.ui.window.Popup -import org.nsh07.pomodoro.R import org.nsh07.pomodoro.data.Stat import org.nsh07.pomodoro.ui.theme.TomatoTheme -import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes import java.time.DayOfWeek import java.time.LocalDate import java.time.format.DateTimeFormatter import java.time.format.FormatStyle import java.time.format.TextStyle import java.util.Locale -import kotlin.math.roundToInt import kotlin.random.Random val CALENDAR_CELL_SIZE = 40.dp @@ -123,14 +115,6 @@ fun FocusHistoryCalendar( DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withLocale(locale) } - val tooltipOffset = with(LocalDensity.current) { - (16 * 2 + // Vertical padding in the tooltip card - typography.titleSmall.lineHeight.value + 4 + // Heading - typography.bodyMedium.lineHeight.value + 8 + // Text - HORIZONTAL_STACKED_BAR_HEIGHT.value + // Obvious - 8).dp.toPx().roundToInt() - } - val groupedData = remember(data) { data.chunked(7) } @@ -220,48 +204,11 @@ fun FocusHistoryCalendar( ) if (isTooltipVisible) { - val values = remember(it) { - listOf( - it.focusTimeQ1, - it.focusTimeQ2, - it.focusTimeQ3, - it.focusTimeQ4 - ) - } - Popup( - alignment = Alignment.TopCenter, - offset = IntOffset(0, -tooltipOffset), - onDismissRequest = { selectedItemIndex = -1 } - ) { - Surface( - shape = shapes.large, - color = colorScheme.surfaceContainer, - contentColor = colorScheme.onSurfaceVariant, - shadowElevation = 3.dp, - tonalElevation = 3.dp, - modifier = Modifier.padding(horizontal = 16.dp) - ) { - Column(Modifier.padding(16.dp)) { - Text( - text = it.date.format(dateFormat), - style = typography.titleSmall - ) - Spacer(Modifier.height(4.dp)) - Text( - text = millisecondsToHoursMinutes( - sum, - stringResource(R.string.hours_and_minutes_format) - ), - style = typography.bodyMedium - ) - Spacer(Modifier.height(8.dp)) - HorizontalStackedBar( - values = values, - rankList = averageRankList - ) - } - } - } + FocusBreakdownTooltip( + it, + averageRankList, + dateFormat + ) { selectedItemIndex = -1 } } } } diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/components/HeatmapWithWeekLabels.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/components/HeatmapWithWeekLabels.kt index 5d89eea..6685ebc 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/components/HeatmapWithWeekLabels.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/components/HeatmapWithWeekLabels.kt @@ -47,26 +47,19 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEach import androidx.compose.ui.util.fastMaxBy -import androidx.compose.ui.window.Popup -import org.nsh07.pomodoro.R import org.nsh07.pomodoro.data.Stat import org.nsh07.pomodoro.ui.theme.TomatoTheme -import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes import java.time.DayOfWeek import java.time.LocalDate import java.time.format.DateTimeFormatter import java.time.format.FormatStyle import java.time.format.TextStyle import java.util.Locale -import kotlin.math.roundToInt val HEATMAP_CELL_SIZE = 28.dp val HEATMAP_CELL_GAP = 2.dp @@ -109,14 +102,6 @@ fun HeatmapWithWeekLabels( } } // Names of the 7 days of the week in the current locale - val tooltipOffset = with(LocalDensity.current) { - (16 * 2 + // Vertical padding in the tooltip card - typography.titleSmall.lineHeight.value + 4 + // Heading - typography.bodyMedium.lineHeight.value + 8 + // Text - HORIZONTAL_STACKED_BAR_HEIGHT.value + // Obvious - 8).dp.toPx().roundToInt() - } - val dateFormat = remember(locale) { DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withLocale(locale) } @@ -186,51 +171,11 @@ fun HeatmapWithWeekLabels( .clickable { activeTooltipIndex = index } ) { if (isTooltipVisible) { - val values = remember(it) { - listOf( - it.focusTimeQ1, - it.focusTimeQ2, - it.focusTimeQ3, - it.focusTimeQ4 - ) - } - - Popup( - alignment = Alignment.TopCenter, - offset = IntOffset(0, -tooltipOffset), - onDismissRequest = { - activeTooltipIndex = -1 - } - ) { - Surface( - shape = shapes.large, - color = colorScheme.surfaceContainer, - contentColor = colorScheme.onSurfaceVariant, - shadowElevation = 3.dp, - tonalElevation = 3.dp, - modifier = Modifier.padding(horizontal = 16.dp) - ) { - Column(Modifier.padding(16.dp)) { - Text( - text = it.date.format(dateFormat), - style = typography.titleSmall - ) - Spacer(Modifier.height(4.dp)) - Text( - text = millisecondsToHoursMinutes( - sum, - stringResource(R.string.hours_and_minutes_format) - ), - style = typography.bodyMedium - ) - Spacer(Modifier.height(8.dp)) - HorizontalStackedBar( - values = values, - rankList = averageRankList - ) - } - } - } + FocusBreakdownTooltip( + it, + averageRankList, + dateFormat + ) { activeTooltipIndex = -1 } } } }