From 0c1aa51ecbaeb370a8c5e766be5dd89fc3820a6c Mon Sep 17 00:00:00 2001 From: Jacob Bosco Date: Mon, 2 Dec 2024 23:13:36 +0530 Subject: [PATCH] WTA #71 updated project details to use lazy column --- .idea/inspectionProfiles/Project_Default.xml | 27 ++++++++ .idea/kotlinc.xml | 4 -- .idea/ktlint-plugin.xml | 3 + README.md | 16 ++++- .../details/ui/components/ProjectHistory.kt | 63 +++++++------------ .../details/ui/components/TimeTab.kt | 44 ++++++++++--- .../ui/components/OtherDailyStatsSection.kt | 2 +- 7 files changed, 104 insertions(+), 55 deletions(-) diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 2623f63d..77ed3c1c 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -1,7 +1,31 @@ + + DISABLED + \ No newline at end of file diff --git a/README.md b/README.md index 24572458..decb1315 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,21 @@ Uses `Export API` to get all user stats without having to upgrade your account ## Screenshots -| Login | ![Login Page](/imgs/Login.png) Login Page | ![Loading extracts from WakaTime](/imgs/Extract.png) Loading extracts from WakaTime | -|-----------|-------------------------------------------------|-------------------------------------------------------------------------------------| -| Home Page | ![Home Page 1](/imgs/HomePage1.png) Home Page 1 | ![Home Page 2](/imgs/HomePage2.png) Home Page 2 | +| Login | ![Login Page](/imgs/Login.png) | ![Loading extracts from WakaTime](/imgs/Extract.png) | +|-----------|-------------------------------------|------------------------------------------------------| +| Home Page | ![Home Page 1](/imgs/HomePage1.png) | ![Home Page 2](/imgs/HomePage2.png) | ## TODO - Show detailed stats for projects - Show details stats for specific time range + +## Setup + +Create file `local.properties` if not already created and add below properties for app id and app secret from +[here](https://wakatime.com/apps). Values will be read from build script and used in code. + +```properties +CLIENT_ID=APP_ID_HERE +CLIENT_SECRET=APP_SECRET_HERE +``` diff --git a/details/src/main/java/com/jacob/wakatimeapp/details/ui/components/ProjectHistory.kt b/details/src/main/java/com/jacob/wakatimeapp/details/ui/components/ProjectHistory.kt index f374ba06..953cf546 100644 --- a/details/src/main/java/com/jacob/wakatimeapp/details/ui/components/ProjectHistory.kt +++ b/details/src/main/java/com/jacob/wakatimeapp/details/ui/components/ProjectHistory.kt @@ -2,9 +2,10 @@ package com.jacob.wakatimeapp.details.ui.components import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.items import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text @@ -18,28 +19,28 @@ import com.jacob.wakatimeapp.core.ui.theme.cardHeader import com.jacob.wakatimeapp.core.ui.theme.cardSubtitle import com.jacob.wakatimeapp.core.ui.theme.spacing import kotlinx.collections.immutable.ImmutableMap -import kotlinx.collections.immutable.toImmutableMap import kotlinx.datetime.LocalDate import kotlinx.datetime.format import kotlinx.datetime.format.DayOfWeekNames import kotlinx.datetime.format.MonthNames import kotlinx.datetime.format.char +import java.util.Comparator.comparing -@Composable -internal fun ProjectHistory( +private const val BaseYear = 2000 + +internal fun LazyListScope.projectHistory( statsForProject: ImmutableMap, - modifier: Modifier = Modifier, ) { - Column( - modifier = modifier.fillMaxSize(), - verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.small), + item { + Text(text = "Project History", modifier = Modifier.padding(vertical = MaterialTheme.spacing.extraSmall)) + } + items( + items = statsForProject.filter { it.value != Time.ZERO } + .toSortedMap(comparing { -it.toEpochDays() }) + .toList(), + key = { it.first.toEpochDays() }, ) { - Text(text = "Project History", modifier = Modifier.padding(vertical = MaterialTheme.spacing.small)) - statsForProject - .filter { it.value != Time.ZERO } - .forEach { localDateTimePair -> - ProjectHistoryItem(entry = localDateTimePair.toPair()) - } + ProjectHistoryItem(entry = it) } } @@ -48,14 +49,15 @@ fun ProjectHistoryItem( entry: Pair, modifier: Modifier = Modifier, ) { - val format = - LocalDate.Format { - dayOfWeek(DayOfWeekNames.ENGLISH_ABBREVIATED) - chars(", ") - monthName(MonthNames.ENGLISH_ABBREVIATED) - char(' ') - dayOfMonth() - } + val format = LocalDate.Format { + dayOfWeek(DayOfWeekNames.ENGLISH_ABBREVIATED) + chars(", ") + monthName(MonthNames.ENGLISH_ABBREVIATED) + char(' ') + dayOfMonth() + chars(", ") + yearTwoDigits(BaseYear) + } WtaSurface(modifier = modifier.fillMaxWidth()) { Column( @@ -85,20 +87,3 @@ private fun ProjectHistoryItemPreview() { } } } - -@WtaComponentPreviews -@Composable -private fun ProjectHistoryListPreview() { - WakaTimeAppTheme { - Surface { - ProjectHistory( - statsForProject = - mapOf( - LocalDate.fromEpochDays(1) to Time(1, 1, 1f), - LocalDate.fromEpochDays(2) to Time(1, 1, 1f), - LocalDate.fromEpochDays(3) to Time(1, 1, 1f), - ).toImmutableMap(), - ) - } - } -} diff --git a/details/src/main/java/com/jacob/wakatimeapp/details/ui/components/TimeTab.kt b/details/src/main/java/com/jacob/wakatimeapp/details/ui/components/TimeTab.kt index 308157d1..e425aa0c 100644 --- a/details/src/main/java/com/jacob/wakatimeapp/details/ui/components/TimeTab.kt +++ b/details/src/main/java/com/jacob/wakatimeapp/details/ui/components/TimeTab.kt @@ -1,13 +1,11 @@ package com.jacob.wakatimeapp.details.ui.components import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text @@ -15,26 +13,32 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.jacob.wakatimeapp.core.models.Time +import com.jacob.wakatimeapp.core.ui.WtaComponentPreviews import com.jacob.wakatimeapp.core.ui.components.VicoBarChart import com.jacob.wakatimeapp.core.ui.components.VicoBarChartData +import com.jacob.wakatimeapp.core.ui.theme.WakaTimeAppTheme import com.jacob.wakatimeapp.core.ui.theme.spacing import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.toImmutableList +import kotlinx.collections.immutable.toImmutableMap +import kotlinx.datetime.Clock import kotlinx.datetime.LocalDate +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toLocalDateTime private const val DaysInChart = 30 @Composable internal fun TimeTab(statsForProject: ImmutableMap, today: LocalDate, modifier: Modifier = Modifier) { - Column( + LazyColumn( verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.small), modifier = modifier .fillMaxSize() - .verticalScroll(rememberScrollState()), + .padding(horizontal = MaterialTheme.spacing.sMedium), ) { - RecentTimeSpentChart(statsForProject, today) - QuickStatsCards() - ProjectHistory(statsForProject, modifier = Modifier.padding(horizontal = MaterialTheme.spacing.small)) + item { RecentTimeSpentChart(statsForProject, today) } + item { QuickStatsCards() } + projectHistory(statsForProject) } } @@ -61,3 +65,27 @@ private fun RecentTimeSpentChart(weeklyTimeSpent: ImmutableMap, showLabel = false, ) } + +@WtaComponentPreviews +@Composable +private fun ProjectHistoryListPreview() { + WakaTimeAppTheme { + Surface { + TimeTab( + mapOf( + LocalDate.fromEpochDays(1) to Time.fromDecimal(3f), + LocalDate.fromEpochDays(2) to Time.fromDecimal(1f), + LocalDate.fromEpochDays(3) to Time.fromDecimal(2f), + LocalDate.fromEpochDays(4) to Time.fromDecimal(2f), + LocalDate.fromEpochDays(5) to Time.fromDecimal(4f), + LocalDate.fromEpochDays(6) to Time.fromDecimal(3f), + LocalDate.fromEpochDays(7) to Time.fromDecimal(2f), + LocalDate.fromEpochDays(8) to Time.fromDecimal(3f), + LocalDate.fromEpochDays(9) to Time.fromDecimal(4f), + LocalDate.fromEpochDays(10) to Time.fromDecimal(1f), + ).toImmutableMap(), + today = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date, + ) + } + } +} diff --git a/home/src/main/java/com/jacob/wakatimeapp/home/ui/components/OtherDailyStatsSection.kt b/home/src/main/java/com/jacob/wakatimeapp/home/ui/components/OtherDailyStatsSection.kt index 3fcda2cc..50d898cd 100644 --- a/home/src/main/java/com/jacob/wakatimeapp/home/ui/components/OtherDailyStatsSection.kt +++ b/home/src/main/java/com/jacob/wakatimeapp/home/ui/components/OtherDailyStatsSection.kt @@ -145,7 +145,7 @@ private fun SectionHeader() = Row( modifier = Modifier.fillMaxWidth(), ) { val typography = MaterialTheme.typography - Text(text = "Other Stats", style = typography.sectionTitle) + Text(text = "Other Daily Stats", style = typography.sectionTitle) Text(text = "Details", color = colorScheme.primary, style = typography.sectionSubtitle) }