From b0ed28ac38ade4b13c9283e801c43bb66a03fac3 Mon Sep 17 00:00:00 2001 From: edrees Date: Sat, 18 Oct 2025 18:36:14 +0300 Subject: [PATCH] feat: implement streak management logic in StartPlayFragment and UserRepository --- .../qurio/data/local/UserDataSource.kt | 8 ---- .../data/repository/UserRepositoryImpl.kt | 40 +++++++++++++++++-- .../qurio/domain/repository/UserRepository.kt | 4 +- .../presentation/screen/home/HomePresenter.kt | 1 - .../screen/results/StartPlayFragment.kt | 4 ++ .../screen/results/StartPlayPresenter.kt | 16 ++++++++ .../main/res/layout/fragment_start_play.xml | 5 ++- .../main/res/navigation/qurio_navigation.xml | 3 ++ 8 files changed, 65 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/thechance/qurio/data/local/UserDataSource.kt b/app/src/main/java/com/thechance/qurio/data/local/UserDataSource.kt index ada1e92..2f03cf5 100644 --- a/app/src/main/java/com/thechance/qurio/data/local/UserDataSource.kt +++ b/app/src/main/java/com/thechance/qurio/data/local/UserDataSource.kt @@ -1,6 +1,4 @@ package com.thechance.qurio.data.local -import android.content.Context -import com.thechance.qurio.R import com.thechance.qurio.domain.entity.Character @@ -11,7 +9,6 @@ object UserDataSource{ private var lives: Int = 4 private var points: Int = 700 private var awards: Int = 0 - private var currentStreak: Int = 0 fun getUserCharacter() = currentCharacter fun updateUserCharacter(newCharacter: Character) { currentCharacter = newCharacter } @@ -23,9 +20,4 @@ object UserDataSource{ fun addPoints(pointsToAdd: Int) { points += pointsToAdd } fun updateAwards(newAwards: Int) { awards = newAwards } fun incrementAwards() { awards++ } - - fun getUserStreak() = currentStreak - fun updateStreak(newStreak: Int) { currentStreak = newStreak } - fun incrementStreak() { currentStreak++ } - fun resetStreak() { currentStreak = 0 } } diff --git a/app/src/main/java/com/thechance/qurio/data/repository/UserRepositoryImpl.kt b/app/src/main/java/com/thechance/qurio/data/repository/UserRepositoryImpl.kt index c1e6be0..7fffd49 100644 --- a/app/src/main/java/com/thechance/qurio/data/repository/UserRepositoryImpl.kt +++ b/app/src/main/java/com/thechance/qurio/data/repository/UserRepositoryImpl.kt @@ -1,14 +1,26 @@ package com.thechance.qurio.data.repository import android.content.Context +import androidx.datastore.core.DataStore +import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.intPreferencesKey +import androidx.datastore.preferences.core.stringPreferencesKey import com.thechance.qurio.data.local.CharactersDataSource import com.thechance.qurio.data.local.UserDataSource import com.thechance.qurio.domain.entity.Character import com.thechance.qurio.domain.repository.user.UserRepository +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map +import kotlinx.datetime.Clock +import kotlinx.datetime.LocalDate +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toLocalDateTime import javax.inject.Inject class UserRepositoryImpl @Inject constructor( private val context: Context, + private val preferences: DataStore ) : UserRepository { @@ -25,15 +37,31 @@ class UserRepositoryImpl @Inject constructor( } override suspend fun getUserStreak(): Int { - return UserDataSource.getUserStreak() + return preferences.data.map { + it[KEY_CURRENT_STREAK] ?: 0 + }.first() } - override suspend fun updateStreak(streak: Int) { - UserDataSource.updateStreak(streak) + override suspend fun getLastPlayedDate(): LocalDate { + return preferences.data.map { + it[KEY_LAST_PLAYED_DATE]?.let { dateString -> + LocalDate.parse(dateString) + } ?: LocalDate(1970, 1, 1) + }.first() + } + + override suspend fun resetStreak() { + preferences.edit { + it[KEY_CURRENT_STREAK] = 1 + it[KEY_LAST_PLAYED_DATE] = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date.toString() + } } override suspend fun incrementStreak() { - UserDataSource.incrementStreak() + preferences.edit { + it[KEY_CURRENT_STREAK] = (it[KEY_CURRENT_STREAK] ?: 0) + 1 + it[KEY_LAST_PLAYED_DATE] = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date.toString() + } } override suspend fun addPoints(points: Int) { @@ -52,4 +80,8 @@ class UserRepositoryImpl @Inject constructor( UserDataSource.updateAwards(awards) } + private companion object { + val KEY_CURRENT_STREAK = intPreferencesKey("current_streak") + val KEY_LAST_PLAYED_DATE = stringPreferencesKey("last_played_date") + } } \ No newline at end of file diff --git a/app/src/main/java/com/thechance/qurio/domain/repository/UserRepository.kt b/app/src/main/java/com/thechance/qurio/domain/repository/UserRepository.kt index 88a5d40..2fe423f 100644 --- a/app/src/main/java/com/thechance/qurio/domain/repository/UserRepository.kt +++ b/app/src/main/java/com/thechance/qurio/domain/repository/UserRepository.kt @@ -1,13 +1,15 @@ package com.thechance.qurio.domain.repository.user import com.thechance.qurio.domain.entity.Character +import kotlinx.datetime.LocalDate interface UserRepository { suspend fun getUserCharacter(): Character suspend fun updateUserCharacter(character: Character) suspend fun getUserStatistics(): Triple suspend fun getUserStreak(): Int - suspend fun updateStreak(streak: Int) + suspend fun getLastPlayedDate(): LocalDate + suspend fun resetStreak() suspend fun incrementStreak() suspend fun addPoints(points: Int) suspend fun updateLives(lives: Int) diff --git a/app/src/main/java/com/thechance/qurio/presentation/screen/home/HomePresenter.kt b/app/src/main/java/com/thechance/qurio/presentation/screen/home/HomePresenter.kt index cb56a03..23fb06d 100644 --- a/app/src/main/java/com/thechance/qurio/presentation/screen/home/HomePresenter.kt +++ b/app/src/main/java/com/thechance/qurio/presentation/screen/home/HomePresenter.kt @@ -46,7 +46,6 @@ class HomePresenter @Inject constructor( } private fun onGetUserStatisticsSuccess(statistics: Triple) { - println("get$statistics") view.setUserStatistics(statistics) } diff --git a/app/src/main/java/com/thechance/qurio/presentation/screen/results/StartPlayFragment.kt b/app/src/main/java/com/thechance/qurio/presentation/screen/results/StartPlayFragment.kt index 6024cb8..3b83ff3 100644 --- a/app/src/main/java/com/thechance/qurio/presentation/screen/results/StartPlayFragment.kt +++ b/app/src/main/java/com/thechance/qurio/presentation/screen/results/StartPlayFragment.kt @@ -42,6 +42,10 @@ class StartPlayFragment : binding.skipButton.setOnClickListener { startPlayPresenter.nextQuestion() } + + binding.backButton.setOnClickListener { + findNavController().navigate(StartPlayFragmentDirections.actionStartPlayFragmentToHomeFragment()) + } } override fun onDestroyView() { diff --git a/app/src/main/java/com/thechance/qurio/presentation/screen/results/StartPlayPresenter.kt b/app/src/main/java/com/thechance/qurio/presentation/screen/results/StartPlayPresenter.kt index 1792de9..2606db6 100644 --- a/app/src/main/java/com/thechance/qurio/presentation/screen/results/StartPlayPresenter.kt +++ b/app/src/main/java/com/thechance/qurio/presentation/screen/results/StartPlayPresenter.kt @@ -9,6 +9,9 @@ import com.thechance.qurio.domain.repository.user.UserRepository import com.thechance.qurio.presentation.base.BasePresenter import com.thechance.qurio.presentation.screen.achievements.AchievementsManager import com.thechance.qurio.presentation.screen.difficulty.DifficultyLevel +import kotlinx.datetime.Clock +import kotlinx.datetime.daysUntil +import kotlinx.datetime.toLocalDateTime import javax.inject.Inject class StartPlayPresenter @Inject constructor( @@ -184,6 +187,7 @@ class StartPlayPresenter @Inject constructor( totalTimeSeconds = session.totalTimeSeconds, earnedCoins = session.earnedCoins ) + updateStreak() if (stars == 0) { tryToExecute( callee = { decreaseLives() }, @@ -203,6 +207,18 @@ class StartPlayPresenter @Inject constructor( ) } + private suspend fun updateStreak() { + val lastPlayedGame = userRepository.getLastPlayedDate() + val today = Clock.System.now() + .toLocalDateTime(kotlinx.datetime.TimeZone.currentSystemDefault()).date + val daysBetween = today.daysUntil(lastPlayedGame) + when (daysBetween) { + 0 -> Unit + 1 -> { userRepository.incrementStreak() } + else -> { userRepository.resetStreak() } + } + } + private suspend fun decreaseLives() { val stats = userRepository.getUserStatistics() val currentLives = stats.first diff --git a/app/src/main/res/layout/fragment_start_play.xml b/app/src/main/res/layout/fragment_start_play.xml index c05876e..2c4a84d 100644 --- a/app/src/main/res/layout/fragment_start_play.xml +++ b/app/src/main/res/layout/fragment_start_play.xml @@ -45,8 +45,9 @@ diff --git a/app/src/main/res/navigation/qurio_navigation.xml b/app/src/main/res/navigation/qurio_navigation.xml index 4d191a1..4860b0c 100644 --- a/app/src/main/res/navigation/qurio_navigation.xml +++ b/app/src/main/res/navigation/qurio_navigation.xml @@ -25,6 +25,9 @@ +