Skip to content

Commit

Permalink
Fixed CalculateLongestStreakUC
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacob3075 committed Oct 16, 2024
1 parent bbd6e1f commit 1996dd4
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,17 @@ class WakaTimeAppDB @Inject constructor(
applicationDao.updateDbWithNewData(detailedDailyStats)
}.mapLeft { Error.DatabaseError.UnknownError("could not insert aggregate stats data into db", it) }

suspend fun getStatsForRange(startDate: LocalDate, endDate: LocalDate): EitherErrorOr<List<DayWithProjects>> = Either.catch {
applicationDao.getStatsForRange(startDate, endDate).toDayWithProjects()
.fillMissingDaysWithZeroValues(startDate, endDate)
}.mapLeft { Error.DatabaseError.UnknownError("could not get stats for range ($startDate - $endDate)", it) }
suspend fun getStatsForRange(startDate: LocalDate, endDate: LocalDate): EitherErrorOr<List<DayWithProjects>> =
Either.catch {
applicationDao.getStatsForRange(startDate, endDate)
.toDayWithProjects()
.fillMissingDaysWithZeroValues(startDate, endDate)
}.mapLeft {
Error.DatabaseError.UnknownError(
"could not get stats for range ($startDate - $endDate)",
it,
)
}

suspend fun getAllProjects(): EitherErrorOr<List<ProjectPerDay>> = Either.catch {
applicationDao.getAllProjects()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.jacob.wakatimeapp.core.ui.components

import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun WtaSurface(modifier: Modifier = Modifier, onClick: () -> Unit = {}, content: @Composable () -> Unit) {
val cardShape = RoundedCornerShape(percent = 25)
Surface(
modifier = modifier,
shape = cardShape,
shadowElevation = 10.dp,
tonalElevation = 2.dp,
onClick = onClick,
) {
content()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ data class HomePageUserDetails(
data class Streak(
val start: LocalDate,
val end: LocalDate,
) {
) : Comparable<Streak> {
val days: Int = if (this == ZERO) 0 else start.daysUntil(end) + 1

operator fun plus(other: Streak) = when {
Expand All @@ -68,7 +68,7 @@ data class Streak(

operator fun contains(other: Streak) = other.start in this && other.end in this

operator fun compareTo(streak: Streak) = days.compareTo(streak.days)
override operator fun compareTo(other: Streak) = days.compareTo(other.days)

private fun padded() = Streak(start - oneDay, end + oneDay)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
package com.jacob.wakatimeapp.home.domain.usecases

import arrow.core.Either
import arrow.core.raise.either
import com.jacob.wakatimeapp.core.common.auth.AuthDataStore
import com.jacob.wakatimeapp.core.common.data.local.WakaTimeAppDB
import com.jacob.wakatimeapp.core.common.utils.InstantProvider
import com.jacob.wakatimeapp.core.models.DailyStatsAggregate
import com.jacob.wakatimeapp.core.models.Error
import com.jacob.wakatimeapp.core.models.Time
import com.jacob.wakatimeapp.home.data.local.HomePageCache
import com.jacob.wakatimeapp.home.data.mappers.toDailyStateAggregate
import com.jacob.wakatimeapp.home.domain.models.Streak
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.collections.Map.Entry
import kotlinx.coroutines.flow.first
import kotlinx.datetime.LocalDate
import kotlin.collections.Map.Entry

@Singleton
internal class CalculateLongestStreakUC @Inject constructor(
Expand All @@ -23,23 +25,28 @@ internal class CalculateLongestStreakUC @Inject constructor(
private val instantProvider: InstantProvider,
) {

suspend operator fun invoke() = either {
suspend operator fun invoke(): Either<Error, Streak> {
val longestStreak = homePageCache.getLongestStreak().first()
val currentStreak = homePageCache.getCurrentStreak().first()
val userDetails = authDataStore.userDetails.first()
val cachedLongestStreak = homePageCache.getLongestStreak().first().bind()
val currentStreak = homePageCache.getCurrentStreak().first().bind()

if (currentStreak > cachedLongestStreak) return@either currentStreak
if (cachedLongestStreak != Streak.ZERO) return@either cachedLongestStreak

val currentDay = instantProvider.date()
val userJoinedData = userDetails.createdAt
return either {
val longerStreak = maxOf(currentStreak.bind(), longestStreak.bind())
if (longerStreak == Streak.ZERO) {
calculateLongestStreak(userJoinedData = userDetails.createdAt, instantProvider.date()).bind()
} else {
longerStreak
}
}
}

wakaTimeAppDB.getStatsForRange(
startDate = userJoinedData,
endDate = currentDay,
)
.bind()
.toDailyStateAggregate()
private suspend fun calculateLongestStreak(
userJoinedData: LocalDate,
currentDay: LocalDate,
): Either<Error, Streak> = wakaTimeAppDB.getStatsForRange(
startDate = userJoinedData,
endDate = currentDay,
).map {
it.toDailyStateAggregate()
.groupConsecutiveDaysWithStats()
.filter(List<Entry<LocalDate, Time>>::isNotEmpty)
.toStreaks()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import com.jacob.wakatimeapp.home.domain.usecases.CalculateLongestStreakUC
import com.jacob.wakatimeapp.home.domain.usecases.GetLast7DaysStatsUC
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
import kotlinx.datetime.LocalDate
import kotlin.coroutines.CoroutineContext

@HiltViewModel
internal class HomePageViewModel @Inject constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.jacob.wakatimeapp.home.ui.components

import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
Expand All @@ -10,7 +9,6 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
Expand All @@ -19,10 +17,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.jacob.wakatimeapp.core.models.Time
import com.jacob.wakatimeapp.core.models.project.Project
import com.jacob.wakatimeapp.core.ui.WtaComponentPreviews
import com.jacob.wakatimeapp.core.ui.components.WtaSurface
import com.jacob.wakatimeapp.core.ui.theme.WakaTimeAppTheme
import com.jacob.wakatimeapp.core.ui.theme.assets
import com.jacob.wakatimeapp.core.ui.theme.cardHeader
Expand Down Expand Up @@ -74,16 +73,8 @@ private fun RecentProjectList(

@Composable
private fun ProjectCardItem(project: Project, onClick: (String) -> Unit) {
val cardShape = RoundedCornerShape(percent = 25)
val spacing = MaterialTheme.spacing
Surface(
modifier = Modifier
.fillMaxWidth(),
shape = cardShape,
shadowElevation = 10.dp,
tonalElevation = 2.dp,
onClick = { onClick(project.name) },
) {
WtaSurface(modifier = Modifier.fillMaxWidth(), onClick = { onClick(project.name) }) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
Expand All @@ -110,7 +101,7 @@ private fun ProjectCardItem(project: Project, onClick: (String) -> Unit) {
}
}

@Preview(showBackground = true, showSystemUi = true, uiMode = UI_MODE_NIGHT_YES)
@WtaComponentPreviews
@Composable
private fun RecentProjectPreview() = WakaTimeAppTheme(darkTheme = true) {
Surface {
Expand All @@ -126,7 +117,7 @@ private fun RecentProjectPreview() = WakaTimeAppTheme(darkTheme = true) {
}
}

@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_YES)
@WtaComponentPreviews
@Composable
private fun ProjectCardItemPreview() = WakaTimeAppTheme {
Surface {
Expand Down

0 comments on commit 1996dd4

Please sign in to comment.