diff --git a/app/src/main/java/org/nsh07/pomodoro/data/Preference.kt b/app/src/main/java/org/nsh07/pomodoro/data/Preference.kt index 50478aa..101dd84 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/Preference.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/Preference.kt @@ -1,8 +1,18 @@ +/* + * Copyright (c) 2025 Nishant Mishra + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package org.nsh07.pomodoro.data import androidx.room.Entity import androidx.room.PrimaryKey +/** + * Class for storing app preferences (settings) in the app's database + */ @Entity(tableName = "int_preference") data class IntPreference( @PrimaryKey diff --git a/app/src/main/java/org/nsh07/pomodoro/data/PreferenceRepository.kt b/app/src/main/java/org/nsh07/pomodoro/data/PreferenceRepository.kt index 05a7791..438af3f 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/PreferenceRepository.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/PreferenceRepository.kt @@ -1,17 +1,42 @@ +/* + * Copyright (c) 2025 Nishant Mishra + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package org.nsh07.pomodoro.data import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +/** + * Interface for reading/writing app preferences to the app's database. This style of storage aims + * to mimic the Preferences DataStore library, preventing the requirement of migration if the + * database schema changes. + */ interface PreferenceRepository { + /** + * Saves an integer preference key-value pair to the database. + */ suspend fun saveIntPreference(key: String, value: Int): Int + /** + * Retrieves an integer preference key-value pair from the database. + */ suspend fun getIntPreference(key: String): Int? + /** + * Erases all integer preference key-value pairs in the database. Do note that the default values + * will need to be rewritten manually + */ suspend fun resetSettings() } +/** + * See [PreferenceRepository] for more details + */ class AppPreferenceRepository( private val preferenceDao: PreferenceDao, private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO diff --git a/app/src/main/java/org/nsh07/pomodoro/data/Stat.kt b/app/src/main/java/org/nsh07/pomodoro/data/Stat.kt index f2c92f6..80a683f 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/Stat.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/Stat.kt @@ -10,6 +10,11 @@ package org.nsh07.pomodoro.data import androidx.room.Entity import androidx.room.PrimaryKey +/** + * Data class for storing the user's statistics in the app's database. This class stores the focus + * durations for the 4 quarters of a day (00:00 - 12:00, 12:00 - 16:00, 16:00 - 20:00, 20:00 - 00:00) + * separately for later analysis (e.g. for showing which parts of the day are most productive). + */ @Entity(tableName = "stat") data class Stat( @PrimaryKey @@ -20,3 +25,16 @@ data class Stat( val focusTimeQ4: Long, val breakTime: Long ) + +data class StatSummary( + val date: String, + val focusTime: Long, + val breakTime: Long +) + +data class StatFocusTime( + val focusTimeQ1: Long, + val focusTimeQ2: Long, + val focusTimeQ3: Long, + val focusTimeQ4: Long +) \ No newline at end of file diff --git a/app/src/main/java/org/nsh07/pomodoro/data/StatDao.kt b/app/src/main/java/org/nsh07/pomodoro/data/StatDao.kt index 5680a1c..4a71d27 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/StatDao.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/StatDao.kt @@ -36,8 +36,11 @@ interface StatDao { @Query("SELECT * FROM stat WHERE date = :date") fun getStat(date: String): Flow - @Query("SELECT * FROM stat") - fun getStats(): Flow> + @Query("SELECT date, focusTimeQ1 + focusTimeQ2 + focusTimeQ3 + focusTimeQ4 as focusTime, breakTime FROM stat") + fun getAllStatsSummary(): Flow> + + @Query("SELECT AVG(focusTimeQ1), AVG(focusTimeQ2), AVG(focusTimeQ3), AVG(focusTimeQ4) FROM stat") + fun getAvgFocusTimes(): Flow @Query("SELECT EXISTS (SELECT * FROM stat WHERE date = :date)") suspend fun statExists(date: String): Boolean diff --git a/app/src/main/java/org/nsh07/pomodoro/data/StatRepository.kt b/app/src/main/java/org/nsh07/pomodoro/data/StatRepository.kt index 08c3b32..8b7dc98 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/StatRepository.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/StatRepository.kt @@ -14,6 +14,11 @@ import kotlinx.coroutines.withContext import java.time.LocalDate import java.time.LocalTime +/** + * Interface for reading/writing statistics to the app's database. Ideally, writing should be done + * through the timer screen's ViewModel and reading should be done through the stats screen's + * ViewModel + */ interface StatRepository { suspend fun addFocusTime(focusTime: Long) @@ -21,9 +26,14 @@ interface StatRepository { fun getTodayStat(): Flow - fun getAllStats(): Flow> + fun getAllStatsSummary(): Flow> + + fun getAverageFocusTimes(): Flow } +/** + * See [StatRepository] for more details + */ class AppStatRepository( private val statDao: StatDao, private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO @@ -85,5 +95,7 @@ class AppStatRepository( return statDao.getStat(currentDate) } - override fun getAllStats(): Flow> = statDao.getStats() + override fun getAllStatsSummary(): Flow> = statDao.getAllStatsSummary() + + override fun getAverageFocusTimes(): Flow = statDao.getAvgFocusTimes() } \ No newline at end of file diff --git a/app/src/main/java/org/nsh07/pomodoro/data/TimerRepository.kt b/app/src/main/java/org/nsh07/pomodoro/data/TimerRepository.kt index d4d1ad3..0283a17 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/TimerRepository.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/TimerRepository.kt @@ -7,6 +7,10 @@ package org.nsh07.pomodoro.data +/** + * Interface that holds the timer durations for each timer type. This repository maintains a single + * source of truth for the timer durations for the various ViewModels in the app. + */ interface TimerRepository { var focusTime: Long var shortBreakTime: Long @@ -14,6 +18,9 @@ interface TimerRepository { var sessionLength: Int } +/** + * See [TimerRepository] for more details + */ class AppTimerRepository : TimerRepository { override var focusTime = 25 * 60 * 1000L override var shortBreakTime = 5 * 60 * 1000L