diff --git a/app/src/main/java/org/nsh07/pomodoro/data/AppContainer.kt b/app/src/main/java/org/nsh07/pomodoro/data/AppContainer.kt index c8039cf..9f2849b 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/AppContainer.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/AppContainer.kt @@ -1,22 +1,30 @@ +/* + * 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 android.content.Context interface AppContainer { val appPreferencesRepository: AppPreferenceRepository + val appStatRepository: AppStatRepository val appTimerRepository: AppTimerRepository } class DefaultAppContainer(context: Context) : AppContainer { override val appPreferencesRepository: AppPreferenceRepository by lazy { - AppPreferenceRepository( - AppDatabase.getDatabase(context).preferenceDao() - ) + AppPreferenceRepository(AppDatabase.getDatabase(context).preferenceDao()) } - override val appTimerRepository: AppTimerRepository by lazy { - AppTimerRepository() + override val appStatRepository: AppStatRepository by lazy { + AppStatRepository(AppDatabase.getDatabase(context).statDao()) } + override val appTimerRepository: AppTimerRepository by lazy { AppTimerRepository() } + } \ No newline at end of file diff --git a/app/src/main/java/org/nsh07/pomodoro/data/AppDatabase.kt b/app/src/main/java/org/nsh07/pomodoro/data/AppDatabase.kt index 96b8130..ea86a1f 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/AppDatabase.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/AppDatabase.kt @@ -1,3 +1,10 @@ +/* + * 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 android.content.Context @@ -6,12 +13,13 @@ import androidx.room.Room import androidx.room.RoomDatabase @Database( - entities = [IntPreference::class], + entities = [IntPreference::class, Stat::class], version = 1 ) abstract class AppDatabase : RoomDatabase() { abstract fun preferenceDao(): PreferenceDao + abstract fun statDao(): StatDao companion object { diff --git a/app/src/main/java/org/nsh07/pomodoro/data/PreferenceDao.kt b/app/src/main/java/org/nsh07/pomodoro/data/PreferenceDao.kt index 490c0db..b450b4c 100644 --- a/app/src/main/java/org/nsh07/pomodoro/data/PreferenceDao.kt +++ b/app/src/main/java/org/nsh07/pomodoro/data/PreferenceDao.kt @@ -1,13 +1,20 @@ +/* + * 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.Dao import androidx.room.Insert -import androidx.room.OnConflictStrategy +import androidx.room.OnConflictStrategy.Companion.REPLACE import androidx.room.Query @Dao interface PreferenceDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) + @Insert(onConflict = REPLACE) suspend fun insertIntPreference(preference: IntPreference) @Query("DELETE FROM int_preference") diff --git a/app/src/main/java/org/nsh07/pomodoro/data/Stat.kt b/app/src/main/java/org/nsh07/pomodoro/data/Stat.kt new file mode 100644 index 0000000..f4125f0 --- /dev/null +++ b/app/src/main/java/org/nsh07/pomodoro/data/Stat.kt @@ -0,0 +1,19 @@ +/* + * 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 + +@Entity(tableName = "stat") +data class Stat( + @PrimaryKey + val date: String, + val focusTime: Int, + val breakTime: Int +) diff --git a/app/src/main/java/org/nsh07/pomodoro/data/StatDao.kt b/app/src/main/java/org/nsh07/pomodoro/data/StatDao.kt new file mode 100644 index 0000000..1448a3a --- /dev/null +++ b/app/src/main/java/org/nsh07/pomodoro/data/StatDao.kt @@ -0,0 +1,35 @@ +/* + * 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.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy.Companion.REPLACE +import androidx.room.Query +import kotlinx.coroutines.flow.Flow + +@Dao +interface StatDao { + @Insert(onConflict = REPLACE) + suspend fun insertStat(stat: Stat) + + @Query("UPDATE stat SET focusTime = focusTime + :focusTime WHERE date = :date") + suspend fun addFocusTime(date: String, focusTime: Int) + + @Query("UPDATE stat SET breakTime = breakTime + :breakTime WHERE date = :date") + suspend fun addBreakTime(date: String, breakTime: Int) + + @Query("SELECT * FROM stat WHERE date = :date") + fun getStat(date: String): Flow + + @Query("SELECT * FROM stat") + fun getStats(): Flow> + + @Query("SELECT EXISTS (SELECT * FROM stat WHERE date = :date)") + suspend fun statExists(date: String): Boolean +} \ No newline at end of file diff --git a/app/src/main/java/org/nsh07/pomodoro/data/StatRepository.kt b/app/src/main/java/org/nsh07/pomodoro/data/StatRepository.kt new file mode 100644 index 0000000..8f615ff --- /dev/null +++ b/app/src/main/java/org/nsh07/pomodoro/data/StatRepository.kt @@ -0,0 +1,54 @@ +/* + * 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.flow.Flow +import kotlinx.coroutines.withContext +import java.time.LocalDate + +interface StatRepository { + suspend fun addFocusTime(focusTime: Int) + + suspend fun addBreakTime(breakTime: Int) + + fun getTodayStat(): Flow + + fun getAllStats(): Flow> +} + +class AppStatRepository( + private val statDao: StatDao, + private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO +) : StatRepository { + override suspend fun addFocusTime(focusTime: Int) = withContext(ioDispatcher) { + val currentDate = LocalDate.now().toString() + if (statDao.statExists(currentDate)) { + statDao.addFocusTime(currentDate, focusTime) + } else { + statDao.insertStat(Stat(currentDate, focusTime, 0)) + } + } + + override suspend fun addBreakTime(breakTime: Int) = withContext(ioDispatcher) { + val currentDate = LocalDate.now().toString() + if (statDao.statExists(currentDate)) { + statDao.addBreakTime(currentDate, breakTime) + } else { + statDao.insertStat(Stat(currentDate, 0, breakTime)) + } + } + + override fun getTodayStat(): Flow { + val currentDate = LocalDate.now().toString() + return statDao.getStat(currentDate) + } + + override fun getAllStats(): Flow> = statDao.getStats() +} \ No newline at end of file