From b6fd00d43e7652590d3ada1bd6901cf87b54e2b9 Mon Sep 17 00:00:00 2001 From: brandy-kay Date: Mon, 7 Aug 2023 14:16:27 +0300 Subject: [PATCH 01/10] setting up work manager --- .../brandyodhiambo/quench/ui/MainActivity.kt | 6 + feature/statistics/build.gradle.kts | 1 + .../presentation/StatisticsViewModel.kt | 111 ++++++++++++++- .../statistics/worker/WorkerRequest.kt | 134 ++++++++++++++++++ .../worker/daily_worker/DailyWorker.kt | 44 ++++++ .../worker/monthly_worker/MonthlyWorker.kt | 47 ++++++ .../worker/weekly_worker/WeeklyWorker.kt | 47 ++++++ shared_dependencies.gradle | 13 +- 8 files changed, 390 insertions(+), 13 deletions(-) create mode 100644 feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt create mode 100644 feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt create mode 100644 feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt create mode 100644 feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt diff --git a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt index ea790b6..6036b4d 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt @@ -21,6 +21,9 @@ import com.brandyodhiambo.quench.navigation.FeatureNavigator import com.brandyodhiambo.quench.navigation.NavGraphs import com.brandyodhiambo.quench.util.AlarmSchedularImpl import com.brandyodhiambo.quench.util.createChannel +import com.brandyodhiambo.statistics.worker.startDailyOnetimeWorkRequest +import com.brandyodhiambo.statistics.worker.startMonthlyPeriodicWorkRequest +import com.brandyodhiambo.statistics.worker.startWeeklyOnetimeWorkRequest import com.google.accompanist.navigation.animation.rememberAnimatedNavController import com.ramcosta.composedestinations.DestinationsNavHost import com.ramcosta.composedestinations.navigation.dependency @@ -45,6 +48,9 @@ class MainActivity : ComponentActivity() { modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background, ) { + startDailyOnetimeWorkRequest(applicationContext) + startWeeklyOnetimeWorkRequest(applicationContext) + startMonthlyPeriodicWorkRequest(applicationContext) val reminderTimeFromDb = viewModel.reminderTime.observeAsState() val hours = reminderTimeFromDb.value?.hour ?: 0 val minutes = reminderTimeFromDb.value?.minute ?: 0 diff --git a/feature/statistics/build.gradle.kts b/feature/statistics/build.gradle.kts index 9b4f753..f982a80 100644 --- a/feature/statistics/build.gradle.kts +++ b/feature/statistics/build.gradle.kts @@ -54,6 +54,7 @@ dependencies { // RamCosta Navigation implementation("io.github.raamcosta.compose-destinations:core:1.5.20-beta") + implementation("androidx.work:work-runtime-ktx:2.8.1") ksp("io.github.raamcosta.compose-destinations:ksp:1.5.15-beta") // Navigation animation diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt index e26f62b..09ee07b 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt @@ -1,15 +1,124 @@ package com.brandyodhiambo.statistics.presentation import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.brandyodhiambo.common.domain.model.DailyStatistics +import com.brandyodhiambo.common.domain.model.MonthlyStatistics +import com.brandyodhiambo.common.domain.model.WeeklyStatistics import com.brandyodhiambo.common.domain.repository.DailyStatisticsRepository +import com.brandyodhiambo.common.domain.repository.GoalWaterIntakeRepository +import com.brandyodhiambo.common.domain.repository.IdealWaterIntakeRepository +import com.brandyodhiambo.common.domain.repository.LevelRepository import com.brandyodhiambo.common.domain.repository.MonthlyStatisticsRepository +import com.brandyodhiambo.common.domain.repository.ReminderTimeRepository +import com.brandyodhiambo.common.domain.repository.SelectedDrinkRepository import com.brandyodhiambo.common.domain.repository.WeeklyStatisticRepository +import com.brandyodhiambo.common.util.isEndOfDay import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import java.time.LocalDateTime import javax.inject.Inject @HiltViewModel class StatisticsViewModel @Inject constructor( + private val levelRepository: LevelRepository, + private val goalWaterIntakeRepository: GoalWaterIntakeRepository, + private val idealWaterIntakeRepository: IdealWaterIntakeRepository, + private val selectedDrinkRepository: SelectedDrinkRepository, + private val reminderTimeRepository: ReminderTimeRepository, private val dailyStatisticsRepository: DailyStatisticsRepository, private val weeklyStatisticsRepository: WeeklyStatisticRepository, private val monthlyStatisticsRepository: MonthlyStatisticsRepository, -) : ViewModel() +) : ViewModel() { + + val levelFromDB = levelRepository.getLevel() + + /*Daily Statistics*/ + val dailyStatisticsFromDB = dailyStatisticsRepository.getDailyStatistics() + fun insertDailyStatistic(dailyStatistics: DailyStatistics) { + viewModelScope.launch { + dailyStatisticsRepository.insertDailyStatistics(dailyStatistics) + } + } + + fun deleteAllDailyStatistics() { + viewModelScope.launch { + dailyStatisticsRepository.deleteAllDailyStatistics() + } + } + + fun deleteOneDailyStatistics(dailyStatistics: DailyStatistics) { + viewModelScope.launch { + dailyStatisticsRepository.deleteDailyStatistics(dailyStatistics) + } + } + + fun updateDailyStatistic(dailyStatistics: DailyStatistics) { + viewModelScope.launch { + dailyStatisticsRepository.updateDailyStatistics(dailyStatistics) + } + } + + fun emptyDBFromDailyData() { + viewModelScope.launch { + levelRepository.deleteAllLevel() + goalWaterIntakeRepository.deleteAllGoalWaterIntakes() + idealWaterIntakeRepository.deleteAllIdealWaterIntakes() + selectedDrinkRepository.deleteAllSelectedDrinks() + reminderTimeRepository.dellAllReminderTimes() + } + } + + /*Weekly Statistics*/ + val weeklyStatisticsFromDB = weeklyStatisticsRepository.getWeeklyStatistic() + fun insertWeeklyStatistic(weeklyStatistics: WeeklyStatistics) { + viewModelScope.launch { + weeklyStatisticsRepository.insertWeeklyStatistic(weeklyStatistics) + } + } + + fun deleteAllWeeklyStatistics() { + viewModelScope.launch { + weeklyStatisticsRepository.deleteAllWeeklyStatistic() + } + } + + fun deleteOneWeeklyStatistics(weeklyStatistics: WeeklyStatistics) { + viewModelScope.launch { + weeklyStatisticsRepository.deleteWeeklyStatistic(weeklyStatistics) + } + } + + fun updateWeeklyStatistic(weeklyStatistics: WeeklyStatistics) { + viewModelScope.launch { + weeklyStatisticsRepository.updateWeeklyStatistic(weeklyStatistics) + } + } + + /*Monthly Statistics*/ + val monthlyStatisticsFromDB = monthlyStatisticsRepository.getMonthlyStatistics() + + fun insertMonthlyStatistic(monthlyStatistics: MonthlyStatistics) { + viewModelScope.launch { + monthlyStatisticsRepository.insertMonthlyStatistics(monthlyStatistics) + } + } + + fun deleteAllMonthlyStatistics() { + viewModelScope.launch { + monthlyStatisticsRepository.deleteAllMonthlyStatistics() + } + } + + fun deleteOneMonthlyStatistics(monthlyStatistics: MonthlyStatistics) { + viewModelScope.launch { + monthlyStatisticsRepository.deleteMonthlyStatistics(monthlyStatistics) + } + } + + fun updateMonthlyStatistic(monthlyStatistics: MonthlyStatistics) { + viewModelScope.launch { + monthlyStatisticsRepository.updateMonthlyStatistics(monthlyStatistics) + } + } +} diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt new file mode 100644 index 0000000..b69ac01 --- /dev/null +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt @@ -0,0 +1,134 @@ +package com.brandyodhiambo.statistics.worker + +import android.content.Context +import androidx.work.BackoffPolicy +import androidx.work.Constraints +import androidx.work.ExistingPeriodicWorkPolicy +import androidx.work.NetworkType +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.PeriodicWorkRequest +import androidx.work.PeriodicWorkRequestBuilder +import androidx.work.WorkManager +import com.brandyodhiambo.statistics.worker.daily_worker.DailyWorker +import com.brandyodhiambo.statistics.worker.daily_worker.DailyWorker.Companion.DAILY_WORK_NAME +import com.brandyodhiambo.statistics.worker.monthly_worker.MonthlyWorker +import com.brandyodhiambo.statistics.worker.monthly_worker.MonthlyWorker.Companion.MONTHLY_WORK_NAME +import com.brandyodhiambo.statistics.worker.weekly_worker.WeeklyWorker +import com.brandyodhiambo.statistics.worker.weekly_worker.WeeklyWorker.Companion.WEEKLY_WORK_NAME +import java.util.concurrent.TimeUnit + +fun startDailyOnetimeWorkRequest(context: Context) { + val constraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.NOT_REQUIRED) + .build() + + val dailyWorkRequest = OneTimeWorkRequestBuilder() + .setConstraints(constraints) + .build() + + WorkManager.getInstance(context).enqueue(dailyWorkRequest) +} + +fun startDailyPeriodicWorkRequest(context: Context) { + val constraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.NOT_REQUIRED) + .setRequiresBatteryNotLow(true) + .setRequiresCharging(true) + .build() + + val workRequest = PeriodicWorkRequestBuilder( + 1, + TimeUnit.DAYS, + ) + .setConstraints(constraints) + .setBackoffCriteria( + BackoffPolicy.LINEAR, + PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, + TimeUnit.MILLISECONDS, + ) + .build() + + WorkManager.getInstance(context).enqueueUniquePeriodicWork( + DAILY_WORK_NAME, + ExistingPeriodicWorkPolicy.REPLACE, + workRequest, + ) +} + +// weekly requests +fun startWeeklyOnetimeWorkRequest(context: Context) { + val constraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.NOT_REQUIRED) + .build() + + val weeklyWorkRequest = OneTimeWorkRequestBuilder() + .setConstraints(constraints) + .build() + + WorkManager.getInstance(context).enqueue(weeklyWorkRequest) +} + +fun startWeeklyPeriodicWorkRequest(context: Context) { + val constraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.NOT_REQUIRED) + .setRequiresBatteryNotLow(true) + .setRequiresCharging(true) + .build() + + val workRequest = PeriodicWorkRequestBuilder( + 1, + TimeUnit.DAYS, + ) + .setConstraints(constraints) + .setBackoffCriteria( + BackoffPolicy.LINEAR, + PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, + TimeUnit.MILLISECONDS, + ) + .build() + + WorkManager.getInstance(context).enqueueUniquePeriodicWork( + WEEKLY_WORK_NAME, + ExistingPeriodicWorkPolicy.REPLACE, + workRequest, + ) +} + +// monthly requests +fun startMonthlyOnetimeWorkRequest(context: Context) { + val constraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.NOT_REQUIRED) + .build() + + val monthlyWorkRequest = OneTimeWorkRequestBuilder() + .setConstraints(constraints) + .build() + + WorkManager.getInstance(context).enqueue(monthlyWorkRequest) +} + +fun startMonthlyPeriodicWorkRequest(context: Context) { + val constraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.NOT_REQUIRED) + .setRequiresBatteryNotLow(true) + .setRequiresCharging(true) + .build() + + val workRequest = PeriodicWorkRequestBuilder( + 1, + TimeUnit.DAYS, + ) + .setConstraints(constraints) + .setBackoffCriteria( + BackoffPolicy.LINEAR, + PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, + TimeUnit.MILLISECONDS, + ) + .build() + + WorkManager.getInstance(context).enqueueUniquePeriodicWork( + MONTHLY_WORK_NAME, + ExistingPeriodicWorkPolicy.REPLACE, + workRequest, + ) +} diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt new file mode 100644 index 0000000..1bed490 --- /dev/null +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt @@ -0,0 +1,44 @@ +package com.brandyodhiambo.statistics.worker.daily_worker + +import android.content.Context +import androidx.hilt.work.HiltWorker +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import com.brandyodhiambo.common.domain.model.DailyStatistics +import com.brandyodhiambo.common.util.getCurrentDay +import com.brandyodhiambo.common.util.isEndOfDay +import com.brandyodhiambo.statistics.presentation.StatisticsViewModel +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import java.time.LocalDateTime + +@HiltWorker +class DailyWorker @AssistedInject constructor( + @Assisted context: Context, + @Assisted params: WorkerParameters, + private val statisticsViewModel: StatisticsViewModel, +) : CoroutineWorker(context, params) { + + private val amountTaken = statisticsViewModel.levelFromDB.value?.amountTaken + companion object { + const val DAILY_WORK_NAME = "com.brandyodhiambo.common.worker.daily_worker.DailyWorker" + private const val TAG = "DailyWorker" + } + + override suspend fun doWork(): Result { + return try { + if (isEndOfDay(dateTime = LocalDateTime.now())) { + statisticsViewModel.insertDailyStatistic( + DailyStatistics( + amountTaken = amountTaken ?: 0f, + day = getCurrentDay(), + ), + ) + statisticsViewModel.emptyDBFromDailyData() + } + Result.success() + } catch (e: Exception) { + Result.failure() + } + } +} diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt new file mode 100644 index 0000000..16bfbc8 --- /dev/null +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt @@ -0,0 +1,47 @@ +package com.brandyodhiambo.statistics.worker.monthly_worker + +import android.content.Context +import androidx.hilt.work.HiltWorker +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import com.brandyodhiambo.common.domain.model.MonthlyStatistics +import com.brandyodhiambo.common.util.getCurrentMonth +import com.brandyodhiambo.common.util.isEndOfMonth +import com.brandyodhiambo.statistics.presentation.StatisticsViewModel +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import java.time.LocalDate + +@HiltWorker +class MonthlyWorker @AssistedInject constructor( + @Assisted context: Context, + @Assisted params: WorkerParameters, + private val statisticsViewModel: StatisticsViewModel, +) : CoroutineWorker(context, params) { + + private val amountTaken = + statisticsViewModel.weeklyStatisticsFromDB.value?.sumByDouble { it.amountTaken.toDouble() } + private val totalAmountTaken = amountTaken?.div(4) // 4 weeks in a month + + companion object { + const val MONTHLY_WORK_NAME = "com.brandyodhiambo.common.worker.monthly_worker.MonthlyWorker" + private const val TAG = "MonthlyWorker" + } + + override suspend fun doWork(): Result { + return try { + if (isEndOfMonth(LocalDate.now())) { + statisticsViewModel.insertMonthlyStatistic( + MonthlyStatistics( + amountTaken = totalAmountTaken?.toFloat() ?: 0f, + month = getCurrentMonth(), + ), + ) + } + + Result.success() + } catch (e: Exception) { + Result.failure() + } + } +} diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt new file mode 100644 index 0000000..7855e50 --- /dev/null +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt @@ -0,0 +1,47 @@ +package com.brandyodhiambo.statistics.worker.weekly_worker + +import android.content.Context +import androidx.hilt.work.HiltWorker +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import com.brandyodhiambo.common.domain.model.WeeklyStatistics +import com.brandyodhiambo.common.util.getCurrentWeekNumber +import com.brandyodhiambo.common.util.isEndOfWeek +import com.brandyodhiambo.statistics.presentation.StatisticsViewModel +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import java.time.LocalDate + +@HiltWorker +class WeeklyWorker @AssistedInject constructor( + @Assisted context: Context, + @Assisted params: WorkerParameters, + private val statisticsViewModel: StatisticsViewModel, +) : CoroutineWorker(context, params) { + + private val amountTaken = + statisticsViewModel.dailyStatisticsFromDB.value?.sumByDouble { it.amountTaken.toDouble() } + + private val totalAmountTaken = amountTaken?.div(7) // 7 days in a week + + companion object { + const val WEEKLY_WORK_NAME = "com.brandyodhiambo.common.worker.weekly_worker.WeeklyWorker" + private const val TAG = "WeeklyWorker" + } + + override suspend fun doWork(): Result { + return try { + if (isEndOfWeek(LocalDate.now())) { + statisticsViewModel.insertWeeklyStatistic( + WeeklyStatistics( + amountTaken = totalAmountTaken?.toFloat() ?: 0f, + week = getCurrentWeekNumber().toString(), + ), + ) + } + Result.success() + } catch (e: Exception) { + Result.failure() + } + } +} diff --git a/shared_dependencies.gradle b/shared_dependencies.gradle index 9fa1147..ac89afd 100644 --- a/shared_dependencies.gradle +++ b/shared_dependencies.gradle @@ -15,16 +15,7 @@ dependencies { debugImplementation("androidx.compose.ui:ui-tooling:${Versions.compose_version}") debugImplementation("androidx.compose.ui:ui-test-manifest:${Versions.compose_version}") - - - // Room - implementation("androidx.room:room-runtime:${Versions.room_version}") - kapt("androidx.room:room-compiler:${Versions.room_version}") - - // Kotlin Extensions and Coroutines support for Room - implementation("androidx.room:room-ktx:${Versions.room_version}") - - + // Compose dependencies implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1") implementation("androidx.navigation:navigation-compose:2.6.0-alpha04") @@ -74,7 +65,5 @@ dependencies { implementation ("com.squareup.retrofit2:converter-gson:2.9.0") - implementation('androidx.work:work-runtime:2.7.1') - } \ No newline at end of file From e98ef57adda213949588c6867c28c0ee732493db Mon Sep 17 00:00:00 2001 From: brandy-kay Date: Tue, 8 Aug 2023 12:15:19 +0300 Subject: [PATCH 02/10] working on daily statistics --- app/src/main/AndroidManifest.xml | 11 +++++++++ .../com/brandyodhiambo/quench/QuenchApp.kt | 15 ++++++++++-- .../brandyodhiambo/common/util/Function.kt | 18 ++++++++++++++ .../presentation/StatisticsViewModel.kt | 12 ++++------ .../worker/daily_worker/DailyWorker.kt | 24 ++++++++++++++----- .../worker/monthly_worker/MonthlyWorker.kt | 9 ++++--- .../worker/weekly_worker/WeeklyWorker.kt | 9 ++++--- 7 files changed, 77 insertions(+), 21 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d844ac2..970e448 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -31,6 +31,17 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/com/brandyodhiambo/quench/QuenchApp.kt b/app/src/main/java/com/brandyodhiambo/quench/QuenchApp.kt index 3e15140..0d49ac8 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/QuenchApp.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/QuenchApp.kt @@ -1,13 +1,24 @@ package com.brandyodhiambo.quench import android.app.Application +import androidx.hilt.work.HiltWorkerFactory +import androidx.work.Configuration import dagger.hilt.android.HiltAndroidApp import timber.log.Timber +import javax.inject.Inject @HiltAndroidApp -class QuenchApp: Application() { +class QuenchApp : Application(), Configuration.Provider { override fun onCreate() { super.onCreate() Timber.plant(Timber.DebugTree()) } -} \ No newline at end of file + + @Inject + lateinit var workerFactory: HiltWorkerFactory + override fun getWorkManagerConfiguration(): Configuration { + return Configuration.Builder() + .setWorkerFactory(workerFactory) + .build() + } +} diff --git a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt index e462092..85893c9 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt @@ -1,6 +1,9 @@ package com.brandyodhiambo.common.util import android.annotation.SuppressLint +import androidx.lifecycle.LiveData +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.suspendCancellableCoroutine import java.text.SimpleDateFormat import java.time.DayOfWeek import java.time.LocalDate @@ -10,6 +13,7 @@ import java.time.format.TextStyle import java.time.temporal.TemporalAdjusters import java.time.temporal.WeekFields import java.util.* +import kotlin.coroutines.resume @SuppressLint("SimpleDateFormat") fun formatDate(timestamp: Long): String { @@ -68,6 +72,20 @@ fun getCurrentYear(): String { return now.year.toString() } +suspend fun LiveData.awaitValue(): T? = suspendCancellableCoroutine { cont -> + val observer = object : androidx.lifecycle.Observer { + override fun onChanged(value: T) { + removeObserver(this) + cont.resume(value) + } + } + observeForever(observer) + + cont.invokeOnCancellation { + removeObserver(observer) + } +} + diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt index 09ee07b..fca3ccb 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt @@ -13,10 +13,8 @@ import com.brandyodhiambo.common.domain.repository.MonthlyStatisticsRepository import com.brandyodhiambo.common.domain.repository.ReminderTimeRepository import com.brandyodhiambo.common.domain.repository.SelectedDrinkRepository import com.brandyodhiambo.common.domain.repository.WeeklyStatisticRepository -import com.brandyodhiambo.common.util.isEndOfDay import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch -import java.time.LocalDateTime import javax.inject.Inject @HiltViewModel @@ -61,11 +59,11 @@ class StatisticsViewModel @Inject constructor( fun emptyDBFromDailyData() { viewModelScope.launch { - levelRepository.deleteAllLevel() - goalWaterIntakeRepository.deleteAllGoalWaterIntakes() - idealWaterIntakeRepository.deleteAllIdealWaterIntakes() - selectedDrinkRepository.deleteAllSelectedDrinks() - reminderTimeRepository.dellAllReminderTimes() + levelRepository.deleteAllLevel() + goalWaterIntakeRepository.deleteAllGoalWaterIntakes() + idealWaterIntakeRepository.deleteAllIdealWaterIntakes() + selectedDrinkRepository.deleteAllSelectedDrinks() + reminderTimeRepository.dellAllReminderTimes() } } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt index 1bed490..fca3599 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt @@ -5,9 +5,15 @@ import androidx.hilt.work.HiltWorker import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import com.brandyodhiambo.common.domain.model.DailyStatistics +import com.brandyodhiambo.common.domain.repository.DailyStatisticsRepository +import com.brandyodhiambo.common.domain.repository.GoalWaterIntakeRepository +import com.brandyodhiambo.common.domain.repository.IdealWaterIntakeRepository +import com.brandyodhiambo.common.domain.repository.LevelRepository +import com.brandyodhiambo.common.domain.repository.ReminderTimeRepository +import com.brandyodhiambo.common.domain.repository.SelectedDrinkRepository +import com.brandyodhiambo.common.util.awaitValue import com.brandyodhiambo.common.util.getCurrentDay import com.brandyodhiambo.common.util.isEndOfDay -import com.brandyodhiambo.statistics.presentation.StatisticsViewModel import dagger.assisted.Assisted import dagger.assisted.AssistedInject import java.time.LocalDateTime @@ -16,10 +22,14 @@ import java.time.LocalDateTime class DailyWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, - private val statisticsViewModel: StatisticsViewModel, + private val levelRepository: LevelRepository, + private val goalWaterIntakeRepository: GoalWaterIntakeRepository, + private val idealWaterIntakeRepository: IdealWaterIntakeRepository, + private val selectedDrinkRepository: SelectedDrinkRepository, + private val reminderTimeRepository: ReminderTimeRepository, + private val dailyStatisticsRepository: DailyStatisticsRepository, ) : CoroutineWorker(context, params) { - private val amountTaken = statisticsViewModel.levelFromDB.value?.amountTaken companion object { const val DAILY_WORK_NAME = "com.brandyodhiambo.common.worker.daily_worker.DailyWorker" private const val TAG = "DailyWorker" @@ -27,14 +37,16 @@ class DailyWorker @AssistedInject constructor( override suspend fun doWork(): Result { return try { + val amountTaken = levelRepository.getLevel().awaitValue()?.amountTaken ?: 1f + if (isEndOfDay(dateTime = LocalDateTime.now())) { - statisticsViewModel.insertDailyStatistic( + dailyStatisticsRepository.insertDailyStatistics( DailyStatistics( - amountTaken = amountTaken ?: 0f, + amountTaken = amountTaken, day = getCurrentDay(), ), ) - statisticsViewModel.emptyDBFromDailyData() + // statisticsViewModel.emptyDBFromDailyData() } Result.success() } catch (e: Exception) { diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt index 16bfbc8..7e6fa74 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt @@ -5,6 +5,8 @@ import androidx.hilt.work.HiltWorker import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import com.brandyodhiambo.common.domain.model.MonthlyStatistics +import com.brandyodhiambo.common.domain.repository.MonthlyStatisticsRepository +import com.brandyodhiambo.common.domain.repository.WeeklyStatisticRepository import com.brandyodhiambo.common.util.getCurrentMonth import com.brandyodhiambo.common.util.isEndOfMonth import com.brandyodhiambo.statistics.presentation.StatisticsViewModel @@ -16,11 +18,12 @@ import java.time.LocalDate class MonthlyWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, - private val statisticsViewModel: StatisticsViewModel, + private val weeklyStatisticRepository: WeeklyStatisticRepository, + private val monthlyStatisticsRepository: MonthlyStatisticsRepository ) : CoroutineWorker(context, params) { private val amountTaken = - statisticsViewModel.weeklyStatisticsFromDB.value?.sumByDouble { it.amountTaken.toDouble() } + weeklyStatisticRepository.getWeeklyStatistic().value?.sumByDouble { it.amountTaken.toDouble() } private val totalAmountTaken = amountTaken?.div(4) // 4 weeks in a month companion object { @@ -31,7 +34,7 @@ class MonthlyWorker @AssistedInject constructor( override suspend fun doWork(): Result { return try { if (isEndOfMonth(LocalDate.now())) { - statisticsViewModel.insertMonthlyStatistic( + monthlyStatisticsRepository.insertMonthlyStatistics( MonthlyStatistics( amountTaken = totalAmountTaken?.toFloat() ?: 0f, month = getCurrentMonth(), diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt index 7855e50..5fb66fb 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt @@ -5,6 +5,8 @@ import androidx.hilt.work.HiltWorker import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import com.brandyodhiambo.common.domain.model.WeeklyStatistics +import com.brandyodhiambo.common.domain.repository.DailyStatisticsRepository +import com.brandyodhiambo.common.domain.repository.WeeklyStatisticRepository import com.brandyodhiambo.common.util.getCurrentWeekNumber import com.brandyodhiambo.common.util.isEndOfWeek import com.brandyodhiambo.statistics.presentation.StatisticsViewModel @@ -16,11 +18,12 @@ import java.time.LocalDate class WeeklyWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, - private val statisticsViewModel: StatisticsViewModel, + private val dailyStatisticsRepository: DailyStatisticsRepository, + private val weeklyStatisticRepository: WeeklyStatisticRepository ) : CoroutineWorker(context, params) { private val amountTaken = - statisticsViewModel.dailyStatisticsFromDB.value?.sumByDouble { it.amountTaken.toDouble() } + dailyStatisticsRepository.getDailyStatistics().value?.sumByDouble { it.amountTaken.toDouble() } private val totalAmountTaken = amountTaken?.div(7) // 7 days in a week @@ -32,7 +35,7 @@ class WeeklyWorker @AssistedInject constructor( override suspend fun doWork(): Result { return try { if (isEndOfWeek(LocalDate.now())) { - statisticsViewModel.insertWeeklyStatistic( + weeklyStatisticRepository.insertWeeklyStatistic( WeeklyStatistics( amountTaken = totalAmountTaken?.toFloat() ?: 0f, week = getCurrentWeekNumber().toString(), From a222049e336e490e4631b70403d177a8458a81e0 Mon Sep 17 00:00:00 2001 From: brandy-kay Date: Thu, 10 Aug 2023 17:08:46 +0300 Subject: [PATCH 03/10] works on weekly achievement --- .../brandyodhiambo/quench/ui/MainActivity.kt | 5 +- .../common/domain/model/Achievement.kt | 6 + .../repository/AchievementRepository.kt | 17 ++ .../brandyodhiambo/common/util/Function.kt | 32 ++- .../main/java/com/brandyodhiambo/Constants.kt | 1 + .../com/brandyodhiambo/dao/AchievementDao.kt | 26 +++ .../brandyodhiambo/database/QuenchDatabase.kt | 7 +- .../entity/AchievementEntity.kt | 13 ++ feature/statistics/build.gradle.kts | 1 + .../statistics/data/mapper/Mapper.kt | 16 ++ .../repository/AchievementRepositoryImpl.kt | 35 ++++ .../presentation/StatisticsScreen.kt | 192 +++++++++++------- .../presentation/StatisticsViewModel.kt | 102 ---------- .../worker/daily_worker/DailyWorker.kt | 6 +- .../worker/monthly_worker/MonthlyWorker.kt | 12 +- .../worker/weekly_worker/WeeklyWorker.kt | 13 +- 16 files changed, 282 insertions(+), 202 deletions(-) create mode 100644 core/common/src/main/java/com/brandyodhiambo/common/domain/model/Achievement.kt create mode 100644 core/common/src/main/java/com/brandyodhiambo/common/domain/repository/AchievementRepository.kt create mode 100644 core/database/src/main/java/com/brandyodhiambo/dao/AchievementDao.kt create mode 100644 core/database/src/main/java/com/brandyodhiambo/entity/AchievementEntity.kt create mode 100644 feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/AchievementRepositoryImpl.kt diff --git a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt index 6036b4d..4077fd1 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt @@ -22,7 +22,7 @@ import com.brandyodhiambo.quench.navigation.NavGraphs import com.brandyodhiambo.quench.util.AlarmSchedularImpl import com.brandyodhiambo.quench.util.createChannel import com.brandyodhiambo.statistics.worker.startDailyOnetimeWorkRequest -import com.brandyodhiambo.statistics.worker.startMonthlyPeriodicWorkRequest +import com.brandyodhiambo.statistics.worker.startMonthlyOnetimeWorkRequest import com.brandyodhiambo.statistics.worker.startWeeklyOnetimeWorkRequest import com.google.accompanist.navigation.animation.rememberAnimatedNavController import com.ramcosta.composedestinations.DestinationsNavHost @@ -50,7 +50,8 @@ class MainActivity : ComponentActivity() { ) { startDailyOnetimeWorkRequest(applicationContext) startWeeklyOnetimeWorkRequest(applicationContext) - startMonthlyPeriodicWorkRequest(applicationContext) + startMonthlyOnetimeWorkRequest(applicationContext) + val reminderTimeFromDb = viewModel.reminderTime.observeAsState() val hours = reminderTimeFromDb.value?.hour ?: 0 val minutes = reminderTimeFromDb.value?.minute ?: 0 diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Achievement.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Achievement.kt new file mode 100644 index 0000000..fe05594 --- /dev/null +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Achievement.kt @@ -0,0 +1,6 @@ +package com.brandyodhiambo.common.domain.model + +data class Achievement( + val isAchieved: Boolean, + val day: String, +) \ No newline at end of file diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/AchievementRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/AchievementRepository.kt new file mode 100644 index 0000000..28914fe --- /dev/null +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/AchievementRepository.kt @@ -0,0 +1,17 @@ +package com.brandyodhiambo.common.domain.repository + +import androidx.lifecycle.LiveData +import com.brandyodhiambo.common.domain.model.Achievement + +interface AchievementRepository { + + suspend fun insertAchievement(achievement: Achievement) + + suspend fun updateAchievement(achievement: Achievement) + + suspend fun deleteAchievement(achievement: Achievement) + + suspend fun deleteAllAchievement() + + fun getAchievement(): LiveData?> +} diff --git a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt index 85893c9..e320472 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt @@ -2,8 +2,12 @@ package com.brandyodhiambo.common.util import android.annotation.SuppressLint import androidx.lifecycle.LiveData +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.first import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.coroutines.withContext import java.text.SimpleDateFormat import java.time.DayOfWeek import java.time.LocalDate @@ -71,18 +75,26 @@ fun getCurrentYear(): String { val now = LocalDateTime.now() return now.year.toString() } - -suspend fun LiveData.awaitValue(): T? = suspendCancellableCoroutine { cont -> - val observer = object : androidx.lifecycle.Observer { - override fun onChanged(value: T) { - removeObserver(this) - cont.resume(value) - } +suspend fun LiveData.awaitValue(): T = withContext(Dispatchers.Default) { + val flow = MutableSharedFlow(replay = 1) + val observer = androidx.lifecycle.Observer { + it?.let { value -> flow.tryEmit(value) } } - observeForever(observer) - cont.invokeOnCancellation { - removeObserver(observer) + withContext(Dispatchers.Main) { + observeForever(observer) + } + try { + flow.first { value -> + withContext(Dispatchers.Main) { + removeObserver(observer) + } + true + } + } finally { + withContext(Dispatchers.Main) { + removeObserver(observer) + } } } diff --git a/core/database/src/main/java/com/brandyodhiambo/Constants.kt b/core/database/src/main/java/com/brandyodhiambo/Constants.kt index 61015e1..fb8543a 100644 --- a/core/database/src/main/java/com/brandyodhiambo/Constants.kt +++ b/core/database/src/main/java/com/brandyodhiambo/Constants.kt @@ -15,6 +15,7 @@ object Constants { const val DAILY_STATISTICS_TABLE = "daily_statistics_table" const val MONTHLY_STATISTICS_TABLE = "monthly_statistics_table" const val WEEKLY_STATISTICS_TABLE = "weekly_statistics_table" + const val ACHIEVEMENT_TABLE = "achievement_table" const val DATABASE_NAME = "water_reminder_db" } diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/AchievementDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/AchievementDao.kt new file mode 100644 index 0000000..7d69faf --- /dev/null +++ b/core/database/src/main/java/com/brandyodhiambo/dao/AchievementDao.kt @@ -0,0 +1,26 @@ +package com.brandyodhiambo.dao + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import com.brandyodhiambo.entity.AchievementEntity + +@Dao +interface AchievementDao { + + @Insert + suspend fun insertAchievement(achievementEntity: AchievementEntity) + + @Query("SELECT *FROM achievement_table") + fun getAchievement(): LiveData?> + + @Query("DELETE FROM achievement_table") + suspend fun deleteAllAchievement() + + @Query("UPDATE achievement_table SET isAchieved = :isAchieved,day = :day WHERE id = :id") + suspend fun updateAchievement(id: Int, isAchieved: Boolean, day: String) + + @Query("DELETE FROM achievement_table WHERE id = :id") + suspend fun deleteAchievement(id: Int) +} diff --git a/core/database/src/main/java/com/brandyodhiambo/database/QuenchDatabase.kt b/core/database/src/main/java/com/brandyodhiambo/database/QuenchDatabase.kt index e94adc5..9eb47bb 100644 --- a/core/database/src/main/java/com/brandyodhiambo/database/QuenchDatabase.kt +++ b/core/database/src/main/java/com/brandyodhiambo/database/QuenchDatabase.kt @@ -4,6 +4,7 @@ import androidx.room.Database import androidx.room.RoomDatabase import androidx.room.TypeConverters import com.brandyodhiambo.converter.Converter +import com.brandyodhiambo.dao.AchievementDao import com.brandyodhiambo.dao.DailyStatisticsDao import com.brandyodhiambo.dao.GoalWaterIntakeDao import com.brandyodhiambo.dao.IdealWaterIntakeDao @@ -14,6 +15,7 @@ import com.brandyodhiambo.dao.SelectedDrinkDao import com.brandyodhiambo.dao.SleepTimeDao import com.brandyodhiambo.dao.WakeTimeDao import com.brandyodhiambo.dao.WeeklyStatisticDao +import com.brandyodhiambo.entity.AchievementEntity import com.brandyodhiambo.entity.DailyStatisticsEntity import com.brandyodhiambo.entity.GoalWaterIntakeEntity import com.brandyodhiambo.entity.IdealWaterIntakeEntity @@ -27,8 +29,8 @@ import com.brandyodhiambo.entity.WeeklyStatisticsEntity @TypeConverters(Converter::class) @Database( - entities = [SelectedDrinkEntity::class, WakeTimeEntity::class, IdealWaterIntakeEntity::class, GoalWaterIntakeEntity::class, SleepTimeEntity::class, LevelEntity::class, ReminderTimeEntity::class, DailyStatisticsEntity::class, WeeklyStatisticsEntity::class, MonthlyStatisticsEntity::class], - version = 4, + entities = [SelectedDrinkEntity::class, WakeTimeEntity::class, IdealWaterIntakeEntity::class, GoalWaterIntakeEntity::class, SleepTimeEntity::class, LevelEntity::class, ReminderTimeEntity::class, DailyStatisticsEntity::class, WeeklyStatisticsEntity::class, MonthlyStatisticsEntity::class, AchievementEntity::class], + version = 5, exportSchema = false, ) abstract class QuenchDatabase : RoomDatabase() { @@ -42,4 +44,5 @@ abstract class QuenchDatabase : RoomDatabase() { abstract fun dailyStatisticsDao(): DailyStatisticsDao abstract fun weeklyStatisticsDao(): WeeklyStatisticDao abstract fun monthlyStatisticsDao(): MonthlyStatisticsDao + abstract fun achievementDao(): AchievementDao } diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/AchievementEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/AchievementEntity.kt new file mode 100644 index 0000000..3cc0230 --- /dev/null +++ b/core/database/src/main/java/com/brandyodhiambo/entity/AchievementEntity.kt @@ -0,0 +1,13 @@ +package com.brandyodhiambo.entity + +import androidx.room.Entity +import androidx.room.PrimaryKey +import com.brandyodhiambo.Constants.ACHIEVEMENT_TABLE + +@Entity(tableName = ACHIEVEMENT_TABLE) +data class AchievementEntity( + @PrimaryKey(autoGenerate = true) + val id: Int = 0, + val isAchieved: Boolean, + val day: String, +) \ No newline at end of file diff --git a/feature/statistics/build.gradle.kts b/feature/statistics/build.gradle.kts index f982a80..c751149 100644 --- a/feature/statistics/build.gradle.kts +++ b/feature/statistics/build.gradle.kts @@ -55,6 +55,7 @@ dependencies { // RamCosta Navigation implementation("io.github.raamcosta.compose-destinations:core:1.5.20-beta") implementation("androidx.work:work-runtime-ktx:2.8.1") + implementation(project(mapOf("path" to ":feature:home"))) ksp("io.github.raamcosta.compose-destinations:ksp:1.5.15-beta") // Navigation animation diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt index 819adad..aebd9fe 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt @@ -1,8 +1,10 @@ package com.brandyodhiambo.statistics.data.mapper +import com.brandyodhiambo.common.domain.model.Achievement import com.brandyodhiambo.common.domain.model.DailyStatistics import com.brandyodhiambo.common.domain.model.MonthlyStatistics import com.brandyodhiambo.common.domain.model.WeeklyStatistics +import com.brandyodhiambo.entity.AchievementEntity import com.brandyodhiambo.entity.DailyStatisticsEntity import com.brandyodhiambo.entity.MonthlyStatisticsEntity import com.brandyodhiambo.entity.WeeklyStatisticsEntity @@ -48,3 +50,17 @@ internal fun MonthlyStatistics.toMonthlyStatisticsEntity(): MonthlyStatisticsEnt month = month, ) } + +internal fun AchievementEntity.toAchievement(): Achievement { + return Achievement( + isAchieved = isAchieved, + day = day, + ) +} + +internal fun Achievement.toAchievementsEntity(): AchievementEntity { + return AchievementEntity( + isAchieved = isAchieved, + day = day + ) +} diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/AchievementRepositoryImpl.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/AchievementRepositoryImpl.kt new file mode 100644 index 0000000..3b1cec2 --- /dev/null +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/AchievementRepositoryImpl.kt @@ -0,0 +1,35 @@ +package com.brandyodhiambo.statistics.data.repository + +import androidx.lifecycle.LiveData +import androidx.lifecycle.Transformations +import com.brandyodhiambo.common.domain.model.Achievement +import com.brandyodhiambo.common.domain.repository.AchievementRepository +import com.brandyodhiambo.dao.AchievementDao +import com.brandyodhiambo.statistics.data.mapper.toAchievement +import com.brandyodhiambo.statistics.data.mapper.toAchievementsEntity + +class AchievementRepositoryImpl( + private val achievementDao: AchievementDao, +) : AchievementRepository { + override suspend fun insertAchievement(achievement: Achievement) { + achievementDao.insertAchievement(achievement.toAchievementsEntity()) + } + + override suspend fun updateAchievement(achievement: Achievement) { + TODO("Not yet implemented") + } + + override suspend fun deleteAchievement(achievement: Achievement) { + achievementDao.deleteAchievement(id = achievement.toAchievementsEntity().id) + } + + override suspend fun deleteAllAchievement() { + achievementDao.deleteAllAchievement() + } + + override fun getAchievement(): LiveData?> { + return Transformations.map(achievementDao.getAchievement()) { achievementEntity -> + achievementEntity?.map { it.toAchievement() } + } + } +} diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt index beb5843..b011ea7 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.material.icons.filled.AccountCircle import androidx.compose.material.icons.filled.DateRange import androidx.compose.material.icons.filled.Star import androidx.compose.runtime.Composable +import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment @@ -27,9 +28,12 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel import com.brandyodhiambo.common.R +import com.brandyodhiambo.common.domain.model.Achievement import com.brandyodhiambo.designsystem.theme.blackColor import com.brandyodhiambo.designsystem.theme.primaryColor +import com.brandyodhiambo.home.presentation.home_screen.HomeViewModel import com.mahmoud.composecharts.barchart.BarChart import com.mahmoud.composecharts.barchart.BarChartEntity import com.ramcosta.composedestinations.annotation.Destination @@ -40,45 +44,57 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator @Composable fun StatisticsScreen( navigator: DestinationsNavigator, + statisticsViewModel: StatisticsViewModel = hiltViewModel(), + homeViewModel: HomeViewModel = hiltViewModel(), ) { - val barChartDataMonth = listOf( - BarChartEntity(30f, primaryColor, "Week 1"), - BarChartEntity(20f, primaryColor, "Week 2"), - BarChartEntity(100f, primaryColor, "Week 3"), - BarChartEntity(70f, primaryColor, "Week 4"), - ) + val dailyStatistics = statisticsViewModel.dailyStatisticsFromDB.observeAsState() + val weeklyStatistics = statisticsViewModel.weeklyStatisticsFromDB.observeAsState() + val monthlyStatistics = statisticsViewModel.monthlyStatisticsFromDB.observeAsState() + val idealWaterIntake = homeViewModel.idealWaterIntakeFromDb.observeAsState() + val goalWaterIntake = homeViewModel.goalWaterIntakeFromDb.observeAsState() - val barChartDataWeek = listOf( - BarChartEntity(30f, primaryColor, "Sun"), - BarChartEntity(20f, primaryColor, "Mon"), - BarChartEntity(100f, primaryColor, "Tus"), - BarChartEntity(70f, primaryColor, "Wed"), - BarChartEntity(90f, primaryColor, "Thirs"), - BarChartEntity(60f, primaryColor, "Fri"), - BarChartEntity(80f, primaryColor, "Sat"), - ) + val barChartDataDaily: List = dailyStatistics.value?.map { dailyStat -> + BarChartEntity(dailyStat.amountTaken, primaryColor, dailyStat.day.take(3)) + } ?: emptyList() - val barChartDataYear = listOf( - BarChartEntity(30f, primaryColor, "Jan"), - BarChartEntity(50f, primaryColor, "Feb"), - BarChartEntity(20f, primaryColor, "Mar"), - BarChartEntity(80f, primaryColor, "Apr"), - BarChartEntity(20f, primaryColor, "May"), - BarChartEntity(90f, primaryColor, "Jun"), - BarChartEntity(05f, primaryColor, "Jul"), - BarChartEntity(100f, primaryColor, "Aug"), - BarChartEntity(40f, primaryColor, "Sep"), - BarChartEntity(70f, primaryColor, "Oct"), - BarChartEntity(70f, primaryColor, "Nov"), - BarChartEntity(70f, primaryColor, "Dec"), - ) + val barChartDataWeek: List = weeklyStatistics.value?.map { weekStat -> + BarChartEntity(weekStat.amountTaken, primaryColor, weekStat.week) + } ?: emptyList() + + val barChartDataMonth: List = monthlyStatistics.value?.map { monthStat -> + BarChartEntity(monthStat.amountTaken, primaryColor, monthStat.month.take(3)) + } ?: emptyList() val verticalAxisValues = listOf(0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f) val setGraphDaily = remember { mutableStateOf(true) } val setGraphMonthly = remember { mutableStateOf(false) } - val setGraphYearly = remember { mutableStateOf(false) } + val setGraphWeek = remember { mutableStateOf(false) } + + val weeklyAverage = weeklyStatistics.value?.map { it.amountTaken }?.average() ?: 0.0 + val monthlyAverage = monthlyStatistics.value?.map { it.amountTaken }?.average() ?: 0.0 + val dailyAverage = dailyStatistics.value?.map { it.amountTaken }?.average() ?: 0.0 + + val drinkFrequency = goalWaterIntake.value?.waterIntake?.div(idealWaterIntake.value?.waterIntake ?: 1) ?: 0 + + val average = if (setGraphDaily.value) { + dailyAverage + } else if (setGraphWeek.value) { + weeklyAverage + } else { + monthlyAverage + } + + val weekAchiement = listOf( + Achievement(isAchieved = true, "Sun"), + Achievement(isAchieved = true, "Mon"), + Achievement(isAchieved = false, "Tue"), + Achievement(isAchieved = false, "Wed"), + Achievement(isAchieved = true, "Thu"), + Achievement(isAchieved = false, "Fri"), + Achievement(isAchieved = false, "Sat"), + ) Scaffold( backgroundColor = primaryColor, @@ -120,8 +136,8 @@ fun StatisticsScreen( shape = RoundedCornerShape(8.dp), ).clickable { setGraphDaily.value = true + setGraphWeek.value = false setGraphMonthly.value = false - setGraphYearly.value = false }, contentAlignment = Alignment.Center, ) { @@ -137,7 +153,7 @@ fun StatisticsScreen( .height(30.dp) .width(100.dp) .background( - color = if (setGraphMonthly.value) { + color = if (setGraphWeek.value) { primaryColor } else { primaryColor.copy( @@ -147,8 +163,8 @@ fun StatisticsScreen( shape = RoundedCornerShape(8.dp), ).clickable { setGraphDaily.value = false - setGraphMonthly.value = true - setGraphYearly.value = false + setGraphWeek.value = true + setGraphMonthly.value = false }, contentAlignment = Alignment.Center, ) { @@ -164,7 +180,7 @@ fun StatisticsScreen( .height(30.dp) .width(100.dp) .background( - color = if (setGraphYearly.value) { + color = if (setGraphMonthly.value) { primaryColor } else { primaryColor.copy( @@ -174,8 +190,8 @@ fun StatisticsScreen( shape = RoundedCornerShape(8.dp), ).clickable { setGraphDaily.value = false - setGraphMonthly.value = false - setGraphYearly.value = true + setGraphWeek.value = false + setGraphMonthly.value = true }, contentAlignment = Alignment.Center, ) { @@ -190,25 +206,25 @@ fun StatisticsScreen( if (setGraphDaily.value) { BarChart( modifier = Modifier.fillMaxSize().padding(16.dp), - barChartData = barChartDataWeek, + barChartData = barChartDataDaily, verticalAxisValues = verticalAxisValues, isShowHorizontalLines = true, isShowVerticalAxis = true, ) } - if (setGraphMonthly.value) { + if (setGraphWeek.value) { BarChart( modifier = Modifier.fillMaxSize().padding(16.dp), - barChartData = barChartDataMonth, + barChartData = barChartDataWeek, verticalAxisValues = verticalAxisValues, isShowHorizontalLines = true, isShowVerticalAxis = true, ) } - if (setGraphYearly.value) { + if (setGraphMonthly.value) { BarChart( modifier = Modifier.fillMaxSize().padding(16.dp), - barChartData = barChartDataYear, + barChartData = barChartDataMonth, verticalAxisValues = verticalAxisValues, isShowHorizontalLines = true, isShowVerticalAxis = true, @@ -218,28 +234,26 @@ fun StatisticsScreen( } } item { - Last7DayGoals() + Last7DayGoals( + weekAchivement = weekAchiement, + ) } item { - DrinkWaterReport() + DrinkWaterReport( + currentDailyAverage = dailyAverage.toInt(), + currentWeeklyAverage = weeklyAverage.toInt(), + currentMonthlyAverage = monthlyAverage.toInt(), + currentAverage = average.toInt(), + currentDrinkFrequency = drinkFrequency, + ) } } } } } -val weekAchiement = listOf( - Weeks(isAcheived = true, "Sun"), - Weeks(isAcheived = true, "Mon"), - Weeks(isAcheived = false, "Tue"), - Weeks(isAcheived = false, "Wed"), - Weeks(isAcheived = true, "Thu"), - Weeks(isAcheived = false, "Fri"), - Weeks(isAcheived = false, "Sat"), -) - @Composable -fun Last7DayGoals() { +fun Last7DayGoals(weekAchivement: List) { Card( modifier = Modifier .height(135.dp) @@ -260,7 +274,7 @@ fun Last7DayGoals() { verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceEvenly, ) { - items(weekAchiement) { weeks -> + items(weekAchivement.takeLast(7)) { weeks -> WeeksAcheive(weeks = weeks) } } @@ -270,12 +284,12 @@ fun Last7DayGoals() { @Composable fun WeeksAcheive( - weeks: Weeks, + weeks: Achievement, ) { Column( horizontalAlignment = Alignment.CenterHorizontally, ) { - if (weeks.isAcheived == true) { + if (weeks.isAchieved) { GoldCup() } else { BlackCup() @@ -327,7 +341,13 @@ fun BlackCup() { } @Composable -fun DrinkWaterReport() { +fun DrinkWaterReport( + currentDailyAverage: Int, + currentWeeklyAverage: Int, + currentMonthlyAverage: Int, + currentDrinkFrequency: Int, + currentAverage: Int, +) { Card( modifier = Modifier .fillMaxWidth() @@ -360,14 +380,49 @@ fun DrinkWaterReport() { ) Spacer(modifier = Modifier.width(8.dp)) Text( - text = "Week Avarage", + text = "Daily Average", + fontSize = 16.sp, + fontWeight = FontWeight.W400, + color = blackColor, + ) + } + Text( + text = "$currentDailyAverage ml/day", + fontSize = 16.sp, + fontWeight = FontWeight.W400, + color = primaryColor, + ) + } + Divider( + modifier = Modifier.height(1.dp).padding(start = 8.dp, end = 8.dp), + color = Color.Gray, + thickness = 1.dp, + ) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = Icons.Default.DateRange, + tint = primaryColor, + contentDescription = null, + ) + Spacer(modifier = Modifier.width(8.dp)) + Text( + text = "Weekly Average", fontSize = 16.sp, fontWeight = FontWeight.W400, color = blackColor, ) } Text( - text = "1850ml/day", + text = "$currentWeeklyAverage ml/day", fontSize = 16.sp, fontWeight = FontWeight.W400, color = primaryColor, @@ -395,14 +450,14 @@ fun DrinkWaterReport() { ) Spacer(modifier = Modifier.width(8.dp)) Text( - text = "Monthly Avarage", + text = "Monthly Average", fontSize = 16.sp, fontWeight = FontWeight.W400, color = blackColor, ) } Text( - text = "1450ml/day", + text = "$currentMonthlyAverage ml/day", fontSize = 16.sp, fontWeight = FontWeight.W400, color = primaryColor, @@ -430,14 +485,14 @@ fun DrinkWaterReport() { ) Spacer(modifier = Modifier.width(8.dp)) Text( - text = "Avarage Completion", + text = "Average Completion", fontSize = 16.sp, fontWeight = FontWeight.W400, color = blackColor, ) } Text( - text = "55%", + text = "$currentAverage%", fontSize = 16.sp, fontWeight = FontWeight.W400, color = primaryColor, @@ -472,7 +527,7 @@ fun DrinkWaterReport() { ) } Text( - text = "5 Times/day", + text = "$currentDrinkFrequency Times/day", fontSize = 16.sp, fontWeight = FontWeight.W400, color = primaryColor, @@ -481,8 +536,3 @@ fun DrinkWaterReport() { } } } - -data class Weeks( - val isAcheived: Boolean, - val day: String, -) diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt index fca3ccb..4499040 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt @@ -1,122 +1,20 @@ package com.brandyodhiambo.statistics.presentation import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.brandyodhiambo.common.domain.model.DailyStatistics -import com.brandyodhiambo.common.domain.model.MonthlyStatistics -import com.brandyodhiambo.common.domain.model.WeeklyStatistics import com.brandyodhiambo.common.domain.repository.DailyStatisticsRepository -import com.brandyodhiambo.common.domain.repository.GoalWaterIntakeRepository -import com.brandyodhiambo.common.domain.repository.IdealWaterIntakeRepository -import com.brandyodhiambo.common.domain.repository.LevelRepository import com.brandyodhiambo.common.domain.repository.MonthlyStatisticsRepository -import com.brandyodhiambo.common.domain.repository.ReminderTimeRepository -import com.brandyodhiambo.common.domain.repository.SelectedDrinkRepository import com.brandyodhiambo.common.domain.repository.WeeklyStatisticRepository import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class StatisticsViewModel @Inject constructor( - private val levelRepository: LevelRepository, - private val goalWaterIntakeRepository: GoalWaterIntakeRepository, - private val idealWaterIntakeRepository: IdealWaterIntakeRepository, - private val selectedDrinkRepository: SelectedDrinkRepository, - private val reminderTimeRepository: ReminderTimeRepository, private val dailyStatisticsRepository: DailyStatisticsRepository, private val weeklyStatisticsRepository: WeeklyStatisticRepository, private val monthlyStatisticsRepository: MonthlyStatisticsRepository, ) : ViewModel() { - val levelFromDB = levelRepository.getLevel() - - /*Daily Statistics*/ val dailyStatisticsFromDB = dailyStatisticsRepository.getDailyStatistics() - fun insertDailyStatistic(dailyStatistics: DailyStatistics) { - viewModelScope.launch { - dailyStatisticsRepository.insertDailyStatistics(dailyStatistics) - } - } - - fun deleteAllDailyStatistics() { - viewModelScope.launch { - dailyStatisticsRepository.deleteAllDailyStatistics() - } - } - - fun deleteOneDailyStatistics(dailyStatistics: DailyStatistics) { - viewModelScope.launch { - dailyStatisticsRepository.deleteDailyStatistics(dailyStatistics) - } - } - - fun updateDailyStatistic(dailyStatistics: DailyStatistics) { - viewModelScope.launch { - dailyStatisticsRepository.updateDailyStatistics(dailyStatistics) - } - } - - fun emptyDBFromDailyData() { - viewModelScope.launch { - levelRepository.deleteAllLevel() - goalWaterIntakeRepository.deleteAllGoalWaterIntakes() - idealWaterIntakeRepository.deleteAllIdealWaterIntakes() - selectedDrinkRepository.deleteAllSelectedDrinks() - reminderTimeRepository.dellAllReminderTimes() - } - } - - /*Weekly Statistics*/ val weeklyStatisticsFromDB = weeklyStatisticsRepository.getWeeklyStatistic() - fun insertWeeklyStatistic(weeklyStatistics: WeeklyStatistics) { - viewModelScope.launch { - weeklyStatisticsRepository.insertWeeklyStatistic(weeklyStatistics) - } - } - - fun deleteAllWeeklyStatistics() { - viewModelScope.launch { - weeklyStatisticsRepository.deleteAllWeeklyStatistic() - } - } - - fun deleteOneWeeklyStatistics(weeklyStatistics: WeeklyStatistics) { - viewModelScope.launch { - weeklyStatisticsRepository.deleteWeeklyStatistic(weeklyStatistics) - } - } - - fun updateWeeklyStatistic(weeklyStatistics: WeeklyStatistics) { - viewModelScope.launch { - weeklyStatisticsRepository.updateWeeklyStatistic(weeklyStatistics) - } - } - - /*Monthly Statistics*/ val monthlyStatisticsFromDB = monthlyStatisticsRepository.getMonthlyStatistics() - - fun insertMonthlyStatistic(monthlyStatistics: MonthlyStatistics) { - viewModelScope.launch { - monthlyStatisticsRepository.insertMonthlyStatistics(monthlyStatistics) - } - } - - fun deleteAllMonthlyStatistics() { - viewModelScope.launch { - monthlyStatisticsRepository.deleteAllMonthlyStatistics() - } - } - - fun deleteOneMonthlyStatistics(monthlyStatistics: MonthlyStatistics) { - viewModelScope.launch { - monthlyStatisticsRepository.deleteMonthlyStatistics(monthlyStatistics) - } - } - - fun updateMonthlyStatistic(monthlyStatistics: MonthlyStatistics) { - viewModelScope.launch { - monthlyStatisticsRepository.updateMonthlyStatistics(monthlyStatistics) - } - } } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt index fca3599..cbca373 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt @@ -46,7 +46,11 @@ class DailyWorker @AssistedInject constructor( day = getCurrentDay(), ), ) - // statisticsViewModel.emptyDBFromDailyData() + goalWaterIntakeRepository.deleteAllGoalWaterIntakes() + idealWaterIntakeRepository.deleteAllIdealWaterIntakes() + selectedDrinkRepository.deleteAllSelectedDrinks() + reminderTimeRepository.dellAllReminderTimes() + levelRepository.deleteAllLevel() } Result.success() } catch (e: Exception) { diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt index 7e6fa74..91fb8ef 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt @@ -7,9 +7,9 @@ import androidx.work.WorkerParameters import com.brandyodhiambo.common.domain.model.MonthlyStatistics import com.brandyodhiambo.common.domain.repository.MonthlyStatisticsRepository import com.brandyodhiambo.common.domain.repository.WeeklyStatisticRepository +import com.brandyodhiambo.common.util.awaitValue import com.brandyodhiambo.common.util.getCurrentMonth import com.brandyodhiambo.common.util.isEndOfMonth -import com.brandyodhiambo.statistics.presentation.StatisticsViewModel import dagger.assisted.Assisted import dagger.assisted.AssistedInject import java.time.LocalDate @@ -19,13 +19,9 @@ class MonthlyWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, private val weeklyStatisticRepository: WeeklyStatisticRepository, - private val monthlyStatisticsRepository: MonthlyStatisticsRepository + private val monthlyStatisticsRepository: MonthlyStatisticsRepository, ) : CoroutineWorker(context, params) { - private val amountTaken = - weeklyStatisticRepository.getWeeklyStatistic().value?.sumByDouble { it.amountTaken.toDouble() } - private val totalAmountTaken = amountTaken?.div(4) // 4 weeks in a month - companion object { const val MONTHLY_WORK_NAME = "com.brandyodhiambo.common.worker.monthly_worker.MonthlyWorker" private const val TAG = "MonthlyWorker" @@ -33,6 +29,10 @@ class MonthlyWorker @AssistedInject constructor( override suspend fun doWork(): Result { return try { + val amountTaken = + weeklyStatisticRepository.getWeeklyStatistic().awaitValue()?.sumByDouble { it.amountTaken.toDouble() } + val totalAmountTaken = amountTaken?.div(4) // 4 weeks in a month + if (isEndOfMonth(LocalDate.now())) { monthlyStatisticsRepository.insertMonthlyStatistics( MonthlyStatistics( diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt index 5fb66fb..7c7cca8 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt @@ -7,9 +7,9 @@ import androidx.work.WorkerParameters import com.brandyodhiambo.common.domain.model.WeeklyStatistics import com.brandyodhiambo.common.domain.repository.DailyStatisticsRepository import com.brandyodhiambo.common.domain.repository.WeeklyStatisticRepository +import com.brandyodhiambo.common.util.awaitValue import com.brandyodhiambo.common.util.getCurrentWeekNumber import com.brandyodhiambo.common.util.isEndOfWeek -import com.brandyodhiambo.statistics.presentation.StatisticsViewModel import dagger.assisted.Assisted import dagger.assisted.AssistedInject import java.time.LocalDate @@ -19,14 +19,8 @@ class WeeklyWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, private val dailyStatisticsRepository: DailyStatisticsRepository, - private val weeklyStatisticRepository: WeeklyStatisticRepository + private val weeklyStatisticRepository: WeeklyStatisticRepository, ) : CoroutineWorker(context, params) { - - private val amountTaken = - dailyStatisticsRepository.getDailyStatistics().value?.sumByDouble { it.amountTaken.toDouble() } - - private val totalAmountTaken = amountTaken?.div(7) // 7 days in a week - companion object { const val WEEKLY_WORK_NAME = "com.brandyodhiambo.common.worker.weekly_worker.WeeklyWorker" private const val TAG = "WeeklyWorker" @@ -34,6 +28,9 @@ class WeeklyWorker @AssistedInject constructor( override suspend fun doWork(): Result { return try { + val amountTaken = dailyStatisticsRepository.getDailyStatistics().awaitValue()?.sumByDouble { it.amountTaken.toDouble() } + val totalAmountTaken = amountTaken?.div(7) // 7 days in a week + if (isEndOfWeek(LocalDate.now())) { weeklyStatisticRepository.insertWeeklyStatistic( WeeklyStatistics( From b1efc247b22bcf65fddab3f276225361eea64d43 Mon Sep 17 00:00:00 2001 From: brandy-kay Date: Sat, 19 Aug 2023 21:23:44 +0300 Subject: [PATCH 04/10] works on weekly achievement --- app/build.gradle.kts | 2 +- .../quench/ExampleInstrumentedTest.kt | 23 ++- .../res/values/ic_launcher_background.xml | 2 +- app/src/main/AndroidManifest.xml | 2 +- .../com/brandyodhiambo/quench/QuenchApp.kt | 15 ++ .../brandyodhiambo/quench/models/TabItem.kt | 17 +- .../quench/navigation/FeatureNavigator.kt | 23 ++- .../quench/navigation/NavGraphs.kt | 21 ++- .../brandyodhiambo/quench/ui/MainActivity.kt | 19 +- .../brandyodhiambo/quench/ui/MainScreen.kt | 41 +++-- .../quench/ui/splash/SplashScreen.kt | 21 ++- .../quench/util/AlarmReceiver.kt | 19 +- .../quench/util/AlarmSchedular.kt | 17 +- .../quench/util/AlarmSchedularImpl.kt | 25 ++- .../quench/util/NotificationUtil.kt | 21 ++- app/src/main/res/values/colors.xml | 2 +- .../res/values/ic_launcher_background.xml | 2 +- app/src/main/res/values/splash.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- app/src/main/res/values/themes.xml | 2 +- app/src/main/res/xml/backup_rules.xml | 2 +- .../main/res/xml/data_extraction_rules.xml | 2 +- .../brandyodhiambo/quench/ExampleUnitTest.kt | 20 ++- build.gradle.kts | 24 ++- .../common/ExampleInstrumentedTest.kt | 23 ++- core/common/src/main/AndroidManifest.xml | 2 +- .../common/domain/model/Achievement.kt | 19 +- .../common/domain/model/AlarmData.kt | 17 +- .../common/domain/model/DailyStatistics.kt | 17 +- .../brandyodhiambo/common/domain/model/Day.kt | 19 +- .../common/domain/model/Days.kt | 19 +- .../common/domain/model/GoalWaterIntake.kt | 15 ++ .../common/domain/model/IdealWaterIntake.kt | 17 +- .../common/domain/model/Level.kt | 17 +- .../common/domain/model/MonthlyStatistics.kt | 17 +- .../common/domain/model/ReminderTime.kt | 17 +- .../common/domain/model/SelectedDrink.kt | 17 +- .../common/domain/model/SleepTime.kt | 17 +- .../common/domain/model/WakeTime.kt | 17 +- .../common/domain/model/WeeklyStatistics.kt | 17 +- .../repository/AchievementRepository.kt | 15 ++ .../repository/DailyStatisticsRepository.kt | 15 ++ .../repository/GoalWaterIntakeRepository.kt | 17 +- .../repository/IdealWaterIntakeRepository.kt | 17 +- .../domain/repository/LevelRepository.kt | 15 ++ .../repository/MonthlyStatisticsRepository.kt | 15 ++ .../repository/ReminderTimeRepository.kt | 15 ++ .../repository/SelectedDrinkRepository.kt | 17 +- .../domain/repository/SleepTimeRepository.kt | 17 +- .../domain/repository/WakeTimeRepository.kt | 17 +- .../repository/WeeklyStatisticRepository.kt | 15 ++ .../component/WaterIntakeGoalDialog.kt | 48 ++++- .../brandyodhiambo/common/util/Function.kt | 39 ++-- .../res/drawable/ic_launcher_foreground.xml | 2 +- core/common/src/main/res/drawable/test.xml | 2 +- .../brandyodhiambo/common/ExampleUnitTest.kt | 20 ++- core/database/build.gradle.kts | 2 +- .../database/ExampleInstrumentedTest.kt | 23 ++- core/database/src/main/AndroidManifest.xml | 2 +- .../main/java/com/brandyodhiambo/Constants.kt | 15 ++ .../com/brandyodhiambo/converter/Converter.kt | 30 +++- .../com/brandyodhiambo/dao/AchievementDao.kt | 15 ++ .../brandyodhiambo/dao/DailyStatisticsDao.kt | 15 ++ .../brandyodhiambo/dao/GoalWaterIntakeDao.kt | 22 ++- .../brandyodhiambo/dao/IdealWaterIntakeDao.kt | 19 +- .../java/com/brandyodhiambo/dao/LevelDao.kt | 15 ++ .../dao/MonthlyStatisticsDao.kt | 15 ++ .../com/brandyodhiambo/dao/ReminderTimeDao.kt | 19 +- .../brandyodhiambo/dao/SelectedDrinkDao.kt | 19 +- .../com/brandyodhiambo/dao/SleepTimeDao.kt | 19 +- .../com/brandyodhiambo/dao/WakeTimeDao.kt | 19 +- .../brandyodhiambo/dao/WeeklyStatisticDao.kt | 15 ++ .../brandyodhiambo/database/QuenchDatabase.kt | 17 +- .../com/brandyodhiambo/di/DatabaseModule.kt | 19 +- .../entity/AchievementEntity.kt | 19 +- .../entity/DailyStatisticsEntity.kt | 17 +- .../entity/GoalWaterIntakeEntity.kt | 15 ++ .../entity/IdealWaterIntakeEntity.kt | 17 +- .../com/brandyodhiambo/entity/LevelEntity.kt | 17 +- .../entity/MonthlyStatisticsEntity.kt | 17 +- .../entity/ReminderTimeEntity.kt | 17 +- .../entity/SelectedDrinkEntity.kt | 15 ++ .../brandyodhiambo/entity/SleepTimeEntity.kt | 15 ++ .../brandyodhiambo/entity/WakeTimeEntity.kt | 15 ++ .../entity/WeeklyStatisticsEntity.kt | 17 +- .../database/ExampleUnitTest.kt | 20 ++- designsystem/build.gradle.kts | 6 +- .../designsystem/ExampleInstrumentedTest.kt | 23 ++- designsystem/src/main/AndroidManifest.xml | 2 +- .../designsystem/components/CircularButton.kt | 17 +- .../components/DialogComponent.kt | 16 +- .../designsystem/components/Loader.kt | 25 ++- .../components/NotificationSwitcher.kt | 34 ++-- .../designsystem/theme/Color.kt | 17 +- .../designsystem/theme/Shape.kt | 17 +- .../designsystem/theme/Theme.kt | 19 +- .../brandyodhiambo/designsystem/theme/Type.kt | 15 ++ .../designsystem/ExampleUnitTest.kt | 20 ++- .../home/ExampleInstrumentedTest.kt | 23 ++- feature/home/src/main/AndroidManifest.xml | 2 +- .../brandyodhiambo/home/data/mapper/Mapper.kt | 43 +++-- .../GoalWaterIntakeRepositoryImpl.kt | 19 +- .../IdealWaterInkateRepositoryImpl.kt | 15 ++ .../data/repository/LevelRepositoryImpl.kt | 19 +- .../repository/ReminderTimeRepositoryImpl.kt | 20 ++- .../repository/SelectedDrinkRepositoryImpl.kt | 25 ++- .../repository/SleepTimeRepositoryImpl.kt | 23 ++- .../data/repository/WakeTimeRepositoryImpl.kt | 19 +- .../com/brandyodhiambo/home/di/HomeModule.kt | 15 ++ .../presentation/component/CircularRating.kt | 33 +++- .../component/CongratulationDialog.kt | 65 ++++--- .../presentation/component/DeleteDialog.kt | 29 ++- .../presentation/component/EmptyDialog.kt | 30 +++- .../component/IdealIntakeGoalDialog.kt | 47 ++++- .../component/SelectDrinkDialog.kt | 75 ++++---- .../component/TimeSetterDialog.kt | 55 +++--- .../presentation/component/WaterProgress.kt | 17 +- .../{home_screen => homeScreen}/HomeScreen.kt | 153 +++++++++------- .../HomeViewModel.kt | 43 +++-- .../SleepAndWakeUpScreen.kt | 59 +++--- .../SleepWakeViewModel.kt | 24 ++- feature/home/src/main/res/font/demo.xml | 2 +- .../brandyodhiambo/home/ExampleUnitTest.kt | 20 ++- .../settings/ExampleInstrumentedTest.kt | 23 ++- feature/settings/src/main/AndroidManifest.xml | 2 +- .../presentation/AddReminderScreen.kt | 46 +++-- .../presentation/NotificationScreen.kt | 43 ++++- .../settings/presentation/SettingsScreen.kt | 125 +++++++------ .../component/CustomCheckingDialog.kt | 26 ++- .../component/CustomReminderDialog.kt | 43 +++-- .../settings/ExampleUnitTest.kt | 20 ++- feature/statistics/build.gradle.kts | 2 +- .../statistics/ExampleInstrumentedTest.kt | 23 ++- .../statistics/src/main/AndroidManifest.xml | 2 +- .../statistics/data/mapper/Mapper.kt | 29 ++- .../repository/AchievementRepositoryImpl.kt | 17 +- .../DailyStatisticsRepositoryImpl.kt | 17 +- .../MonthlyStatisticsRepositoryImpl.kt | 17 +- .../WeeklyStatisticsRepositoryImpl.kt | 17 +- .../statistics/di/StatisticsModule.kt | 15 ++ .../presentation/StatisticsScreen.kt | 170 ++++++++++-------- .../presentation/StatisticsViewModel.kt | 17 +- .../statistics/worker/WorkerRequest.kt | 46 +++-- .../DailyWorker.kt | 24 ++- .../MonthlyWorker.kt | 28 ++- .../WeeklyWorker.kt | 27 ++- .../statistics/ExampleUnitTest.kt | 20 ++- ktlint.gradle | 12 ++ spotless.gradle | 33 ++++ spotless/copyright.java | 15 ++ spotless/copyright.kt | 15 ++ 151 files changed, 2669 insertions(+), 671 deletions(-) rename feature/home/src/main/java/com/brandyodhiambo/home/presentation/{home_screen => homeScreen}/HomeScreen.kt (85%) rename feature/home/src/main/java/com/brandyodhiambo/home/presentation/{home_screen => homeScreen}/HomeViewModel.kt (87%) rename feature/home/src/main/java/com/brandyodhiambo/home/presentation/{sleep_wake_screen => sleepWakeScreen}/SleepAndWakeUpScreen.kt (82%) rename feature/home/src/main/java/com/brandyodhiambo/home/presentation/{sleep_wake_screen => sleepWakeScreen}/SleepWakeViewModel.kt (81%) rename feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/{daily_worker => dailyWorker}/DailyWorker.kt (72%) rename feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/{monthly_worker => monthlyWorker}/MonthlyWorker.kt (60%) rename feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/{weekly_worker => weeklyWorker}/WeeklyWorker.kt (63%) create mode 100644 ktlint.gradle create mode 100644 spotless.gradle create mode 100644 spotless/copyright.java create mode 100644 spotless/copyright.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 30d321d..55f5cef 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -40,7 +40,7 @@ android { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro", + "proguard-rules.pro" ) } } diff --git a/app/src/androidTest/java/com/brandyodhiambo/quench/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/brandyodhiambo/quench/ExampleInstrumentedTest.kt index 1536297..968a560 100644 --- a/app/src/androidTest/java/com/brandyodhiambo/quench/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/com/brandyodhiambo/quench/ExampleInstrumentedTest.kt @@ -1,13 +1,26 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import junit.framework.TestCase.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * @@ -21,4 +34,4 @@ class ExampleInstrumentedTest { val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.brandyodhiambo.quench", appContext.packageName) } -} \ No newline at end of file +} diff --git a/app/src/debug/res/values/ic_launcher_background.xml b/app/src/debug/res/values/ic_launcher_background.xml index 1a25384..d70b681 100644 --- a/app/src/debug/res/values/ic_launcher_background.xml +++ b/app/src/debug/res/values/ic_launcher_background.xml @@ -1,4 +1,4 @@ #1F93F8 - \ No newline at end of file + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 970e448..3c25032 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -44,4 +44,4 @@ - \ No newline at end of file + diff --git a/app/src/main/java/com/brandyodhiambo/quench/QuenchApp.kt b/app/src/main/java/com/brandyodhiambo/quench/QuenchApp.kt index 0d49ac8..cd223c6 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/QuenchApp.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/QuenchApp.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench import android.app.Application diff --git a/app/src/main/java/com/brandyodhiambo/quench/models/TabItem.kt b/app/src/main/java/com/brandyodhiambo/quench/models/TabItem.kt index 6a59f35..6e161e1 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/models/TabItem.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/models/TabItem.kt @@ -1,7 +1,22 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench.models import androidx.compose.runtime.Composable -import com.brandyodhiambo.home.presentation.home_screen.HomeScreen +import com.brandyodhiambo.home.presentation.homeScreen.HomeScreen import com.brandyodhiambo.quench.R import com.brandyodhiambo.settings.presentation.SettingScreen import com.brandyodhiambo.settings.presentation.SettingsNavigator diff --git a/app/src/main/java/com/brandyodhiambo/quench/navigation/FeatureNavigator.kt b/app/src/main/java/com/brandyodhiambo/quench/navigation/FeatureNavigator.kt index 81d208d..884af08 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/navigation/FeatureNavigator.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/navigation/FeatureNavigator.kt @@ -1,8 +1,23 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench.navigation import androidx.navigation.NavController import com.brandyodhiambo.home.presentation.destinations.SleepAndWakeTimeScreenDestination -import com.brandyodhiambo.home.presentation.sleep_wake_screen.SleepAndWakeUpScreenScreenNavigator +import com.brandyodhiambo.home.presentation.sleepWakeScreen.SleepAndWakeUpScreenScreenNavigator import com.brandyodhiambo.quench.ui.splash.SplashScreenNavigator import com.brandyodhiambo.settings.presentation.AddReminderNavigator import com.brandyodhiambo.settings.presentation.NotificationNavigator @@ -14,7 +29,7 @@ import com.ramcosta.composedestinations.spec.NavGraphSpec class FeatureNavigator( private val navController: NavController, - private val navGraph: NavGraphSpec, + private val navGraph: NavGraphSpec ) : SplashScreenNavigator, SleepAndWakeUpScreenScreenNavigator, SettingsNavigator, @@ -22,7 +37,7 @@ class FeatureNavigator( AddReminderNavigator { override fun navigateToNotificationScreen() { navController.navigate( - NavGraphs.settings.route, + NavGraphs.settings.route ) } @@ -40,7 +55,7 @@ class FeatureNavigator( override fun navigateToMainScreen() { navController.navigate( - NavGraphs.home.route, + NavGraphs.home.route ) { popUpTo(NavGraphs.splash.route) { inclusive = true diff --git a/app/src/main/java/com/brandyodhiambo/quench/navigation/NavGraphs.kt b/app/src/main/java/com/brandyodhiambo/quench/navigation/NavGraphs.kt index c24405a..8bc65a5 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/navigation/NavGraphs.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/navigation/NavGraphs.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench.navigation import com.brandyodhiambo.home.presentation.destinations.HomeScreenDestination @@ -18,7 +33,7 @@ object NavGraphs { override val startRoute: Route = SplashScreenDestination routedIn this override val destinationsByRoute = listOf>( SplashScreenDestination, - SleepAndWakeTimeScreenDestination, + SleepAndWakeTimeScreenDestination ).routedIn(this).associateBy { it.route } } val home = object : NavGraphSpec { @@ -26,7 +41,7 @@ object NavGraphs { override val startRoute: Route = MainScreenDestination routedIn this override val destinationsByRoute = listOf>( HomeScreenDestination, - MainScreenDestination, + MainScreenDestination ).routedIn(this).associateBy { it.route } } @@ -36,7 +51,7 @@ object NavGraphs { override val destinationsByRoute = listOf>( SettingScreenDestination, NotificationScreenDestination, - AddReminderScreenDestination, + AddReminderScreenDestination ).routedIn(this).associateBy { it.route } } diff --git a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt index 4077fd1..f0b773c 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench.ui import android.annotation.SuppressLint @@ -15,7 +30,7 @@ import androidx.navigation.NavDestination import androidx.navigation.NavDestination.Companion.hierarchy import com.brandyodhiambo.common.domain.model.AlarmData import com.brandyodhiambo.designsystem.theme.QuenchTheme -import com.brandyodhiambo.home.presentation.home_screen.HomeViewModel +import com.brandyodhiambo.home.presentation.homeScreen.HomeViewModel import com.brandyodhiambo.quench.R import com.brandyodhiambo.quench.navigation.FeatureNavigator import com.brandyodhiambo.quench.navigation.NavGraphs @@ -49,8 +64,8 @@ class MainActivity : ComponentActivity() { color = MaterialTheme.colors.background, ) { startDailyOnetimeWorkRequest(applicationContext) - startWeeklyOnetimeWorkRequest(applicationContext) startMonthlyOnetimeWorkRequest(applicationContext) + startWeeklyOnetimeWorkRequest(applicationContext) val reminderTimeFromDb = viewModel.reminderTime.observeAsState() val hours = reminderTimeFromDb.value?.hour ?: 0 diff --git a/app/src/main/java/com/brandyodhiambo/quench/ui/MainScreen.kt b/app/src/main/java/com/brandyodhiambo/quench/ui/MainScreen.kt index bc14c7a..8c72200 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/ui/MainScreen.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/ui/MainScreen.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench.ui import android.annotation.SuppressLint @@ -41,19 +56,19 @@ import kotlinx.coroutines.launch @Destination fun MainScreen( navigator: DestinationsNavigator, - settingsNavigator: SettingsNavigator, + settingsNavigator: SettingsNavigator ) { Scaffold { val tabs = listOf( TabItem.Home(navigator = navigator), TabItem.Statistic(navigator = navigator), - TabItem.Settings(navigator = settingsNavigator), + TabItem.Settings(navigator = settingsNavigator) ) val pagerState = rememberPagerState() Column( modifier = Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, + horizontalAlignment = Alignment.CenterHorizontally ) { TopAppBar( title = { @@ -61,18 +76,18 @@ fun MainScreen( text = "Quench", fontSize = 30.sp, textAlign = TextAlign.Center, - fontFamily = roboto, + fontFamily = roboto ) }, modifier = Modifier.fillMaxWidth(), backgroundColor = primaryColor, contentColor = Color.White, - elevation = 4.dp, + elevation = 4.dp ) CustomTab(tabs = tabs, pagerState = pagerState) TabContent( tabs = tabs, - pagerState = pagerState, + pagerState = pagerState ) } } @@ -82,11 +97,11 @@ fun MainScreen( @Composable fun TabContent( tabs: List, - pagerState: PagerState, + pagerState: PagerState ) { HorizontalPager(count = tabs.size, state = pagerState) { page -> tabs[page].screen( - onClick = { }, + onClick = { } ) } } @@ -95,7 +110,7 @@ fun TabContent( @Composable fun CustomTab( tabs: List, - pagerState: PagerState, + pagerState: PagerState ) { val scope = rememberCoroutineScope() @@ -105,16 +120,16 @@ fun CustomTab( contentColor = Color.White, indicator = { tabPositions -> TabRowDefaults.Indicator( - Modifier.pagerTabIndicatorOffset(pagerState, tabPositions), + Modifier.pagerTabIndicatorOffset(pagerState, tabPositions) ) - }, + } ) { tabs.forEachIndexed { index, tabItem -> LeadingIconTab( icon = { Icon( painter = painterResource(id = tabItem.icon), - contentDescription = "", + contentDescription = "" ) }, selected = pagerState.currentPage == index, @@ -123,7 +138,7 @@ fun CustomTab( pagerState.animateScrollToPage(index) } }, - text = { Text(text = tabItem.title, fontFamily = roboto) }, + text = { Text(text = tabItem.title, fontFamily = roboto) } ) } } diff --git a/app/src/main/java/com/brandyodhiambo/quench/ui/splash/SplashScreen.kt b/app/src/main/java/com/brandyodhiambo/quench/ui/splash/SplashScreen.kt index b305525..950d91c 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/ui/splash/SplashScreen.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/ui/splash/SplashScreen.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench.ui.splash import androidx.compose.foundation.layout.Arrangement @@ -13,27 +28,25 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.brandyodhiambo.designsystem.components.Loader -import com.brandyodhiambo.home.presentation.sleep_wake_screen.SleepWakeViewModel +import com.brandyodhiambo.home.presentation.sleepWakeScreen.SleepWakeViewModel import com.brandyodhiambo.quench.R import com.ramcosta.composedestinations.annotation.Destination import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.withContext - interface SplashScreenNavigator { fun navigateToSleepWakeTimeScreen() fun popBackStack() fun navigateToMainScreen() - } + @Composable @Destination(start = true) fun SplashScreen( navigator: SplashScreenNavigator, viewModel: SleepWakeViewModel = hiltViewModel() ) { - val sleepTime = viewModel.sleepTime.observeAsState() val wakeTime = viewModel.wakeTime.observeAsState() diff --git a/app/src/main/java/com/brandyodhiambo/quench/util/AlarmReceiver.kt b/app/src/main/java/com/brandyodhiambo/quench/util/AlarmReceiver.kt index 2eac94d..bed05df 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/util/AlarmReceiver.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/util/AlarmReceiver.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench.util import android.app.NotificationManager @@ -14,13 +29,13 @@ class AlarmReceiver : BroadcastReceiver() { val notificationManager = ContextCompat.getSystemService( context!!, - NotificationManager::class.java, + NotificationManager::class.java ) as NotificationManager notificationManager.sendReminderNotification( context = context, title = "Drink Water", - message = message, + message = message ) } } diff --git a/app/src/main/java/com/brandyodhiambo/quench/util/AlarmSchedular.kt b/app/src/main/java/com/brandyodhiambo/quench/util/AlarmSchedular.kt index 19f1836..74e9dce 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/util/AlarmSchedular.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/util/AlarmSchedular.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench.util import com.brandyodhiambo.common.domain.model.AlarmData @@ -6,4 +21,4 @@ interface AlarmSchedular { fun schedule(item: AlarmData) fun cancel(item: AlarmData) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brandyodhiambo/quench/util/AlarmSchedularImpl.kt b/app/src/main/java/com/brandyodhiambo/quench/util/AlarmSchedularImpl.kt index f36ba8c..b94f686 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/util/AlarmSchedularImpl.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/util/AlarmSchedularImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench.util import android.app.AlarmManager @@ -8,7 +23,7 @@ import com.brandyodhiambo.common.domain.model.AlarmData import java.time.ZoneId class AlarmSchedularImpl( - private val context: Context, + private val context: Context ) : AlarmSchedular { private val alarmManager = context.getSystemService(AlarmManager::class.java) @@ -24,8 +39,8 @@ class AlarmSchedularImpl( context, item.hashCode(), intent, - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, - ), + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE + ) ) } @@ -35,8 +50,8 @@ class AlarmSchedularImpl( context, item.hashCode(), Intent(context, AlarmReceiver::class.java), - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, - ), + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE + ) ) } } diff --git a/app/src/main/java/com/brandyodhiambo/quench/util/NotificationUtil.kt b/app/src/main/java/com/brandyodhiambo/quench/util/NotificationUtil.kt index 7f5a2dc..e3e3b2f 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/util/NotificationUtil.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/util/NotificationUtil.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench.util import android.app.NotificationChannel @@ -23,7 +38,7 @@ fun createChannel(context: Context) { fun NotificationManager.sendReminderNotification( context: Context, title: String, - message: String, + message: String ) { // Opening the Notification @@ -32,7 +47,7 @@ fun NotificationManager.sendReminderNotification( context, NOTIFICATION_ID, contentIntent, - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) // Building the notification val builder = NotificationCompat.Builder(context, CHANNEL_ID) @@ -40,7 +55,7 @@ fun NotificationManager.sendReminderNotification( .setContentText(message) .setStyle( NotificationCompat.BigTextStyle() - .bigText(message), + .bigText(message) ) .setSmallIcon(R.drawable.ic_notification) .setPriority(NotificationCompat.PRIORITY_HIGH) diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 9c02e43..15be7d3 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -8,4 +8,4 @@ #FF000000 #FFFFFFFF #FF1F93F8 - \ No newline at end of file + diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml index c5d5899..f42ada6 100644 --- a/app/src/main/res/values/ic_launcher_background.xml +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -1,4 +1,4 @@ #FFFFFF - \ No newline at end of file + diff --git a/app/src/main/res/values/splash.xml b/app/src/main/res/values/splash.xml index 1dbc856..a75b32d 100644 --- a/app/src/main/res/values/splash.xml +++ b/app/src/main/res/values/splash.xml @@ -6,4 +6,4 @@ 200 @style/Theme.Quench - \ No newline at end of file + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1fafe89..ec0c7d5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,4 @@ Quench It\'s time to drink water - \ No newline at end of file + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index ce455b7..3bc8ece 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -4,4 +4,4 @@ - \ No newline at end of file + diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml index fa0f996..148c18b 100644 --- a/app/src/main/res/xml/backup_rules.xml +++ b/app/src/main/res/xml/backup_rules.xml @@ -10,4 +10,4 @@ --> - \ No newline at end of file + diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml index 9ee9997..0c4f95c 100644 --- a/app/src/main/res/xml/data_extraction_rules.xml +++ b/app/src/main/res/xml/data_extraction_rules.xml @@ -16,4 +16,4 @@ --> - \ No newline at end of file + diff --git a/app/src/test/java/com/brandyodhiambo/quench/ExampleUnitTest.kt b/app/src/test/java/com/brandyodhiambo/quench/ExampleUnitTest.kt index 77b5bf9..cdea123 100644 --- a/app/src/test/java/com/brandyodhiambo/quench/ExampleUnitTest.kt +++ b/app/src/test/java/com/brandyodhiambo/quench/ExampleUnitTest.kt @@ -1,9 +1,23 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.quench +import junit.framework.TestCase.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +28,4 @@ class ExampleUnitTest { fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/build.gradle.kts b/build.gradle.kts index 540c244..988d6c5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,16 +4,22 @@ buildscript { mavenCentral() } dependencies { - classpath ("com.google.dagger:hilt-android-gradle-plugin:2.42") + classpath("com.google.dagger:hilt-android-gradle-plugin:2.42") + classpath("com.diffplug.spotless:spotless-plugin-gradle:6.19.0") } -}// Top-level build file where you can add configuration options common to all sub-projects/modules. +} // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id ("com.android.application") version ("7.2.1") apply false - id ("com.android.library") version ("7.2.1") apply false - id ("org.jetbrains.kotlin.android") version ("1.7.0") apply false + id("com.android.application") version ("7.2.1") apply false + id("com.android.library") version ("7.2.1") apply false + id("org.jetbrains.kotlin.android") version ("1.7.0") apply false + + id("org.jlleitschuh.gradle.ktlint") version "11.3.1" apply false + id("com.diffplug.spotless") version "6.19.0" apply false } -/* -task clean(type: Delete) { - delete rootProject.buildDir -}*/ +subprojects { + afterEvaluate { + project.apply("$rootDir/spotless.gradle") + project.apply("$rootDir/ktlint.gradle") + } +} diff --git a/core/common/src/androidTest/java/com/brandyodhiambo/common/ExampleInstrumentedTest.kt b/core/common/src/androidTest/java/com/brandyodhiambo/common/ExampleInstrumentedTest.kt index 7fb6bf6..61d52ab 100644 --- a/core/common/src/androidTest/java/com/brandyodhiambo/common/ExampleInstrumentedTest.kt +++ b/core/common/src/androidTest/java/com/brandyodhiambo/common/ExampleInstrumentedTest.kt @@ -1,13 +1,26 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import junit.framework.TestCase.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * @@ -21,4 +34,4 @@ class ExampleInstrumentedTest { val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.brandyodhiambo.common.test", appContext.packageName) } -} \ No newline at end of file +} diff --git a/core/common/src/main/AndroidManifest.xml b/core/common/src/main/AndroidManifest.xml index f762718..be9f5a5 100644 --- a/core/common/src/main/AndroidManifest.xml +++ b/core/common/src/main/AndroidManifest.xml @@ -2,4 +2,4 @@ - \ No newline at end of file + diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Achievement.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Achievement.kt index fe05594..632f483 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Achievement.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Achievement.kt @@ -1,6 +1,21 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class Achievement( val isAchieved: Boolean, - val day: String, -) \ No newline at end of file + val day: String +) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/AlarmData.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/AlarmData.kt index e138712..c5f6e71 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/AlarmData.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/AlarmData.kt @@ -1,8 +1,23 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model import java.time.LocalDateTime data class AlarmData( val time: LocalDateTime, - val message: String, + val message: String ) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/DailyStatistics.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/DailyStatistics.kt index 0eb1a45..3cb9b35 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/DailyStatistics.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/DailyStatistics.kt @@ -1,6 +1,21 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class DailyStatistics( val amountTaken: Float, - val day: String, + val day: String ) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Day.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Day.kt index 9b3eeb6..e506734 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Day.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Day.kt @@ -1,6 +1,21 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class Day( val day: String, - val isOn: Boolean, -) \ No newline at end of file + val isOn: Boolean +) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Days.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Days.kt index 8dd6df0..a994065 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Days.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Days.kt @@ -1,6 +1,21 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class Days( val day: String, - var isSelected: Boolean, -) \ No newline at end of file + var isSelected: Boolean +) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/GoalWaterIntake.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/GoalWaterIntake.kt index 1e2a463..f07a0bd 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/GoalWaterIntake.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/GoalWaterIntake.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class GoalWaterIntake( diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/IdealWaterIntake.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/IdealWaterIntake.kt index 3e1463e..8bac36b 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/IdealWaterIntake.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/IdealWaterIntake.kt @@ -1,6 +1,21 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class IdealWaterIntake( val waterIntake: Int, - val form:String + val form: String ) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Level.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Level.kt index a31d2c8..23eba82 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Level.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/Level.kt @@ -1,6 +1,21 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class Level( val amountTaken: Float, - val waterTaken: Int, + val waterTaken: Int ) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/MonthlyStatistics.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/MonthlyStatistics.kt index 380ff1d..e473683 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/MonthlyStatistics.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/MonthlyStatistics.kt @@ -1,6 +1,21 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class MonthlyStatistics( val amountTaken: Float, - val month: String, + val month: String ) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/ReminderTime.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/ReminderTime.kt index da746b0..0bc128c 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/ReminderTime.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/ReminderTime.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class ReminderTime( @@ -6,5 +21,5 @@ data class ReminderTime( val ampm: String, val isRepeated: Boolean, val isAllDay: Boolean, - val days: List, + val days: List ) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/SelectedDrink.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/SelectedDrink.kt index 1844a1d..f21317b 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/SelectedDrink.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/SelectedDrink.kt @@ -1,8 +1,23 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class SelectedDrink( val drinkValue: String, val time: String, val icon: Int, - val id:Int? = null + val id: Int? = null ) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/SleepTime.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/SleepTime.kt index d8aa827..0be3b4a 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/SleepTime.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/SleepTime.kt @@ -1,7 +1,22 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class SleepTime( val hours: Int, val minutes: Int, - val amPm: String, + val amPm: String ) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/WakeTime.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/WakeTime.kt index 67adaa8..d4870d6 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/WakeTime.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/WakeTime.kt @@ -1,7 +1,22 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class WakeTime( val hours: Int, val minutes: Int, - val amPm: String, + val amPm: String ) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/WeeklyStatistics.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/WeeklyStatistics.kt index dd0834c..45452fa 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/model/WeeklyStatistics.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/model/WeeklyStatistics.kt @@ -1,6 +1,21 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.model data class WeeklyStatistics( val amountTaken: Float, - val week: String, + val week: String ) diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/AchievementRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/AchievementRepository.kt index 28914fe..ca82122 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/AchievementRepository.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/AchievementRepository.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.repository import androidx.lifecycle.LiveData diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/DailyStatisticsRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/DailyStatisticsRepository.kt index f5e7603..c866377 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/DailyStatisticsRepository.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/DailyStatisticsRepository.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.repository import androidx.lifecycle.LiveData diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/GoalWaterIntakeRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/GoalWaterIntakeRepository.kt index aa7b814..5182e6b 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/GoalWaterIntakeRepository.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/GoalWaterIntakeRepository.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.repository import androidx.lifecycle.LiveData @@ -9,4 +24,4 @@ interface GoalWaterIntakeRepository { suspend fun deleteGoalWaterIntake(goalWaterIntake: GoalWaterIntake) suspend fun deleteAllGoalWaterIntakes() fun getGoalWaterIntake(): LiveData -} \ No newline at end of file +} diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/IdealWaterIntakeRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/IdealWaterIntakeRepository.kt index d5e2b64..bf14789 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/IdealWaterIntakeRepository.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/IdealWaterIntakeRepository.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.repository import androidx.lifecycle.LiveData @@ -9,4 +24,4 @@ interface IdealWaterIntakeRepository { suspend fun deleteIdealWaterIntake(idealWaterIntake: IdealWaterIntake) suspend fun deleteAllIdealWaterIntakes() fun getIdealWaterIntake(): LiveData -} \ No newline at end of file +} diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/LevelRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/LevelRepository.kt index 702d997..7bca607 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/LevelRepository.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/LevelRepository.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.repository import androidx.lifecycle.LiveData diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/MonthlyStatisticsRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/MonthlyStatisticsRepository.kt index d139f41..9680e44 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/MonthlyStatisticsRepository.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/MonthlyStatisticsRepository.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.repository import androidx.lifecycle.LiveData diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/ReminderTimeRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/ReminderTimeRepository.kt index a7b0ee2..39b7b3b 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/ReminderTimeRepository.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/ReminderTimeRepository.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.repository import androidx.lifecycle.LiveData diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/SelectedDrinkRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/SelectedDrinkRepository.kt index 97c94c9..cafeee7 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/SelectedDrinkRepository.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/SelectedDrinkRepository.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.repository import androidx.lifecycle.LiveData @@ -8,4 +23,4 @@ interface SelectedDrinkRepository { suspend fun insertSelectedDrink(selectedDrink: SelectedDrink) suspend fun deleteAllSelectedDrinks() suspend fun deleteOneSelectedDrink(id: Int) -} \ No newline at end of file +} diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/SleepTimeRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/SleepTimeRepository.kt index 9b9be88..7b79f74 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/SleepTimeRepository.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/SleepTimeRepository.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.repository import androidx.lifecycle.LiveData @@ -10,4 +25,4 @@ interface SleepTimeRepository { fun getSleepTime(): LiveData suspend fun deleteSleepTime(sleepTime: SleepTime) suspend fun dellAllSleepTimes() -} \ No newline at end of file +} diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/WakeTimeRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/WakeTimeRepository.kt index 2b9721b..2f445ae 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/WakeTimeRepository.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/WakeTimeRepository.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.repository import androidx.lifecycle.LiveData @@ -10,4 +25,4 @@ interface WakeTimeRepository { fun getWakeTime(): LiveData suspend fun deleteWakeTime(wakeTime: WakeTime) suspend fun dellAllWakeTimes() -} \ No newline at end of file +} diff --git a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/WeeklyStatisticRepository.kt b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/WeeklyStatisticRepository.kt index d7c6693..a690bf7 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/WeeklyStatisticRepository.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/domain/repository/WeeklyStatisticRepository.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.domain.repository import androidx.lifecycle.LiveData diff --git a/core/common/src/main/java/com/brandyodhiambo/common/presentation/component/WaterIntakeGoalDialog.kt b/core/common/src/main/java/com/brandyodhiambo/common/presentation/component/WaterIntakeGoalDialog.kt index 24a5c22..99de9d0 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/presentation/component/WaterIntakeGoalDialog.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/presentation/component/WaterIntakeGoalDialog.kt @@ -1,12 +1,46 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.presentation.component import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +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.foundation.text.KeyboardOptions -import androidx.compose.material.* -import androidx.compose.runtime.* +import androidx.compose.material.Card +import androidx.compose.material.DropdownMenuItem +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ExposedDropdownMenuBox +import androidx.compose.material.ExposedDropdownMenuDefaults +import androidx.compose.material.OutlinedTextField +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.material.TextFieldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color.Companion.Gray @@ -29,11 +63,11 @@ import com.brandyodhiambo.designsystem.theme.primaryColor fun WaterIntakeDialog( modifier: Modifier = Modifier, openCustomDialog: MutableState, - currentWaterIntakeText:String, - currentWaterIntakeFormText:String, + currentWaterIntakeText: String, + currentWaterIntakeFormText: String, onCurrentWaterIntakeTextChange: (String) -> Unit, - onCurrentWaterIntakeFormTextChange:(String) -> Unit, - onOkayClick: () -> Unit, + onCurrentWaterIntakeFormTextChange: (String) -> Unit, + onOkayClick: () -> Unit ) { Card( diff --git a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt index e320472..cee46a8 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt @@ -1,12 +1,25 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common.util import android.annotation.SuppressLint import androidx.lifecycle.LiveData import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.first -import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext import java.text.SimpleDateFormat import java.time.DayOfWeek @@ -17,7 +30,6 @@ import java.time.format.TextStyle import java.time.temporal.TemporalAdjusters import java.time.temporal.WeekFields import java.util.* -import kotlin.coroutines.resume @SuppressLint("SimpleDateFormat") fun formatDate(timestamp: Long): String { @@ -39,21 +51,6 @@ fun String.toInitials(): String { .reduce { acc, s -> acc + s } } -fun isEndOfDay(dateTime: LocalDateTime): Boolean { - val endOfDay = LocalDateTime.of(dateTime.toLocalDate(), LocalTime.MAX) - return dateTime == endOfDay -} - -fun isEndOfWeek(date: LocalDate): Boolean { - val endOfWeek = date.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)) - return date == endOfWeek -} - -fun isEndOfMonth(date: LocalDate): Boolean { - val endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth()) - return date == endOfMonth -} - fun getCurrentDay(): String { val now = LocalDateTime.now() val currentDayOfWeek = now.dayOfWeek @@ -97,9 +94,3 @@ suspend fun LiveData.awaitValue(): T = withContext(Dispatchers.Default) { } } } - - - - - - diff --git a/core/common/src/main/res/drawable/ic_launcher_foreground.xml b/core/common/src/main/res/drawable/ic_launcher_foreground.xml index 2b068d1..7706ab9 100644 --- a/core/common/src/main/res/drawable/ic_launcher_foreground.xml +++ b/core/common/src/main/res/drawable/ic_launcher_foreground.xml @@ -27,4 +27,4 @@ android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" android:strokeWidth="1" android:strokeColor="#00000000" /> - \ No newline at end of file + diff --git a/core/common/src/main/res/drawable/test.xml b/core/common/src/main/res/drawable/test.xml index a8b409b..7fc46c5 100644 --- a/core/common/src/main/res/drawable/test.xml +++ b/core/common/src/main/res/drawable/test.xml @@ -1,4 +1,4 @@ - \ No newline at end of file + diff --git a/core/common/src/test/java/com/brandyodhiambo/common/ExampleUnitTest.kt b/core/common/src/test/java/com/brandyodhiambo/common/ExampleUnitTest.kt index ae0f167..7a5811a 100644 --- a/core/common/src/test/java/com/brandyodhiambo/common/ExampleUnitTest.kt +++ b/core/common/src/test/java/com/brandyodhiambo/common/ExampleUnitTest.kt @@ -1,9 +1,23 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.common +import junit.framework.TestCase.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +28,4 @@ class ExampleUnitTest { fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index 947365c..f46cd52 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -49,4 +49,4 @@ dependencies { // Kotlin Extensions and Coroutines support for Room implementation("androidx.room:room-ktx:${Versions.room_version}") -} \ No newline at end of file +} diff --git a/core/database/src/androidTest/java/com/brandyodhiambo/database/ExampleInstrumentedTest.kt b/core/database/src/androidTest/java/com/brandyodhiambo/database/ExampleInstrumentedTest.kt index ffd3ba4..27ad3d1 100644 --- a/core/database/src/androidTest/java/com/brandyodhiambo/database/ExampleInstrumentedTest.kt +++ b/core/database/src/androidTest/java/com/brandyodhiambo/database/ExampleInstrumentedTest.kt @@ -1,13 +1,26 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.database -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import junit.framework.TestCase.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * @@ -21,4 +34,4 @@ class ExampleInstrumentedTest { val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.brandyodhiambo.database.test", appContext.packageName) } -} \ No newline at end of file +} diff --git a/core/database/src/main/AndroidManifest.xml b/core/database/src/main/AndroidManifest.xml index a5918e6..8bdb7e1 100644 --- a/core/database/src/main/AndroidManifest.xml +++ b/core/database/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ - \ No newline at end of file + diff --git a/core/database/src/main/java/com/brandyodhiambo/Constants.kt b/core/database/src/main/java/com/brandyodhiambo/Constants.kt index fb8543a..dade69d 100644 --- a/core/database/src/main/java/com/brandyodhiambo/Constants.kt +++ b/core/database/src/main/java/com/brandyodhiambo/Constants.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo object Constants { diff --git a/core/database/src/main/java/com/brandyodhiambo/converter/Converter.kt b/core/database/src/main/java/com/brandyodhiambo/converter/Converter.kt index 8a52de4..f06bb65 100644 --- a/core/database/src/main/java/com/brandyodhiambo/converter/Converter.kt +++ b/core/database/src/main/java/com/brandyodhiambo/converter/Converter.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.converter import androidx.room.ProvidedTypeConverter @@ -6,14 +21,13 @@ import com.brandyodhiambo.common.domain.model.Days import com.google.gson.Gson import com.google.gson.reflect.TypeToken - @ProvidedTypeConverter class Converter(private val gson: Gson) { @TypeConverter fun toDaysString(parts: List): String { return gson.toJson( parts, - object : TypeToken>() {}.type, + object : TypeToken>() {}.type ) ?: "[]" } @@ -21,7 +35,7 @@ class Converter(private val gson: Gson) { fun toDays(parts: String): List { return gson.fromJson>( parts, - object : TypeToken>() {}.type, + object : TypeToken>() {}.type ) ?: emptyList() } @@ -29,7 +43,7 @@ class Converter(private val gson: Gson) { fun toDayString(parts: Days): String { return gson.toJson( parts, - object : TypeToken() {}.type, + object : TypeToken() {}.type ) ?: "" } @@ -37,7 +51,7 @@ class Converter(private val gson: Gson) { fun toDay(parts: String): Days? { return gson.fromJson( parts, - object : TypeToken() {}.type, + object : TypeToken() {}.type ) ?: null } @@ -45,7 +59,7 @@ class Converter(private val gson: Gson) { fun fromList(parts: List): String { return gson.toJson( parts, - object : TypeToken>() {}.type, + object : TypeToken>() {}.type ) ?: "[]" } @@ -53,7 +67,7 @@ class Converter(private val gson: Gson) { fun toList(parts: String): List { return gson.fromJson>( parts, - object : TypeToken>() {}.type, + object : TypeToken>() {}.type ) ?: emptyList() } -} \ No newline at end of file +} diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/AchievementDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/AchievementDao.kt index 7d69faf..801335f 100644 --- a/core/database/src/main/java/com/brandyodhiambo/dao/AchievementDao.kt +++ b/core/database/src/main/java/com/brandyodhiambo/dao/AchievementDao.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.dao import androidx.lifecycle.LiveData diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/DailyStatisticsDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/DailyStatisticsDao.kt index e2de24e..05eebdf 100644 --- a/core/database/src/main/java/com/brandyodhiambo/dao/DailyStatisticsDao.kt +++ b/core/database/src/main/java/com/brandyodhiambo/dao/DailyStatisticsDao.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.dao import androidx.lifecycle.LiveData diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/GoalWaterIntakeDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/GoalWaterIntakeDao.kt index e111dda..60a7682 100644 --- a/core/database/src/main/java/com/brandyodhiambo/dao/GoalWaterIntakeDao.kt +++ b/core/database/src/main/java/com/brandyodhiambo/dao/GoalWaterIntakeDao.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.dao import androidx.lifecycle.LiveData @@ -20,11 +35,8 @@ interface GoalWaterIntakeDao { suspend fun deleteGoalIntake(goalWaterIntake: GoalWaterIntakeEntity) @Query("UPDATE goal_table SET waterIntake = :waterIntake, form = :form WHERE id = :id") - suspend fun updateGoalIntake(id: Int,waterIntake: String, form: String) + suspend fun updateGoalIntake(id: Int, waterIntake: String, form: String) @Query("DELETE FROM goal_table") suspend fun deleteAllGoalIntake() - - - -} \ No newline at end of file +} diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/IdealWaterIntakeDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/IdealWaterIntakeDao.kt index 69a3807..1ce3479 100644 --- a/core/database/src/main/java/com/brandyodhiambo/dao/IdealWaterIntakeDao.kt +++ b/core/database/src/main/java/com/brandyodhiambo/dao/IdealWaterIntakeDao.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.dao import androidx.lifecycle.LiveData @@ -19,8 +34,8 @@ interface IdealWaterIntakeDao { suspend fun deleteIdealIntake(idealWaterIntake: IdealWaterIntakeEntity) @Query("UPDATE ideal_water_table SET waterIntake = :waterIntake, form = :form WHERE id = :id") - suspend fun updateIdealIntake(id: Int,waterIntake: String, form: String) + suspend fun updateIdealIntake(id: Int, waterIntake: String, form: String) @Query("DELETE FROM ideal_water_table") suspend fun deleteAllIdealIntake() -} \ No newline at end of file +} diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/LevelDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/LevelDao.kt index 75e22cb..c88e34c 100644 --- a/core/database/src/main/java/com/brandyodhiambo/dao/LevelDao.kt +++ b/core/database/src/main/java/com/brandyodhiambo/dao/LevelDao.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.dao import androidx.lifecycle.LiveData diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/MonthlyStatisticsDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/MonthlyStatisticsDao.kt index 59ee467..8e2e985 100644 --- a/core/database/src/main/java/com/brandyodhiambo/dao/MonthlyStatisticsDao.kt +++ b/core/database/src/main/java/com/brandyodhiambo/dao/MonthlyStatisticsDao.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.dao import androidx.lifecycle.LiveData diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/ReminderTimeDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/ReminderTimeDao.kt index 3cc9d80..da38d67 100644 --- a/core/database/src/main/java/com/brandyodhiambo/dao/ReminderTimeDao.kt +++ b/core/database/src/main/java/com/brandyodhiambo/dao/ReminderTimeDao.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.dao import androidx.lifecycle.LiveData @@ -27,9 +42,9 @@ interface ReminderTimeDao { ampm: String, isRepeated: Boolean, isAllDay: Boolean, - days: List, + days: List ) @Query("DELETE FROM reminder_table") suspend fun deleteAllReminderTime() -} \ No newline at end of file +} diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/SelectedDrinkDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/SelectedDrinkDao.kt index 55cfdeb..8ea0426 100644 --- a/core/database/src/main/java/com/brandyodhiambo/dao/SelectedDrinkDao.kt +++ b/core/database/src/main/java/com/brandyodhiambo/dao/SelectedDrinkDao.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.dao import androidx.lifecycle.LiveData @@ -21,8 +36,8 @@ interface SelectedDrinkDao { suspend fun deleteSelectedDrink(id: Int) @Query("UPDATE selected_drink_table SET drinkValue = :drinkValue, time = :time , icon = :icon WHERE id = :id") - suspend fun updateSelectedDrink(id: Int,drinkValue: String, time: String,icon: Int) + suspend fun updateSelectedDrink(id: Int, drinkValue: String, time: String, icon: Int) @Query("DELETE FROM selected_drink_table") suspend fun deleteAllSelectedDrink() -} \ No newline at end of file +} diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/SleepTimeDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/SleepTimeDao.kt index 8586bbe..65d4b21 100644 --- a/core/database/src/main/java/com/brandyodhiambo/dao/SleepTimeDao.kt +++ b/core/database/src/main/java/com/brandyodhiambo/dao/SleepTimeDao.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.dao import androidx.lifecycle.LiveData @@ -20,8 +35,8 @@ interface SleepTimeDao { suspend fun deleteSleepTime(sleepTimeEntity: SleepTimeEntity) @Query("UPDATE sleep_time_table SET hour = :hours, minute = :minutes, ampm = :ampm WHERE id = :id") - suspend fun updateSleepTime(id: Int,hours: String, minutes: String,ampm:String) + suspend fun updateSleepTime(id: Int, hours: String, minutes: String, ampm: String) @Query("DELETE FROM sleep_time_table") suspend fun deleteAllSleepTime() -} \ No newline at end of file +} diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/WakeTimeDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/WakeTimeDao.kt index 3e068b8..30d6be4 100644 --- a/core/database/src/main/java/com/brandyodhiambo/dao/WakeTimeDao.kt +++ b/core/database/src/main/java/com/brandyodhiambo/dao/WakeTimeDao.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.dao import androidx.lifecycle.LiveData @@ -20,8 +35,8 @@ interface WakeTimeDao { suspend fun deleteWakeTime(wakeTimeEntity: WakeTimeEntity) @Query("UPDATE wake_time_table SET hour = :hours, minute = :minutes, ampm = :ampm WHERE id = :id") - suspend fun updateWakeTime(id: Int,hours: String, minutes: String,ampm:String) + suspend fun updateWakeTime(id: Int, hours: String, minutes: String, ampm: String) @Query("DELETE FROM wake_time_table") suspend fun deleteAllWakeTime() -} \ No newline at end of file +} diff --git a/core/database/src/main/java/com/brandyodhiambo/dao/WeeklyStatisticDao.kt b/core/database/src/main/java/com/brandyodhiambo/dao/WeeklyStatisticDao.kt index bb0c2fd..2664b5a 100644 --- a/core/database/src/main/java/com/brandyodhiambo/dao/WeeklyStatisticDao.kt +++ b/core/database/src/main/java/com/brandyodhiambo/dao/WeeklyStatisticDao.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.dao import androidx.lifecycle.LiveData diff --git a/core/database/src/main/java/com/brandyodhiambo/database/QuenchDatabase.kt b/core/database/src/main/java/com/brandyodhiambo/database/QuenchDatabase.kt index 9eb47bb..ee206f9 100644 --- a/core/database/src/main/java/com/brandyodhiambo/database/QuenchDatabase.kt +++ b/core/database/src/main/java/com/brandyodhiambo/database/QuenchDatabase.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.database import androidx.room.Database @@ -31,7 +46,7 @@ import com.brandyodhiambo.entity.WeeklyStatisticsEntity @Database( entities = [SelectedDrinkEntity::class, WakeTimeEntity::class, IdealWaterIntakeEntity::class, GoalWaterIntakeEntity::class, SleepTimeEntity::class, LevelEntity::class, ReminderTimeEntity::class, DailyStatisticsEntity::class, WeeklyStatisticsEntity::class, MonthlyStatisticsEntity::class, AchievementEntity::class], version = 5, - exportSchema = false, + exportSchema = false ) abstract class QuenchDatabase : RoomDatabase() { abstract fun wakeTimeDao(): WakeTimeDao diff --git a/core/database/src/main/java/com/brandyodhiambo/di/DatabaseModule.kt b/core/database/src/main/java/com/brandyodhiambo/di/DatabaseModule.kt index a879ca5..1e9d81d 100644 --- a/core/database/src/main/java/com/brandyodhiambo/di/DatabaseModule.kt +++ b/core/database/src/main/java/com/brandyodhiambo/di/DatabaseModule.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.di import android.content.Context @@ -21,12 +36,12 @@ object DatabaseModule { @Singleton fun provideQuenchDatabase( @ApplicationContext context: Context, - gson: Gson, + gson: Gson ): QuenchDatabase { return Room.databaseBuilder( context, QuenchDatabase::class.java, - DATABASE_NAME, + DATABASE_NAME ) .allowMainThreadQueries() .fallbackToDestructiveMigration() diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/AchievementEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/AchievementEntity.kt index 3cc0230..fa43da9 100644 --- a/core/database/src/main/java/com/brandyodhiambo/entity/AchievementEntity.kt +++ b/core/database/src/main/java/com/brandyodhiambo/entity/AchievementEntity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.entity import androidx.room.Entity @@ -9,5 +24,5 @@ data class AchievementEntity( @PrimaryKey(autoGenerate = true) val id: Int = 0, val isAchieved: Boolean, - val day: String, -) \ No newline at end of file + val day: String +) diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/DailyStatisticsEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/DailyStatisticsEntity.kt index d62e248..7598aca 100644 --- a/core/database/src/main/java/com/brandyodhiambo/entity/DailyStatisticsEntity.kt +++ b/core/database/src/main/java/com/brandyodhiambo/entity/DailyStatisticsEntity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.entity import androidx.room.Entity @@ -9,5 +24,5 @@ data class DailyStatisticsEntity( @PrimaryKey(autoGenerate = true) val id: Int = 0, val amountTaken: Float, - val day: String, + val day: String ) diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/GoalWaterIntakeEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/GoalWaterIntakeEntity.kt index 9f89a80..a445f49 100644 --- a/core/database/src/main/java/com/brandyodhiambo/entity/GoalWaterIntakeEntity.kt +++ b/core/database/src/main/java/com/brandyodhiambo/entity/GoalWaterIntakeEntity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.entity import androidx.room.Entity diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/IdealWaterIntakeEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/IdealWaterIntakeEntity.kt index 32c9bfb..c7acde1 100644 --- a/core/database/src/main/java/com/brandyodhiambo/entity/IdealWaterIntakeEntity.kt +++ b/core/database/src/main/java/com/brandyodhiambo/entity/IdealWaterIntakeEntity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.entity import androidx.room.Entity @@ -9,5 +24,5 @@ data class IdealWaterIntakeEntity( @PrimaryKey(autoGenerate = true) val id: Int = 0, val waterIntake: Int, - val form:String + val form: String ) diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/LevelEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/LevelEntity.kt index 66e9485..94932ec 100644 --- a/core/database/src/main/java/com/brandyodhiambo/entity/LevelEntity.kt +++ b/core/database/src/main/java/com/brandyodhiambo/entity/LevelEntity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.entity import androidx.room.Entity @@ -9,5 +24,5 @@ data class LevelEntity( @PrimaryKey(autoGenerate = true) val id: Int = 0, val amountTaken: Float, - val waterTaken: Int, + val waterTaken: Int ) diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/MonthlyStatisticsEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/MonthlyStatisticsEntity.kt index 27d1ac9..151c6a1 100644 --- a/core/database/src/main/java/com/brandyodhiambo/entity/MonthlyStatisticsEntity.kt +++ b/core/database/src/main/java/com/brandyodhiambo/entity/MonthlyStatisticsEntity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.entity import androidx.room.Entity @@ -9,5 +24,5 @@ data class MonthlyStatisticsEntity( @PrimaryKey(autoGenerate = true) val id: Int = 0, val amountTaken: Float, - val month: String, + val month: String ) diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/ReminderTimeEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/ReminderTimeEntity.kt index a98ac67..395574c 100644 --- a/core/database/src/main/java/com/brandyodhiambo/entity/ReminderTimeEntity.kt +++ b/core/database/src/main/java/com/brandyodhiambo/entity/ReminderTimeEntity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.entity import androidx.room.Entity @@ -14,5 +29,5 @@ data class ReminderTimeEntity( val ampm: String, val isRepeated: Boolean, val isAllDay: Boolean, - val days: List, + val days: List ) diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/SelectedDrinkEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/SelectedDrinkEntity.kt index 6b9b5d7..9b94d59 100644 --- a/core/database/src/main/java/com/brandyodhiambo/entity/SelectedDrinkEntity.kt +++ b/core/database/src/main/java/com/brandyodhiambo/entity/SelectedDrinkEntity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.entity import androidx.room.Entity diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/SleepTimeEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/SleepTimeEntity.kt index dedf9c8..a57e5a5 100644 --- a/core/database/src/main/java/com/brandyodhiambo/entity/SleepTimeEntity.kt +++ b/core/database/src/main/java/com/brandyodhiambo/entity/SleepTimeEntity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.entity import androidx.room.Entity diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/WakeTimeEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/WakeTimeEntity.kt index 5f37f4e..4b962a8 100644 --- a/core/database/src/main/java/com/brandyodhiambo/entity/WakeTimeEntity.kt +++ b/core/database/src/main/java/com/brandyodhiambo/entity/WakeTimeEntity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.entity import androidx.room.Entity diff --git a/core/database/src/main/java/com/brandyodhiambo/entity/WeeklyStatisticsEntity.kt b/core/database/src/main/java/com/brandyodhiambo/entity/WeeklyStatisticsEntity.kt index 0ea3c9f..f2544c8 100644 --- a/core/database/src/main/java/com/brandyodhiambo/entity/WeeklyStatisticsEntity.kt +++ b/core/database/src/main/java/com/brandyodhiambo/entity/WeeklyStatisticsEntity.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.entity import androidx.room.Entity @@ -9,5 +24,5 @@ data class WeeklyStatisticsEntity( @PrimaryKey(autoGenerate = true) val id: Int = 0, val amountTaken: Float, - val week: String, + val week: String ) diff --git a/core/database/src/test/java/com/brandyodhiambo/database/ExampleUnitTest.kt b/core/database/src/test/java/com/brandyodhiambo/database/ExampleUnitTest.kt index e098671..1fb06b3 100644 --- a/core/database/src/test/java/com/brandyodhiambo/database/ExampleUnitTest.kt +++ b/core/database/src/test/java/com/brandyodhiambo/database/ExampleUnitTest.kt @@ -1,9 +1,23 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.database +import junit.framework.TestCase.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +28,4 @@ class ExampleUnitTest { fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/designsystem/build.gradle.kts b/designsystem/build.gradle.kts index f0362c0..e8ff5a6 100644 --- a/designsystem/build.gradle.kts +++ b/designsystem/build.gradle.kts @@ -48,7 +48,7 @@ android { } dependencies { - implementation ("androidx.compose.animation:animation:1.3.3") - implementation ("androidx.compose.animation:animation-core:1.3.3") - implementation ("androidx.compose.animation:animation-graphics:1.3.3") + implementation("androidx.compose.animation:animation:1.3.3") + implementation("androidx.compose.animation:animation-core:1.3.3") + implementation("androidx.compose.animation:animation-graphics:1.3.3") } diff --git a/designsystem/src/androidTest/java/com/brandyodhiambo/designsystem/ExampleInstrumentedTest.kt b/designsystem/src/androidTest/java/com/brandyodhiambo/designsystem/ExampleInstrumentedTest.kt index d611c13..8fa05c2 100644 --- a/designsystem/src/androidTest/java/com/brandyodhiambo/designsystem/ExampleInstrumentedTest.kt +++ b/designsystem/src/androidTest/java/com/brandyodhiambo/designsystem/ExampleInstrumentedTest.kt @@ -1,13 +1,26 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.designsystem -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import junit.framework.TestCase.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * @@ -21,4 +34,4 @@ class ExampleInstrumentedTest { val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.brandyodhiambo.designsystem.test", appContext.packageName) } -} \ No newline at end of file +} diff --git a/designsystem/src/main/AndroidManifest.xml b/designsystem/src/main/AndroidManifest.xml index a5918e6..8bdb7e1 100644 --- a/designsystem/src/main/AndroidManifest.xml +++ b/designsystem/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ - \ No newline at end of file + diff --git a/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/CircularButton.kt b/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/CircularButton.kt index e57954c..2b3cc11 100644 --- a/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/CircularButton.kt +++ b/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/CircularButton.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.designsystem.components import androidx.compose.foundation.Image @@ -48,7 +63,7 @@ fun CircularButton( contentDescription = null ) Spacer(modifier = Modifier.height(8.dp)) - Text(text = title, fontSize = 12.sp, fontFamily = roboto,fontWeight = FontWeight.Bold) + Text(text = title, fontSize = 12.sp, fontFamily = roboto, fontWeight = FontWeight.Bold) } } } diff --git a/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/DialogComponent.kt b/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/DialogComponent.kt index c41b4bc..f5db049 100644 --- a/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/DialogComponent.kt +++ b/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/DialogComponent.kt @@ -1,8 +1,22 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.designsystem.components import androidx.compose.runtime.Composable @Composable fun DialogComponent() { - } diff --git a/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/Loader.kt b/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/Loader.kt index 9ea8f76..8083b3b 100644 --- a/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/Loader.kt +++ b/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/Loader.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.designsystem.components import androidx.compose.foundation.background @@ -17,7 +32,7 @@ import com.airbnb.lottie.compose.rememberLottieComposition @Composable fun Loader( - compositions: Int, + compositions: Int ) { val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(compositions)) val progress by animateLottieCompositionAsState(composition = composition, restartOnPlay = true, iterations = 2) @@ -29,12 +44,10 @@ fun Loader( .background(Color.White), verticalArrangement = Arrangement.Center ) { - LottieAnimation( composition = composition, - progress = { progress }, - // applyOpacityToLayers = true + progress = { progress } + // applyOpacityToLayers = true ) } - -} \ No newline at end of file +} diff --git a/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/NotificationSwitcher.kt b/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/NotificationSwitcher.kt index 1962e4d..87a1ec0 100644 --- a/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/NotificationSwitcher.kt +++ b/designsystem/src/main/java/com/brandyodhiambo/designsystem/components/NotificationSwitcher.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.designsystem.components import androidx.compose.animation.core.AnimationSpec @@ -40,19 +55,20 @@ fun NotificationSwitcher( parentShape: Shape = CircleShape, toggleShape: Shape = CircleShape, animationSpecs: AnimationSpec = tween(durationMillis = 300), - onToggle: () -> Unit, + onToggle: () -> Unit ) { val offset by animateDpAsState( targetValue = if (isOn) 0.dp else size, animationSpec = animationSpecs ) - Box(modifier = Modifier - .width(size * 2) - .height(size) - .clip(shape = parentShape) - .clickable { onToggle() } - .background(color = if (isOn) primaryColor else Color.LightGray) + Box( + modifier = Modifier + .width(size * 2) + .height(size) + .clip(shape = parentShape) + .clickable { onToggle() } + .background(color = if (isOn) primaryColor else Color.LightGray) ) { Box( modifier = Modifier @@ -101,6 +117,4 @@ fun NotificationSwitcher( } } } - - -} \ No newline at end of file +} diff --git a/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Color.kt b/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Color.kt index aa934a1..e6837d5 100644 --- a/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Color.kt +++ b/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Color.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.designsystem.theme import androidx.compose.ui.graphics.Color @@ -12,4 +27,4 @@ val blackColor = Color(0xFF2D2D2D) val secondaryWhite = Color(0xFFF2FBFF) val PrimaryWhite = Color(0xFFFFFFFF) val lightBlue = Color(0xFFD5F4FD) -val GoldColor = Color(0xFFFFD700) \ No newline at end of file +val GoldColor = Color(0xFFFFD700) diff --git a/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Shape.kt b/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Shape.kt index 0258822..736bc37 100644 --- a/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Shape.kt +++ b/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Shape.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.designsystem.theme import androidx.compose.foundation.shape.RoundedCornerShape @@ -8,4 +23,4 @@ val Shapes = Shapes( small = RoundedCornerShape(4.dp), medium = RoundedCornerShape(4.dp), large = RoundedCornerShape(0.dp) -) \ No newline at end of file +) diff --git a/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Theme.kt b/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Theme.kt index 3f22904..0070ae9 100644 --- a/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Theme.kt +++ b/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Theme.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.designsystem.theme import androidx.compose.foundation.isSystemInDarkTheme @@ -24,7 +39,7 @@ private val LightColorPalette = lightColors( onSecondary = Color.Black, onBackground = Color.Black, onSurface = Color.Black, - */ + */ ) @Composable @@ -41,4 +56,4 @@ fun QuenchTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable shapes = Shapes, content = content ) -} \ No newline at end of file +} diff --git a/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Type.kt b/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Type.kt index a2793fa..054232f 100644 --- a/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Type.kt +++ b/designsystem/src/main/java/com/brandyodhiambo/designsystem/theme/Type.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.designsystem.theme import androidx.compose.material.Typography diff --git a/designsystem/src/test/java/com/brandyodhiambo/designsystem/ExampleUnitTest.kt b/designsystem/src/test/java/com/brandyodhiambo/designsystem/ExampleUnitTest.kt index 9d8357f..7fc076b 100644 --- a/designsystem/src/test/java/com/brandyodhiambo/designsystem/ExampleUnitTest.kt +++ b/designsystem/src/test/java/com/brandyodhiambo/designsystem/ExampleUnitTest.kt @@ -1,9 +1,23 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.designsystem +import junit.framework.TestCase.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +28,4 @@ class ExampleUnitTest { fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/feature/home/src/androidTest/java/com/brandyodhiambo/home/ExampleInstrumentedTest.kt b/feature/home/src/androidTest/java/com/brandyodhiambo/home/ExampleInstrumentedTest.kt index c3f2673..4c4ecc0 100644 --- a/feature/home/src/androidTest/java/com/brandyodhiambo/home/ExampleInstrumentedTest.kt +++ b/feature/home/src/androidTest/java/com/brandyodhiambo/home/ExampleInstrumentedTest.kt @@ -1,13 +1,26 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import junit.framework.TestCase.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * @@ -21,4 +34,4 @@ class ExampleInstrumentedTest { val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.brandyodhiambo.home.test", appContext.packageName) } -} \ No newline at end of file +} diff --git a/feature/home/src/main/AndroidManifest.xml b/feature/home/src/main/AndroidManifest.xml index a5918e6..8bdb7e1 100644 --- a/feature/home/src/main/AndroidManifest.xml +++ b/feature/home/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ - \ No newline at end of file + diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/data/mapper/Mapper.kt b/feature/home/src/main/java/com/brandyodhiambo/home/data/mapper/Mapper.kt index 334d67b..95c65d1 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/data/mapper/Mapper.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/data/mapper/Mapper.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.data.mapper import com.brandyodhiambo.common.domain.model.GoalWaterIntake @@ -19,7 +34,7 @@ internal fun SleepTimeEntity.toSleepTime(): SleepTime { return SleepTime( hours = hour, minutes = minute, - amPm = ampm, + amPm = ampm ) } @@ -27,7 +42,7 @@ internal fun SleepTime.toSleepTimeEntity(): SleepTimeEntity { return SleepTimeEntity( hour = hours, minute = minutes, - ampm = amPm, + ampm = amPm ) } @@ -35,7 +50,7 @@ internal fun WakeTimeEntity.toWakeTime(): WakeTime { return WakeTime( hours = hour, minutes = minute, - amPm = ampm, + amPm = ampm ) } @@ -43,35 +58,35 @@ internal fun WakeTime.toWakeTimeEntity(): WakeTimeEntity { return WakeTimeEntity( hour = hours, minute = minutes, - ampm = amPm, + ampm = amPm ) } internal fun IdealWaterIntakeEntity.toIdealWaterIntake(): IdealWaterIntake { return IdealWaterIntake( waterIntake = waterIntake, - form = form, + form = form ) } internal fun IdealWaterIntake.toIdealWaterIntakeEntity(): IdealWaterIntakeEntity { return IdealWaterIntakeEntity( waterIntake = waterIntake, - form = form, + form = form ) } internal fun GoalWaterIntake.toGoalWaterIntakeEntity(): GoalWaterIntakeEntity { return GoalWaterIntakeEntity( waterIntake = waterIntake, - form = form, + form = form ) } internal fun GoalWaterIntakeEntity.toGoalWaterIntake(): GoalWaterIntake { return GoalWaterIntake( waterIntake = waterIntake, - form = form, + form = form ) } @@ -79,7 +94,7 @@ internal fun SelectedDrink.toSelectedDrinkEntity(): SelectedDrinkEntity { return SelectedDrinkEntity( drinkValue = drinkValue, icon = icon, - time = time, + time = time ) } @@ -88,21 +103,21 @@ internal fun SelectedDrinkEntity.toSelectedDrink(): SelectedDrink { drinkValue = drinkValue, icon = icon, time = time, - id = id, + id = id ) } internal fun LevelEntity.toLevel(): Level { return Level( amountTaken = amountTaken, - waterTaken = waterTaken, + waterTaken = waterTaken ) } internal fun Level.toLevelEntity(): LevelEntity { return LevelEntity( amountTaken = amountTaken, - waterTaken = waterTaken, + waterTaken = waterTaken ) } @@ -113,7 +128,7 @@ internal fun ReminderTimeEntity.toReminderTime(): ReminderTime { ampm = ampm, isRepeated = isRepeated, isAllDay = isAllDay, - days = days, + days = days ) } @@ -124,6 +139,6 @@ internal fun ReminderTime.toReminderEntity(): ReminderTimeEntity { ampm = ampm, isRepeated = isRepeated, isAllDay = isAllDay, - days = days, + days = days ) } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/GoalWaterIntakeRepositoryImpl.kt b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/GoalWaterIntakeRepositoryImpl.kt index 6fd7bcc..f90da9f 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/GoalWaterIntakeRepositoryImpl.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/GoalWaterIntakeRepositoryImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.data.repository import androidx.lifecycle.LiveData @@ -9,7 +24,7 @@ import com.brandyodhiambo.home.data.mapper.toGoalWaterIntake import com.brandyodhiambo.home.data.mapper.toGoalWaterIntakeEntity class GoalWaterIntakeRepositoryImpl( - private val goalWaterIntakeDao: GoalWaterIntakeDao, + private val goalWaterIntakeDao: GoalWaterIntakeDao ) : GoalWaterIntakeRepository { override suspend fun insertGoalWaterIntake(goalWaterIntake: GoalWaterIntake) { goalWaterIntakeDao.insertGoalWaterIntake(goalWaterIntake.toGoalWaterIntakeEntity()) @@ -32,4 +47,4 @@ class GoalWaterIntakeRepositoryImpl( goalWaterIntakeEntity?.toGoalWaterIntake() } } -} \ No newline at end of file +} diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/IdealWaterInkateRepositoryImpl.kt b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/IdealWaterInkateRepositoryImpl.kt index 5d49faf..edec8b3 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/IdealWaterInkateRepositoryImpl.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/IdealWaterInkateRepositoryImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.data.repository import androidx.lifecycle.LiveData diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/LevelRepositoryImpl.kt b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/LevelRepositoryImpl.kt index a8d1b7e..2e5902e 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/LevelRepositoryImpl.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/LevelRepositoryImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.data.repository import androidx.lifecycle.LiveData @@ -9,7 +24,7 @@ import com.brandyodhiambo.home.data.mapper.toLevel import com.brandyodhiambo.home.data.mapper.toLevelEntity class LevelRepositoryImpl( - private val levelDao: LevelDao, + private val levelDao: LevelDao ) : LevelRepository { override suspend fun insertLevel(level: Level) { levelDao.insertLevel(level.toLevelEntity()) @@ -20,7 +35,7 @@ class LevelRepositoryImpl( levelDao.updateLevel( id = entityData.id, amountTaken = entityData.amountTaken, - waterTaken = entityData.waterTaken, + waterTaken = entityData.waterTaken ) } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/ReminderTimeRepositoryImpl.kt b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/ReminderTimeRepositoryImpl.kt index 69846ea..c7018d7 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/ReminderTimeRepositoryImpl.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/ReminderTimeRepositoryImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.data.repository import androidx.lifecycle.LiveData @@ -7,7 +22,6 @@ import com.brandyodhiambo.common.domain.repository.ReminderTimeRepository import com.brandyodhiambo.dao.ReminderTimeDao import com.brandyodhiambo.home.data.mapper.toReminderEntity import com.brandyodhiambo.home.data.mapper.toReminderTime -import com.brandyodhiambo.home.data.mapper.toWakeTime class ReminderTimeRepositoryImpl( private val reminderTimeDao: ReminderTimeDao @@ -25,7 +39,7 @@ class ReminderTimeRepositoryImpl( ampm = entityData.ampm, isRepeated = entityData.isRepeated, isAllDay = entityData.isAllDay, - days = entityData.days, + days = entityData.days ) } @@ -42,4 +56,4 @@ class ReminderTimeRepositoryImpl( override suspend fun dellAllReminderTimes() { reminderTimeDao.deleteAllReminderTime() } -} \ No newline at end of file +} diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/SelectedDrinkRepositoryImpl.kt b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/SelectedDrinkRepositoryImpl.kt index e1ff5e5..ee4fac8 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/SelectedDrinkRepositoryImpl.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/SelectedDrinkRepositoryImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.data.repository import androidx.lifecycle.LiveData @@ -10,15 +25,15 @@ import com.brandyodhiambo.home.data.mapper.toSelectedDrinkEntity class SelectedDrinkRepositoryImpl( private val selectedDrinkDao: SelectedDrinkDao -):SelectedDrinkRepository { +) : SelectedDrinkRepository { override fun getSelectedDrink(): LiveData> { - return Transformations.map(selectedDrinkDao.getSelectedDrink()){ selectedDrinkEntity -> + return Transformations.map(selectedDrinkDao.getSelectedDrink()) { selectedDrinkEntity -> selectedDrinkEntity.map { it.toSelectedDrink() } } } - override suspend fun insertSelectedDrink(selectedDrink: SelectedDrink) { - selectedDrinkDao.insertSelectedDrink(selectedDrink.toSelectedDrinkEntity()) + override suspend fun insertSelectedDrink(selectedDrink: SelectedDrink) { + selectedDrinkDao.insertSelectedDrink(selectedDrink.toSelectedDrinkEntity()) } override suspend fun deleteAllSelectedDrinks() { @@ -28,4 +43,4 @@ class SelectedDrinkRepositoryImpl( override suspend fun deleteOneSelectedDrink(id: Int) { selectedDrinkDao.deleteSelectedDrink(id) } -} \ No newline at end of file +} diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/SleepTimeRepositoryImpl.kt b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/SleepTimeRepositoryImpl.kt index 9b2cbb3..f3a3c9c 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/SleepTimeRepositoryImpl.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/SleepTimeRepositoryImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.data.repository import androidx.lifecycle.LiveData @@ -10,7 +25,7 @@ import com.brandyodhiambo.home.data.mapper.toSleepTimeEntity class SleepTimeRepositoryImpl( private val sleepTimeDao: SleepTimeDao -):SleepTimeRepository { +) : SleepTimeRepository { override suspend fun insertSleepTime(sleepTime: SleepTime) { sleepTimeDao.insertSleepTime(sleepTime.toSleepTimeEntity()) } @@ -26,16 +41,16 @@ class SleepTimeRepositoryImpl( } override fun getSleepTime(): LiveData { - return Transformations.map(sleepTimeDao.getSleepTime()){ sleepTimeEntity -> + return Transformations.map(sleepTimeDao.getSleepTime()) { sleepTimeEntity -> sleepTimeEntity?.toSleepTime() } } override suspend fun deleteSleepTime(sleepTime: SleepTime) { - sleepTimeDao.deleteSleepTime(sleepTime.toSleepTimeEntity()) + sleepTimeDao.deleteSleepTime(sleepTime.toSleepTimeEntity()) } override suspend fun dellAllSleepTimes() { sleepTimeDao.deleteAllSleepTime() } -} \ No newline at end of file +} diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/WakeTimeRepositoryImpl.kt b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/WakeTimeRepositoryImpl.kt index a1b75d0..4a86b93 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/WakeTimeRepositoryImpl.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/WakeTimeRepositoryImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.data.repository import androidx.lifecycle.LiveData @@ -9,7 +24,7 @@ import com.brandyodhiambo.home.data.mapper.toWakeTime import com.brandyodhiambo.home.data.mapper.toWakeTimeEntity class WakeTimeRepositoryImpl( - private val wakeTimeDao: WakeTimeDao, + private val wakeTimeDao: WakeTimeDao ) : WakeTimeRepository { override suspend fun insertWakeTime(wakeTime: WakeTime) { wakeTimeDao.insertWakeTime(wakeTime.toWakeTimeEntity()) @@ -21,7 +36,7 @@ class WakeTimeRepositoryImpl( id = entityData.id, hours = entityData.hour.toString(), minutes = entityData.minute.toString(), - ampm = entityData.ampm, + ampm = entityData.ampm ) } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/di/HomeModule.kt b/feature/home/src/main/java/com/brandyodhiambo/home/di/HomeModule.kt index 471a4e5..266e55e 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/di/HomeModule.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/di/HomeModule.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.di import com.brandyodhiambo.common.domain.repository.GoalWaterIntakeRepository diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CircularRating.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CircularRating.kt index 85902ee..a0a4e32 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CircularRating.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CircularRating.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.presentation.component import androidx.compose.animation.core.animateFloatAsState @@ -38,7 +53,7 @@ fun CircularRating( color: Color = primaryColor, strokeWidth: Dp = 8.dp, animationDuration: Int = 1000, - animDelay: Int = 0, + animDelay: Int = 0 ) { var animationPlayed by remember { mutableStateOf(false) @@ -48,8 +63,8 @@ fun CircularRating( targetValue = if (animationPlayed) percentage else 0f, animationSpec = tween( durationMillis = animationDuration, - delayMillis = animDelay, - ), + delayMillis = animDelay + ) ) LaunchedEffect(key1 = true) { @@ -58,36 +73,36 @@ fun CircularRating( Box( contentAlignment = Alignment.Center, - modifier = Modifier.size(radius * 2f), + modifier = Modifier.size(radius * 2f) ) { Canvas( modifier = Modifier - .size(radius * 2f), + .size(radius * 2f) ) { drawArc( color = color, startAngle = 90f, sweepAngle = (360 * (currentPercentage.value * 0.01)).toFloat(), useCenter = false, - style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round), + style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round) ) } Column( - horizontalAlignment = Alignment.CenterHorizontally, + horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "$drunk /$goal ml", color = primaryColor, fontSize = fontSize, fontFamily = roboto, - fontWeight = FontWeight.Bold, + fontWeight = FontWeight.Bold ) Text( text = " You have completed ${(currentPercentage.value * number).toInt()}% of daily target", color = Color.Gray, fontSize = 12.sp, fontFamily = roboto, - fontWeight = FontWeight.Normal, + fontWeight = FontWeight.Normal ) } } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CongratulationDialog.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CongratulationDialog.kt index f37dff2..2ba719e 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CongratulationDialog.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CongratulationDialog.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.presentation.component import android.content.Intent @@ -5,7 +20,15 @@ import android.widget.Toast import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +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.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Card import androidx.compose.material.Text @@ -28,28 +51,28 @@ import com.brandyodhiambo.designsystem.theme.primaryColor @Composable fun CongratulationsDialog( - openDialogCustom: MutableState, + openDialogCustom: MutableState ) { val context = LocalContext.current Card( modifier = Modifier.padding(10.dp, 5.dp, 10.dp, 10.dp), shape = RoundedCornerShape(12.dp), - elevation = 8.dp, + elevation = 8.dp ) { Column( - modifier = Modifier.fillMaxWidth(), + modifier = Modifier.fillMaxWidth() ) { Box( modifier = Modifier .fillMaxWidth() - .height(300.dp), + .height(300.dp) ) { Image( modifier = Modifier .fillMaxWidth() .height(300.dp), painter = painterResource(id = R.drawable.congratulations), - contentDescription = null, + contentDescription = null ) } Text( @@ -58,20 +81,20 @@ fun CongratulationsDialog( modifier = Modifier .fillMaxWidth(), maxLines = 2, - overflow = TextOverflow.Ellipsis, + overflow = TextOverflow.Ellipsis ) Spacer(modifier = Modifier.height(8.dp)) Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceEvenly, + horizontalArrangement = Arrangement.SpaceEvenly ) { Image( painter = painterResource(id = R.drawable.facebook), contentDescription = null, contentScale = ContentScale.Fit, colorFilter = ColorFilter.tint( - color = primaryColor, + color = primaryColor ), modifier = Modifier .width(50.dp) @@ -86,11 +109,11 @@ fun CongratulationsDialog( .makeText( context, "Facebook is not installed", - Toast.LENGTH_SHORT, + Toast.LENGTH_SHORT ) .show() } - }, + } ) Image( @@ -98,7 +121,7 @@ fun CongratulationsDialog( contentDescription = null, contentScale = ContentScale.Fit, colorFilter = ColorFilter.tint( - color = primaryColor, + color = primaryColor ), modifier = Modifier .width(50.dp) @@ -113,11 +136,11 @@ fun CongratulationsDialog( .makeText( context, "Twitter is not installed", - Toast.LENGTH_SHORT, + Toast.LENGTH_SHORT ) .show() } - }, + } ) Image( @@ -137,11 +160,11 @@ fun CongratulationsDialog( .makeText( context, "Whatsapp is not installed", - Toast.LENGTH_SHORT, + Toast.LENGTH_SHORT ) .show() } - }, + } ) @@ -157,11 +180,11 @@ fun CongratulationsDialog( sendIntent.action = Intent.ACTION_SEND sendIntent.putExtra( Intent.EXTRA_TEXT, - "Quench App", + "Quench App" ) sendIntent.type = "text/plain" context.startActivity(sendIntent) - }, + } ) } @@ -171,7 +194,7 @@ fun CongratulationsDialog( .fillMaxWidth() .padding(top = 10.dp) .background(Color.White), - horizontalArrangement = Arrangement.SpaceAround, + horizontalArrangement = Arrangement.SpaceAround ) { TextButton(onClick = { openDialogCustom.value = false @@ -180,7 +203,7 @@ fun CongratulationsDialog( "Cancel", fontWeight = FontWeight.Bold, color = Color.Black, - modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), + modifier = Modifier.padding(top = 5.dp, bottom = 5.dp) ) } TextButton(onClick = { @@ -190,7 +213,7 @@ fun CongratulationsDialog( "Okay", fontWeight = FontWeight.ExtraBold, color = primaryColor, - modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), + modifier = Modifier.padding(top = 5.dp, bottom = 5.dp) ) } } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/DeleteDialog.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/DeleteDialog.kt index 06c47e5..d76ecb3 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/DeleteDialog.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/DeleteDialog.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.presentation.component import androidx.compose.foundation.layout.fillMaxWidth @@ -20,7 +35,7 @@ import com.brandyodhiambo.designsystem.theme.roboto fun DeleteDialog( id: Int, onDismiss: () -> Unit, - onConfirmClick: (Int) -> Unit, + onConfirmClick: (Int) -> Unit ) { AlertDialog( backgroundColor = Color.White, @@ -30,7 +45,7 @@ fun DeleteDialog( text = "Delete Drink", textAlign = TextAlign.Center, fontSize = 20.sp, - fontFamily = roboto, + fontFamily = roboto ) }, text = { @@ -38,7 +53,7 @@ fun DeleteDialog( color = blackColor, modifier = Modifier .fillMaxWidth() - .padding(top = 5.dp, bottom = 5.dp), + .padding(top = 5.dp, bottom = 5.dp) ) Text( "Are you sure you want to delete this drink?", @@ -47,7 +62,7 @@ fun DeleteDialog( color = blackColor, modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), textAlign = TextAlign.Center, - fontSize = 16.sp, + fontSize = 16.sp ) }, confirmButton = { @@ -59,7 +74,7 @@ fun DeleteDialog( fontWeight = FontWeight.Bold, fontFamily = roboto, color = Color.Black, - modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), + modifier = Modifier.padding(top = 5.dp, bottom = 5.dp) ) } }, @@ -72,9 +87,9 @@ fun DeleteDialog( fontWeight = FontWeight.Bold, fontFamily = roboto, color = Color.Black, - modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), + modifier = Modifier.padding(top = 5.dp, bottom = 5.dp) ) } - }, + } ) } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/EmptyDialog.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/EmptyDialog.kt index 3dd6c4b..783fef5 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/EmptyDialog.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/EmptyDialog.kt @@ -1,6 +1,20 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.presentation.component - import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.AlertDialog @@ -20,7 +34,7 @@ import com.brandyodhiambo.designsystem.theme.roboto @Composable fun EmptyDialog( onDismiss: () -> Unit, - onConfirmClick: () -> Unit, + onConfirmClick: () -> Unit ) { AlertDialog( backgroundColor = Color.White, @@ -30,7 +44,7 @@ fun EmptyDialog( text = "No Drinks", textAlign = TextAlign.Center, fontSize = 20.sp, - fontFamily = roboto, + fontFamily = roboto ) }, text = { @@ -38,7 +52,7 @@ fun EmptyDialog( color = blackColor, modifier = Modifier .fillMaxWidth() - .padding(top = 5.dp, bottom = 5.dp), + .padding(top = 5.dp, bottom = 5.dp) ) Text( "You have no drinks in your list. Add a drink to get started.", @@ -47,7 +61,7 @@ fun EmptyDialog( color = blackColor, modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), textAlign = TextAlign.Center, - fontSize = 16.sp, + fontSize = 16.sp ) }, confirmButton = { @@ -59,7 +73,7 @@ fun EmptyDialog( fontWeight = FontWeight.Bold, fontFamily = roboto, color = Color.Black, - modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), + modifier = Modifier.padding(top = 5.dp, bottom = 5.dp) ) } }, @@ -72,9 +86,9 @@ fun EmptyDialog( fontWeight = FontWeight.Bold, fontFamily = roboto, color = Color.Black, - modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), + modifier = Modifier.padding(top = 5.dp, bottom = 5.dp) ) } - }, + } ) } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/IdealIntakeGoalDialog.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/IdealIntakeGoalDialog.kt index 378ec2f..d12decb 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/IdealIntakeGoalDialog.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/IdealIntakeGoalDialog.kt @@ -1,12 +1,46 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.presentation.component import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +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.foundation.text.KeyboardOptions -import androidx.compose.material.* -import androidx.compose.runtime.* +import androidx.compose.material.Card +import androidx.compose.material.DropdownMenuItem +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ExposedDropdownMenuBox +import androidx.compose.material.ExposedDropdownMenuDefaults +import androidx.compose.material.OutlinedTextField +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.material.TextFieldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color.Companion.Gray @@ -28,8 +62,8 @@ import com.brandyodhiambo.designsystem.theme.primaryColor fun IdealIntakeGoalDialog( modifier: Modifier = Modifier, idealCustomDialog: MutableState, - currentIdealIntakeText:String, - currentIdealIntakeFormText:String, + currentIdealIntakeText: String, + currentIdealIntakeFormText: String, onCurrentIdealIntakeFormTextChange: (String) -> Unit, onCurrentIdealIntakeTextChange: (String) -> Unit, onOkayClick: () -> Unit @@ -76,7 +110,6 @@ fun IdealIntakeGoalDialog( .padding(top = 10.dp), horizontalArrangement = Arrangement.SpaceBetween ) { - OutlinedTextField( modifier = Modifier .fillMaxWidth(0.5f) @@ -99,7 +132,7 @@ fun IdealIntakeGoalDialog( "2810", color = Gray ) - }, + } ) val options = listOf("ml", "l") diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/SelectDrinkDialog.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/SelectDrinkDialog.kt index 91aa740..8a69e10 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/SelectDrinkDialog.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/SelectDrinkDialog.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.presentation.component import android.os.Build @@ -51,44 +66,44 @@ import java.time.format.DateTimeFormatter val selectedDrinks = listOf( SelectDrink( icon = R.drawable.small_cup, - size = "300ml", + size = "300ml" ), SelectDrink( icon = R.drawable.small_cup, - size = "350ml", + size = "350ml" ), SelectDrink( icon = R.drawable.small_glass, - size = "400ml", + size = "400ml" ), SelectDrink( icon = R.drawable.ic_glass, - size = "450ml", + size = "450ml" ), SelectDrink( icon = R.drawable.ic_cup, - size = "500ml", + size = "500ml" ), SelectDrink( icon = R.drawable.big_cup, - size = "550ml", + size = "550ml" ), SelectDrink( icon = R.drawable.kettle, - size = "600ml", + size = "600ml" ), SelectDrink( icon = R.drawable.big_cup, - size = "650ml", + size = "650ml" ), SelectDrink( icon = R.drawable.kettle, - size = "700ml", + size = "700ml" ), SelectDrink( icon = R.drawable.kettle, - size = "1000ml", - ), + size = "1000ml" + ) ) @RequiresApi(Build.VERSION_CODES.O) @@ -99,18 +114,18 @@ fun SelectDrinkComposable( onCurrentSelectedDrinkTime: (String) -> Unit, onCurrentSelectedDrinkSize: (String) -> Unit, onCurrentSelectedDrinkIcon: (Int) -> Unit, - onClick: () -> Unit, + onClick: () -> Unit ) { val openTimeDialog = rememberMaterialDialogState() Card( shape = RoundedCornerShape(10.dp), modifier = Modifier.padding(10.dp, 5.dp, 5.dp, 5.dp), - elevation = 8.dp, + elevation = 8.dp ) { Column( modifier .background(Color.White) - .padding(8.dp), + .padding(8.dp) ) { Text( text = "Select Drink", @@ -121,7 +136,7 @@ fun SelectDrinkComposable( maxLines = 2, fontSize = 20.sp, fontWeight = FontWeight.W500, - overflow = TextOverflow.Ellipsis, + overflow = TextOverflow.Ellipsis ) Spacer(modifier = Modifier.height(12.dp)) LazyVerticalGrid(columns = GridCells.Fixed(count = 4)) { @@ -131,7 +146,7 @@ fun SelectDrinkComposable( openTimeDialog = openTimeDialog, onCurrentSelectedDrinkTime = onCurrentSelectedDrinkTime, onCurrentSelectedDrinkSize = onCurrentSelectedDrinkSize, - onCurrentSelectedDrinkIcon = onCurrentSelectedDrinkIcon, + onCurrentSelectedDrinkIcon = onCurrentSelectedDrinkIcon ) } } @@ -141,7 +156,7 @@ fun SelectDrinkComposable( .fillMaxWidth() .padding(top = 10.dp) .background(Color.White), - horizontalArrangement = Arrangement.SpaceAround, + horizontalArrangement = Arrangement.SpaceAround ) { TextButton(onClick = { openDialog.value = false @@ -150,7 +165,7 @@ fun SelectDrinkComposable( "Cancel", fontWeight = FontWeight.Bold, color = Color.Black, - modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), + modifier = Modifier.padding(top = 5.dp, bottom = 5.dp) ) } TextButton(onClick = { @@ -161,7 +176,7 @@ fun SelectDrinkComposable( "Okay", fontWeight = FontWeight.ExtraBold, color = primaryColor, - modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), + modifier = Modifier.padding(top = 5.dp, bottom = 5.dp) ) } } @@ -176,7 +191,7 @@ fun SelectCard( openTimeDialog: MaterialDialogState, onCurrentSelectedDrinkSize: (String) -> Unit, onCurrentSelectedDrinkIcon: (Int) -> Unit, - onCurrentSelectedDrinkTime: (String) -> Unit, + onCurrentSelectedDrinkTime: (String) -> Unit ) { Column( horizontalAlignment = Alignment.CenterHorizontally, @@ -184,18 +199,18 @@ fun SelectCard( openTimeDialog.show() onCurrentSelectedDrinkIcon(selectDrink.icon) onCurrentSelectedDrinkSize(selectDrink.size) - }, + } ) { Image( painter = painterResource(id = selectDrink.icon), contentDescription = null, contentScale = ContentScale.Fit, colorFilter = ColorFilter.tint( - color = primaryColor, + color = primaryColor ), modifier = Modifier .padding(top = 8.dp) - .height(20.dp), + .height(20.dp) ) Spacer(modifier = Modifier.height(8.dp)) Text( @@ -205,12 +220,12 @@ fun SelectCard( maxLines = 2, fontSize = 14.sp, fontWeight = FontWeight.W300, - overflow = TextOverflow.Ellipsis, + overflow = TextOverflow.Ellipsis ) if (openTimeDialog.showing) { TimeDialog( openDialog = openTimeDialog, - onCurrentSelectedDrinkTime = onCurrentSelectedDrinkTime, + onCurrentSelectedDrinkTime = onCurrentSelectedDrinkTime ) } } @@ -220,7 +235,7 @@ fun SelectCard( @Composable fun TimeDialog( onCurrentSelectedDrinkTime: (String) -> Unit, - openDialog: MaterialDialogState, + openDialog: MaterialDialogState ) { var pickedTime by remember { mutableStateOf(LocalTime.MAX) @@ -233,7 +248,7 @@ fun TimeDialog( onCurrentSelectedDrinkTime(pickedTime.format(DateTimeFormatter.ofPattern("HH:mm a"))) } negativeButton(text = "Cancel", textStyle = TextStyle(color = primaryColor)) - }, + } ) { timepicker( initialTime = pickedTime, @@ -246,8 +261,8 @@ fun TimeDialog( activeBackgroundColor = primaryColor, activeTextColor = Color.White, inactiveBackgroundColor = Color.White, - inactiveTextColor = Color.Black, - ), + inactiveTextColor = Color.Black + ) ) { pickedTime = it } @@ -256,5 +271,5 @@ fun TimeDialog( data class SelectDrink( val size: String, - val icon: Int, + val icon: Int ) diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/TimeSetterDialog.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/TimeSetterDialog.kt index d29513e..c30334b 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/TimeSetterDialog.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/TimeSetterDialog.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.presentation.component import androidx.compose.foundation.BorderStroke @@ -47,7 +62,7 @@ fun TimeSetterDialog( onCurrentPickerValueChanged: (Hours) -> Unit, onDismiss: () -> Unit, onAllDayClicked: () -> Unit, - onConfirmClick: () -> Unit, + onConfirmClick: () -> Unit ) { AlertDialog( backgroundColor = Color.White, @@ -58,12 +73,12 @@ fun TimeSetterDialog( contentDescription = null, contentScale = ContentScale.Fit, colorFilter = ColorFilter.tint( - color = primaryColor, + color = primaryColor ), modifier = Modifier .padding(top = 35.dp) .height(70.dp) - .fillMaxWidth(), + .fillMaxWidth() ) }, @@ -77,21 +92,21 @@ fun TimeSetterDialog( .fillMaxWidth(), maxLines = 2, overflow = TextOverflow.Ellipsis, - fontFamily = roboto, + fontFamily = roboto ) Spacer(modifier = Modifier.height(8.dp)) TimePickerForDialogInHours( currentPickerValueText = currentPickerValueText, onPickerValueChange = { onCurrentPickerValueChanged(it) - }, + } ) Row( Modifier .fillMaxWidth() .padding(top = 10.dp), horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = "Reminder Time", @@ -101,7 +116,7 @@ fun TimeSetterDialog( .padding(top = 5.dp), fontWeight = FontWeight.Bold, maxLines = 2, - overflow = TextOverflow.Ellipsis, + overflow = TextOverflow.Ellipsis ) TextButton(onClick = { onAllDayClicked() @@ -115,14 +130,14 @@ fun TimeSetterDialog( .padding(top = 5.dp), fontWeight = FontWeight.W100, maxLines = 2, - overflow = TextOverflow.Ellipsis, + overflow = TextOverflow.Ellipsis ) } } Spacer(modifier = Modifier.height(8.dp)) LazyRow( verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp) ) { items(reminderDays) { singleDay -> DayItem( @@ -131,7 +146,7 @@ fun TimeSetterDialog( onClick = { singleDay.isSelected = !singleDay.isSelected // get the selected day and add it to the list - }, + } ) } } @@ -146,7 +161,7 @@ fun TimeSetterDialog( fontWeight = FontWeight.Bold, fontFamily = roboto, color = Color.Black, - modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), + modifier = Modifier.padding(top = 5.dp, bottom = 5.dp) ) } }, @@ -159,17 +174,17 @@ fun TimeSetterDialog( fontWeight = FontWeight.Bold, fontFamily = roboto, color = Color.Black, - modifier = Modifier.padding(top = 5.dp, bottom = 5.dp), + modifier = Modifier.padding(top = 5.dp, bottom = 5.dp) ) } - }, + } ) } @Composable fun TimePickerForDialogInHours( currentPickerValueText: Hours, - onPickerValueChange: (Hours) -> Unit, + onPickerValueChange: (Hours) -> Unit ) { HoursNumberPicker( dividersColor = blackColor, @@ -182,16 +197,16 @@ fun TimePickerForDialogInHours( Text( modifier = Modifier.padding(horizontal = 8.dp), textAlign = TextAlign.Center, - text = ":", + text = ":" ) }, minutesDivider = { Text( modifier = Modifier.padding(horizontal = 8.dp), textAlign = TextAlign.Center, - text = " ", + text = " " ) - }, + } ) } @@ -206,11 +221,11 @@ fun DayItem(color: Color, text: String, onClick: () -> Unit = {}) { .clickable { onClick() }, - elevation = 8.dp, + elevation = 8.dp ) { Column( horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, + verticalArrangement = Arrangement.Center ) { Text( text = text, @@ -218,7 +233,7 @@ fun DayItem(color: Color, text: String, onClick: () -> Unit = {}) { color = color, fontSize = 14.sp, fontFamily = roboto, - fontWeight = FontWeight.Bold, + fontWeight = FontWeight.Bold ) } } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/WaterProgress.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/WaterProgress.kt index eac5435..f0fe15e 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/WaterProgress.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/WaterProgress.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.presentation.component import android.graphics.Paint @@ -63,4 +78,4 @@ fun WaterProgress(progress: Float, modifier: Modifier = Modifier) { textPaint ) } -} \ No newline at end of file +} diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/home_screen/HomeScreen.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt similarity index 85% rename from feature/home/src/main/java/com/brandyodhiambo/home/presentation/home_screen/HomeScreen.kt rename to feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt index 2795286..c371f4e 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/home_screen/HomeScreen.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt @@ -1,13 +1,44 @@ -package com.brandyodhiambo.home.presentation.home_screen +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.brandyodhiambo.home.presentation.homeScreen import android.annotation.SuppressLint import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.* +import androidx.compose.material.Card +import androidx.compose.material.Divider +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Scaffold +import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete import androidx.compose.runtime.Composable @@ -50,7 +81,7 @@ import com.ramcosta.composedestinations.annotation.Destination @Destination @Composable fun HomeScreen( - viewModel: HomeViewModel = hiltViewModel(), + viewModel: HomeViewModel = hiltViewModel() ) { val openTimeDialog = remember { mutableStateOf(false) } val openDeleteDialog = remember { mutableStateOf(false) } @@ -78,12 +109,12 @@ fun HomeScreen( val minute = reminderTimeFromDb.value?.minute Scaffold( - backgroundColor = primaryColor, + backgroundColor = primaryColor ) { paddingValues -> Box( modifier = Modifier .fillMaxSize() - .padding(paddingValues), + .padding(paddingValues) ) { LazyColumn { item { @@ -93,7 +124,7 @@ fun HomeScreen( waterIntake = waterIntake, form = waterIntakeForm, goalForm = goalForm, - goalWaterIntake = goalWaterIntake, + goalWaterIntake = goalWaterIntake ) } item { @@ -112,16 +143,16 @@ fun HomeScreen( val (amount, taken) = incrementProgressCircle( selectedDrinksFromDB = selectedDrinksFromDB, goalWaterIntake = goalWaterIntake, - viewModel = viewModel, + viewModel = viewModel ) viewModel.deleteAllLevels() viewModel.insertLevel( Level( amountTaken = amount, - waterTaken = taken, - ), + waterTaken = taken + ) ) - }, + } ) } item { @@ -138,13 +169,14 @@ fun HomeScreen( } } - if(openEmptyStateDialog.value){ + if (openEmptyStateDialog.value) { Dialog(onDismissRequest = { openEmptyStateDialog.value = false }) { EmptyDialog( onConfirmClick = { openEmptyStateDialog.value = false - selectedDrinkDialog.value = true }, - onDismiss = { openEmptyStateDialog.value = false }, + selectedDrinkDialog.value = true + }, + onDismiss = { openEmptyStateDialog.value = false } ) } } @@ -157,13 +189,14 @@ fun HomeScreen( onConfirmClick = { id -> viewModel.deleteOneSelectedDrink(id) openDeleteDialog.value = false - }, + } ) } } if ((waterTaken >= goalWaterIntake) && (goalWaterIntake != 0)) { openCongratulationsDialog.value = true + } if (openCongratulationsDialog.value) { @@ -183,7 +216,7 @@ fun HomeScreen( }, onAllDayClicked = { viewModel.onAllDaySelected( - isAllDay = true, + isAllDay = true ) viewModel.reminderDays.value = listOf( Days("M", viewModel.isAllDaySelected.value), @@ -192,7 +225,7 @@ fun HomeScreen( Days("T", viewModel.isAllDaySelected.value), Days("F", viewModel.isAllDaySelected.value), Days("S", viewModel.isAllDaySelected.value), - Days("S", viewModel.isAllDaySelected.value), + Days("S", viewModel.isAllDaySelected.value) ) }, onConfirmClick = { @@ -209,7 +242,7 @@ fun HomeScreen( amPm = ampm, isReapeated = false, isAllDay = viewModel.isAllDaySelected.value, - days = viewModel.reminderDays.value, + days = viewModel.reminderDays.value ) if (viewModel.reminderTime.value != null) { viewModel.deleteAllRemindTime() @@ -221,10 +254,10 @@ fun HomeScreen( ampm = viewModel.reminderSelectedTime.value.ampm, isRepeated = false, isAllDay = viewModel.isAllDaySelected.value, - days = viewModel.reminderDays.value, - ), + days = viewModel.reminderDays.value + ) ) - }, + } ) } } @@ -244,10 +277,10 @@ fun HomeScreen( onOkayClick = { val goalWaterIntakeToInsert = GoalWaterIntake( waterIntake = viewModel.goalWaterIntakeValue.value.toInt(), - form = viewModel.goalWaterForm.value, + form = viewModel.goalWaterForm.value ) viewModel.insertGoalWaterIntake(goalWaterIntakeToInsert) - }, + } ) } } @@ -267,10 +300,10 @@ fun HomeScreen( onOkayClick = { val idealWaterIntakeToInsert = IdealWaterIntake( waterIntake = viewModel.idealWaterIntakeValue.value.toInt(), - form = viewModel.idealWaterForm.value, + form = viewModel.idealWaterForm.value ) viewModel.insertIdealWaterIntake(idealWaterIntakeToInsert) - }, + } ) } } @@ -293,10 +326,10 @@ fun HomeScreen( SelectedDrink( drinkValue = viewModel.size.value, icon = viewModel.selectedIcon.value, - time = viewModel.selectedTime.value, - ), + time = viewModel.selectedTime.value + ) ) - }, + } ) } } @@ -307,7 +340,7 @@ fun HomeScreen( private fun incrementProgressCircle( selectedDrinksFromDB: State>, goalWaterIntake: Int, - viewModel: HomeViewModel, + viewModel: HomeViewModel ): Pair { // getting the last selected drink var amountTaken = viewModel.levelFromDB.value?.amountTaken ?: 0f @@ -355,49 +388,49 @@ fun WaterIntake( waterIntake: Int, form: String, goalForm: String, - goalWaterIntake: Int, + goalWaterIntake: Int ) { Card( modifier = Modifier .height(100.dp) .padding(16.dp) .fillMaxWidth(), - elevation = 4.dp, + elevation = 4.dp ) { Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), horizontalArrangement = Arrangement.SpaceEvenly, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Image( painter = painterResource(id = R.drawable.ic_glass), - contentDescription = null, + contentDescription = null ) Spacer(modifier = Modifier.width(8.dp)) Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.clickable { idealWaterIntakeDialog.value = true - }, + } ) { Text( text = "Ideal water intake", fontSize = 14.sp, color = Color.Gray, - fontFamily = roboto, + fontFamily = roboto ) Text( text = "$waterIntake $form", fontSize = 16.sp, color = Color.Gray, fontWeight = FontWeight.Bold, - fontFamily = roboto, + fontFamily = roboto ) } } @@ -406,11 +439,11 @@ fun WaterIntake( .fillMaxHeight() .width(2.dp), thickness = 2.dp, - color = primaryColor, + color = primaryColor ) Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Image(painter = painterResource(id = R.drawable.ic_cup), contentDescription = null) Spacer(modifier = Modifier.width(8.dp)) @@ -418,20 +451,20 @@ fun WaterIntake( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.clickable { openGoalDialog.value = true - }, + } ) { Text( text = "Water intake goal", fontSize = 14.sp, color = Color.Gray, - fontFamily = roboto, + fontFamily = roboto ) Text( text = "$goalWaterIntake $goalForm", fontSize = 16.sp, color = Color.Gray, fontWeight = FontWeight.Bold, - fontFamily = roboto, + fontFamily = roboto ) } } @@ -447,32 +480,32 @@ fun WaterRecord( time: String, goalWaterIntake: Int, selectedDrinkDialog: MutableState, - onAddLevelClick: () -> Unit, + onAddLevelClick: () -> Unit ) { Card( modifier = Modifier .fillMaxWidth() .height(350.dp) .padding(start = 16.dp, end = 16.dp), - elevation = 4.dp, + elevation = 4.dp ) { Column( modifier = Modifier .fillMaxSize() .padding(8.dp), - horizontalAlignment = Alignment.CenterHorizontally, + horizontalAlignment = Alignment.CenterHorizontally ) { Spacer(modifier = Modifier.height(8.dp)) CircularRating( percentage = amountTaken, drunk = waterTaken, - goal = goalWaterIntake, + goal = goalWaterIntake ) Spacer(modifier = Modifier.height(8.dp)) Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceEvenly, + horizontalArrangement = Arrangement.SpaceEvenly ) { CircularButton( backgroundColor = lightBlue, @@ -480,7 +513,7 @@ fun WaterRecord( title = time, onClick = { openDialog.value = true - }, + } ) CircularButton( backgroundColor = lightBlue, @@ -488,7 +521,7 @@ fun WaterRecord( title = "Add Level", onClick = { onAddLevelClick() - }, + } ) CircularButton( backgroundColor = lightBlue, @@ -496,7 +529,7 @@ fun WaterRecord( title = "Add Drink", onClick = { selectedDrinkDialog.value = true - }, + } ) } } @@ -506,13 +539,13 @@ fun WaterRecord( @Composable fun WaterIntakeTimeAndLevel( intake: SelectedDrink, - onDeleteIconClick: (SelectedDrink) -> Unit, + onDeleteIconClick: (SelectedDrink) -> Unit ) { Column( modifier = Modifier .fillMaxSize() .padding(start = 16.dp, end = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, + horizontalAlignment = Alignment.CenterHorizontally ) { Row( modifier = Modifier @@ -520,48 +553,48 @@ fun WaterIntakeTimeAndLevel( .background(Color.White) .padding(4.dp), horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Row( horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Icon( modifier = Modifier.size(20.dp), painter = painterResource(id = intake.icon), tint = primaryColor, - contentDescription = null, + contentDescription = null ) Text( text = intake.drinkValue, fontFamily = roboto, fontSize = 16.sp, - fontWeight = FontWeight.W400, + fontWeight = FontWeight.W400 ) } Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = intake.time, fontSize = 14.sp, color = Color.Gray, fontFamily = roboto, - fontWeight = FontWeight.W300, + fontWeight = FontWeight.W300 ) IconButton(onClick = { onDeleteIconClick(intake) }) { Icon( imageVector = Icons.Default.Delete, tint = Color.Gray, - contentDescription = null, + contentDescription = null ) } } } Divider( thickness = 1.dp, - color = Color.Gray, + color = Color.Gray ) } } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/home_screen/HomeViewModel.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeViewModel.kt similarity index 87% rename from feature/home/src/main/java/com/brandyodhiambo/home/presentation/home_screen/HomeViewModel.kt rename to feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeViewModel.kt index 698d696..9ce837b 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/home_screen/HomeViewModel.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeViewModel.kt @@ -1,4 +1,19 @@ -package com.brandyodhiambo.home.presentation.home_screen +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.brandyodhiambo.home.presentation.homeScreen import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -28,12 +43,12 @@ class HomeViewModel @Inject constructor( private val goalWaterIntakeRepository: GoalWaterIntakeRepository, private val selectedDrinkRepository: SelectedDrinkRepository, private val levelRepository: LevelRepository, - private val reminderTimeRepository: ReminderTimeRepository, + private val reminderTimeRepository: ReminderTimeRepository ) : ViewModel() { /* - * ideal water intake value and functions - * */ + * ideal water intake value and functions + * */ private val _idealWaterIntake = mutableStateOf("500") var idealWaterIntakeValue: State = _idealWaterIntake fun setIdealWaterIntakeValue(value: String) { @@ -60,8 +75,8 @@ class HomeViewModel @Inject constructor( } /* - * Goal Water intake values and functions - * */ + * Goal Water intake values and functions + * */ private val _goalWaterIntake = mutableStateOf("2080") var goalWaterIntakeValue: State = _goalWaterIntake fun setGoalWaterIntakeValue(value: String) { @@ -88,8 +103,8 @@ class HomeViewModel @Inject constructor( } /* - * Selected drink values and functions - * */ + * Selected drink values and functions + * */ private val _size = mutableStateOf("0") var size: State = _size fun setSize(value: String) { @@ -129,8 +144,8 @@ class HomeViewModel @Inject constructor( } /* - * Level values and functions - * */ + * Level values and functions + * */ private val _amountTaken = mutableStateOf(0f) var amountTaken: State = _amountTaken @@ -171,8 +186,8 @@ class HomeViewModel @Inject constructor( } /* - * Reminder Time - * */ + * Reminder Time + * */ private val _reminderTimePickerValue = mutableStateOf(AMPMHours(0, 0, AMPMHours.DayTime.AM)) val reminderTimePickerValue: MutableState = _reminderTimePickerValue @@ -198,7 +213,7 @@ class HomeViewModel @Inject constructor( amPm: String, isReapeated: Boolean, isAllDay: Boolean, - days: List, + days: List ) { _reminderSelectedTime.value = ReminderTime( hour = hours, @@ -206,7 +221,7 @@ class HomeViewModel @Inject constructor( ampm = amPm, isRepeated = isReapeated, isAllDay = isAllDay, - days = days, + days = days ) } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleep_wake_screen/SleepAndWakeUpScreen.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleepWakeScreen/SleepAndWakeUpScreen.kt similarity index 82% rename from feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleep_wake_screen/SleepAndWakeUpScreen.kt rename to feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleepWakeScreen/SleepAndWakeUpScreen.kt index 367c892..32ea2cd 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleep_wake_screen/SleepAndWakeUpScreen.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleepWakeScreen/SleepAndWakeUpScreen.kt @@ -1,4 +1,19 @@ -package com.brandyodhiambo.home.presentation.sleep_wake_screen +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.brandyodhiambo.home.presentation.sleepWakeScreen import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -37,23 +52,23 @@ interface SleepAndWakeUpScreenScreenNavigator { @Composable fun SleepAndWakeTimeScreen( navigator: SleepAndWakeUpScreenScreenNavigator, - viewModel: SleepWakeViewModel = hiltViewModel(), + viewModel: SleepWakeViewModel = hiltViewModel() ) { Box( - modifier = Modifier.fillMaxSize(), + modifier = Modifier.fillMaxSize() ) { Column( modifier = Modifier .fillMaxSize() .padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Top, + verticalArrangement = Arrangement.Top ) { Spacer(modifier = Modifier.height(16.dp)) Text( text = "What's your wake up time?", fontSize = 24.sp, - color = blackColor, + color = blackColor ) Spacer(modifier = Modifier.height(16.dp)) WakeTimePickerInHours( @@ -67,14 +82,14 @@ fun SleepAndWakeTimeScreen( "PM" } viewModel.onTimeWakeSelected(it.hours, it.minutes, ampm) - }, + } ) Spacer(modifier = Modifier.height(32.dp)) Text( text = "What's your Sleeping time?", fontSize = 24.sp, - color = blackColor, + color = blackColor ) Spacer(modifier = Modifier.height(16.dp)) SleepTimePickerInHours( @@ -90,7 +105,7 @@ fun SleepAndWakeTimeScreen( "PM" } viewModel.onTimeSleepSelected(it.hours, it.minutes, ampm) - }, + } ) Spacer(modifier = Modifier.height(32.dp)) @@ -99,7 +114,7 @@ fun SleepAndWakeTimeScreen( modifier = Modifier .fillMaxSize() .padding(bottom = 16.dp, start = 16.dp, end = 16.dp), - verticalArrangement = Arrangement.Bottom, + verticalArrangement = Arrangement.Bottom ) { Button( modifier = Modifier @@ -109,23 +124,23 @@ fun SleepAndWakeTimeScreen( SleepTime( viewModel.sleepSelectedTime.value.hours, viewModel.sleepSelectedTime.value.minutes, - viewModel.sleepSelectedTime.value.amPm, - ), + viewModel.sleepSelectedTime.value.amPm + ) ) viewModel.insertWakeTime( WakeTime( viewModel.wakeSelectedTime.value.hours, viewModel.wakeSelectedTime.value.minutes, - viewModel.wakeSelectedTime.value.amPm, - ), + viewModel.wakeSelectedTime.value.amPm + ) ) navigator.popBackStack() navigator.navigateToMainScreen() }, shape = RoundedCornerShape(15.dp), - colors = ButtonDefaults.buttonColors(backgroundColor = primaryColor), + colors = ButtonDefaults.buttonColors(backgroundColor = primaryColor) ) { Text(text = "Next", Modifier.padding(8.dp), color = Color.White) } @@ -137,7 +152,7 @@ fun SleepAndWakeTimeScreen( fun SleepTimePickerInHours( currentPickerValueText: Hours, onCurrentPickerValueTextChange: (Hours) -> Unit, - onTimeSleepSelected: (Hours) -> Unit, + onTimeSleepSelected: (Hours) -> Unit ) { HoursNumberPicker( dividersColor = blackColor, @@ -151,16 +166,16 @@ fun SleepTimePickerInHours( Text( modifier = Modifier.padding(horizontal = 8.dp), textAlign = TextAlign.Center, - text = ":", + text = ":" ) }, minutesDivider = { Text( modifier = Modifier.padding(horizontal = 8.dp), textAlign = TextAlign.Center, - text = " ", + text = " " ) - }, + } ) } @@ -168,7 +183,7 @@ fun SleepTimePickerInHours( fun WakeTimePickerInHours( currentPickerValueText: Hours, onCurrentPickerValueTextChange: (Hours) -> Unit, - onTimeWakeSelected: (Hours) -> Unit, + onTimeWakeSelected: (Hours) -> Unit ) { HoursNumberPicker( dividersColor = blackColor, @@ -182,15 +197,15 @@ fun WakeTimePickerInHours( Text( modifier = Modifier.padding(horizontal = 8.dp), textAlign = TextAlign.Center, - text = ":", + text = ":" ) }, minutesDivider = { Text( modifier = Modifier.padding(horizontal = 8.dp), textAlign = TextAlign.Center, - text = " ", + text = " " ) - }, + } ) } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleep_wake_screen/SleepWakeViewModel.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleepWakeScreen/SleepWakeViewModel.kt similarity index 81% rename from feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleep_wake_screen/SleepWakeViewModel.kt rename to feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleepWakeScreen/SleepWakeViewModel.kt index 109f0b6..3cd63dc 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleep_wake_screen/SleepWakeViewModel.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/sleepWakeScreen/SleepWakeViewModel.kt @@ -1,4 +1,19 @@ -package com.brandyodhiambo.home.presentation.sleep_wake_screen +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.brandyodhiambo.home.presentation.sleepWakeScreen import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf @@ -18,7 +33,7 @@ import javax.inject.Inject class SleepWakeViewModel @Inject constructor( private val sleepTimeRepository: SleepTimeRepository, private val wakeTimeRepository: WakeTimeRepository -):ViewModel() { +) : ViewModel() { private val _sleepTimePickerValue = mutableStateOf(AMPMHours(0, 0, AMPMHours.DayTime.AM)) val sleepTimePickerValue: MutableState = _sleepTimePickerValue @@ -90,7 +105,4 @@ class SleepWakeViewModel @Inject constructor( wakeTimeRepository.dellAllWakeTimes() } } - - - -} \ No newline at end of file +} diff --git a/feature/home/src/main/res/font/demo.xml b/feature/home/src/main/res/font/demo.xml index 8f51456..5811f8c 100644 --- a/feature/home/src/main/res/font/demo.xml +++ b/feature/home/src/main/res/font/demo.xml @@ -1,4 +1,4 @@ - \ No newline at end of file + diff --git a/feature/home/src/test/java/com/brandyodhiambo/home/ExampleUnitTest.kt b/feature/home/src/test/java/com/brandyodhiambo/home/ExampleUnitTest.kt index 66c53b4..e060358 100644 --- a/feature/home/src/test/java/com/brandyodhiambo/home/ExampleUnitTest.kt +++ b/feature/home/src/test/java/com/brandyodhiambo/home/ExampleUnitTest.kt @@ -1,9 +1,23 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home +import junit.framework.TestCase.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +28,4 @@ class ExampleUnitTest { fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/feature/settings/src/androidTest/java/com/brandyodhiambo/settings/ExampleInstrumentedTest.kt b/feature/settings/src/androidTest/java/com/brandyodhiambo/settings/ExampleInstrumentedTest.kt index 3cbc695..0ffef08 100644 --- a/feature/settings/src/androidTest/java/com/brandyodhiambo/settings/ExampleInstrumentedTest.kt +++ b/feature/settings/src/androidTest/java/com/brandyodhiambo/settings/ExampleInstrumentedTest.kt @@ -1,13 +1,26 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.settings -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import junit.framework.TestCase.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * @@ -21,4 +34,4 @@ class ExampleInstrumentedTest { val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.brandyodhiambo.settings.test", appContext.packageName) } -} \ No newline at end of file +} diff --git a/feature/settings/src/main/AndroidManifest.xml b/feature/settings/src/main/AndroidManifest.xml index a5918e6..8bdb7e1 100644 --- a/feature/settings/src/main/AndroidManifest.xml +++ b/feature/settings/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ - \ No newline at end of file + diff --git a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/AddReminderScreen.kt b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/AddReminderScreen.kt index 3a28dc2..7618361 100644 --- a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/AddReminderScreen.kt +++ b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/AddReminderScreen.kt @@ -1,11 +1,42 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.settings.presentation import android.annotation.SuppressLint -import androidx.compose.foundation.layout.* -import androidx.compose.material.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Scaffold +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* -import androidx.compose.runtime.* +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -24,12 +55,10 @@ import com.chargemap.compose.numberpicker.Hours import com.chargemap.compose.numberpicker.HoursNumberPicker import com.ramcosta.composedestinations.annotation.Destination - -interface AddReminderNavigator{ +interface AddReminderNavigator { fun navigateUp() } - @SuppressLint("UnusedMaterialScaffoldPaddingParameter") @Destination @Composable @@ -154,8 +183,6 @@ fun AddReminderScreen( ) } - - if (repeateModeDialog.value) { Dialog(onDismissRequest = { repeateModeDialog.value }) { val repeatMode = listOf("Once", "Mon to Fri", "Daily", "Custom") @@ -215,6 +242,5 @@ fun ReminderTimePickerInHours() { ) } ) - } } diff --git a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/NotificationScreen.kt b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/NotificationScreen.kt index 991fc9e..4589bb0 100644 --- a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/NotificationScreen.kt +++ b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/NotificationScreen.kt @@ -1,14 +1,45 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.settings.presentation import android.annotation.SuppressLint -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.* +import androidx.compose.material.Card +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Scaffold +import androidx.compose.material.Text +import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.ArrowBack @@ -30,7 +61,6 @@ interface NotificationNavigator { fun navigateToReminderScreen() fun popBackStack() - } @SuppressLint("UnusedMaterialScaffoldPaddingParameter") @@ -87,9 +117,9 @@ fun NotificationScreen( item { AddReminder(navigator = navigator) } - if(reminder.isEmpty()){ + if (reminder.isEmpty()) { item { - //Loader(compositions = R.raw.clock) + // Loader(compositions = R.raw.clock) } } else { items(reminder) { reminder -> @@ -225,7 +255,6 @@ fun WeeksReminder(day: Day, reminder: Reminder) { } } - data class Reminder( val time: String, val days: List, diff --git a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt index 508ba58..74cf640 100644 --- a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt +++ b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.settings.presentation import android.annotation.SuppressLint @@ -35,7 +50,7 @@ interface SettingsNavigator { @Destination @Composable fun SettingScreen( - navigator: SettingsNavigator, + navigator: SettingsNavigator ) { val openIntakeDialog = remember { mutableStateOf(false) } val openGenderDialog = remember { mutableStateOf(false) } @@ -44,25 +59,25 @@ fun SettingScreen( val openWeightUnitDialog = remember { mutableStateOf(false) } Scaffold( - backgroundColor = primaryColor, + backgroundColor = primaryColor ) { paddingValues -> Box( modifier = Modifier .fillMaxSize() - .padding(paddingValues), + .padding(paddingValues) ) { LazyColumn { item { UnitsWaterIntake( openTimeFormatDialog = openTimeDialog, openWaterUnitDialog = openWaterUnitDialog, - openWeightUnitDialog = openWeightUnitDialog, + openWeightUnitDialog = openWeightUnitDialog ) } item { Goals( openDialog = openIntakeDialog, - openGenderDialog = openGenderDialog, + openGenderDialog = openGenderDialog ) } item { @@ -82,7 +97,7 @@ fun SettingScreen( CustomReminderDialog( openDialog = openGenderDialog, items = gender, - title = "Gender", + title = "Gender" ) } } @@ -92,7 +107,7 @@ fun SettingScreen( CustomReminderDialog( openDialog = openTimeDialog, items = time, - title = "Time Format", + title = "Time Format" ) } } @@ -103,7 +118,7 @@ fun SettingScreen( CustomReminderDialog( openDialog = openWaterUnitDialog, items = waterUnit, - title = "Water Unit", + title = "Water Unit" ) } } @@ -114,7 +129,7 @@ fun SettingScreen( CustomReminderDialog( openDialog = openWeightUnitDialog, items = weightUnit, - title = "Weight Unit", + title = "Weight Unit" ) } } @@ -126,29 +141,29 @@ fun SettingScreen( fun UnitsWaterIntake( openTimeFormatDialog: MutableState, openWaterUnitDialog: MutableState, - openWeightUnitDialog: MutableState, + openWeightUnitDialog: MutableState ) { Card( modifier = Modifier .fillMaxWidth() .padding(top = 8.dp, start = 16.dp, end = 16.dp), - elevation = 4.dp, + elevation = 4.dp ) { Column( - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(8.dp) ) { Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Text( text = "Water Unit", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) TextButton(onClick = { openWaterUnitDialog.value = true }) { @@ -156,7 +171,7 @@ fun UnitsWaterIntake( text = "ml", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor, + color = primaryColor ) } } @@ -165,20 +180,20 @@ fun UnitsWaterIntake( .height(1.dp) .padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Text( text = "Weight Unit", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) TextButton(onClick = { openWeightUnitDialog.value = true }) { @@ -186,7 +201,7 @@ fun UnitsWaterIntake( text = "Kg", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor, + color = primaryColor ) } } @@ -195,27 +210,27 @@ fun UnitsWaterIntake( .height(1.dp) .padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Text( text = "Time Format", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) TextButton(onClick = { openTimeFormatDialog.value = true }) { Text( text = "12 hours", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor, + color = primaryColor ) } } @@ -230,33 +245,33 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { modifier = Modifier .fillMaxWidth() .padding(top = 8.dp, start = 16.dp, end = 16.dp, bottom = 16.dp), - elevation = 4.dp, + elevation = 4.dp ) { Column( - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(8.dp) ) { Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = "Reminder Mode", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } IconButton(onClick = { }) { Image( painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null, + contentDescription = null ) } } @@ -265,23 +280,23 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { .height(1.dp) .padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = "Reminder Sound", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } IconButton(onClick = { @@ -290,7 +305,7 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { }) { Image( painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null, + contentDescription = null ) } } @@ -299,23 +314,23 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { .height(1.dp) .padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = "Notifications", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } IconButton(onClick = { @@ -323,7 +338,7 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { }) { Image( painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null, + contentDescription = null ) } } @@ -334,32 +349,32 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { @Composable fun Goals( openDialog: MutableState, - openGenderDialog: MutableState, + openGenderDialog: MutableState ) { Card( modifier = Modifier .fillMaxWidth() .padding(top = 8.dp, start = 16.dp, end = 16.dp), - elevation = 4.dp, + elevation = 4.dp ) { Column( - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(8.dp) ) { Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = "Gender", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } Row( @@ -367,17 +382,17 @@ fun Goals( horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.clickable { openGenderDialog.value = true - }, + } ) { Text( text = "Male", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor, + color = primaryColor ) Image( painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null, + contentDescription = null ) } } @@ -386,23 +401,23 @@ fun Goals( .height(1.dp) .padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = "Intake Goal", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } Row( @@ -410,17 +425,17 @@ fun Goals( horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.clickable { openDialog.value = true - }, + } ) { Text( text = "2400ml", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor, + color = primaryColor ) Image( painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null, + contentDescription = null ) } } diff --git a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/component/CustomCheckingDialog.kt b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/component/CustomCheckingDialog.kt index a877830..c1395bd 100644 --- a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/component/CustomCheckingDialog.kt +++ b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/component/CustomCheckingDialog.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.settings.presentation.component import androidx.compose.foundation.background @@ -30,7 +45,7 @@ import com.brandyodhiambo.designsystem.theme.secondaryWhite fun CustomCheckinDialog( openDialog: MutableState, title: String, - items: List, + items: List ) { val selectedValues = remember { mutableStateListOf() } val isSelectedItem: (String) -> Boolean = { selectedValues.contains(it) } @@ -47,9 +62,11 @@ fun CustomCheckinDialog( modifier = Modifier.padding(10.dp, 5.dp, 10.dp, 10.dp), elevation = 8.dp ) { - Column(Modifier - .padding(8.dp) - .background(Color.White)) { + Column( + Modifier + .padding(8.dp) + .background(Color.White) + ) { Text( text = "Select $title", modifier = Modifier.padding(8.dp) @@ -117,7 +134,6 @@ fun CustomCheckinDialog( ) } } - } } } diff --git a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/component/CustomReminderDialog.kt b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/component/CustomReminderDialog.kt index 7333eeb..d5378c1 100644 --- a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/component/CustomReminderDialog.kt +++ b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/component/CustomReminderDialog.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.settings.presentation.component import androidx.compose.foundation.background @@ -33,7 +48,7 @@ import com.brandyodhiambo.designsystem.theme.secondaryWhite fun CustomReminderDialog( openDialog: MutableState, title: String, - items: List, + items: List ) { val selectedValue = remember { mutableStateOf("") } val isSelectedItem: (String) -> Boolean = { selectedValue.value == it } @@ -44,9 +59,11 @@ fun CustomReminderDialog( modifier = Modifier.padding(10.dp, 5.dp, 10.dp, 10.dp), elevation = 8.dp ) { - Column(Modifier - .padding(8.dp) - .background(Color.White)) { + Column( + Modifier + .padding(8.dp) + .background(Color.White) + ) { Text( text = "Select $title", modifier = Modifier.padding(8.dp) @@ -120,15 +137,15 @@ fun CustomReminderDialog( } } - if(selectedValue.value == "Custom"){ - Dialog(onDismissRequest = {openDialog.value = false}) { - CustomCheckinDialog( - openDialog = openDialog, - title = "Custom", - items = listOf("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday") - ) - } + if (selectedValue.value == "Custom") { + Dialog(onDismissRequest = { openDialog.value = false }) { + CustomCheckinDialog( + openDialog = openDialog, + title = "Custom", + items = listOf("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday") + ) + } } } } -} \ No newline at end of file +} diff --git a/feature/settings/src/test/java/com/brandyodhiambo/settings/ExampleUnitTest.kt b/feature/settings/src/test/java/com/brandyodhiambo/settings/ExampleUnitTest.kt index ed9e803..94be793 100644 --- a/feature/settings/src/test/java/com/brandyodhiambo/settings/ExampleUnitTest.kt +++ b/feature/settings/src/test/java/com/brandyodhiambo/settings/ExampleUnitTest.kt @@ -1,9 +1,23 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.settings +import junit.framework.TestCase.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +28,4 @@ class ExampleUnitTest { fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/feature/statistics/build.gradle.kts b/feature/statistics/build.gradle.kts index c751149..239d1bf 100644 --- a/feature/statistics/build.gradle.kts +++ b/feature/statistics/build.gradle.kts @@ -28,7 +28,7 @@ android { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro", + "proguard-rules.pro" ) } } diff --git a/feature/statistics/src/androidTest/java/com/brandyodhiambo/statistics/ExampleInstrumentedTest.kt b/feature/statistics/src/androidTest/java/com/brandyodhiambo/statistics/ExampleInstrumentedTest.kt index 12e2402..178b18f 100644 --- a/feature/statistics/src/androidTest/java/com/brandyodhiambo/statistics/ExampleInstrumentedTest.kt +++ b/feature/statistics/src/androidTest/java/com/brandyodhiambo/statistics/ExampleInstrumentedTest.kt @@ -1,13 +1,26 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import junit.framework.TestCase.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * @@ -21,4 +34,4 @@ class ExampleInstrumentedTest { val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.brandyodhiambo.statistics.test", appContext.packageName) } -} \ No newline at end of file +} diff --git a/feature/statistics/src/main/AndroidManifest.xml b/feature/statistics/src/main/AndroidManifest.xml index a5918e6..8bdb7e1 100644 --- a/feature/statistics/src/main/AndroidManifest.xml +++ b/feature/statistics/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ - \ No newline at end of file + diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt index aebd9fe..1d8b7a3 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics.data.mapper import com.brandyodhiambo.common.domain.model.Achievement @@ -12,49 +27,49 @@ import com.brandyodhiambo.entity.WeeklyStatisticsEntity internal fun DailyStatisticsEntity.toDailyStatistics(): DailyStatistics { return DailyStatistics( amountTaken = amountTaken, - day = day, + day = day ) } internal fun DailyStatistics.toDailyStatisticsEntity(): DailyStatisticsEntity { return DailyStatisticsEntity( amountTaken = amountTaken, - day = day, + day = day ) } internal fun WeeklyStatisticsEntity.toWeeklyStatistics(): WeeklyStatistics { return WeeklyStatistics( amountTaken = amountTaken, - week = week, + week = week ) } internal fun WeeklyStatistics.toWeeklyStatisticsEntity(): WeeklyStatisticsEntity { return WeeklyStatisticsEntity( amountTaken = amountTaken, - week = week, + week = week ) } internal fun MonthlyStatisticsEntity.toMonthlyStatistics(): MonthlyStatistics { return MonthlyStatistics( amountTaken = amountTaken, - month = month, + month = month ) } internal fun MonthlyStatistics.toMonthlyStatisticsEntity(): MonthlyStatisticsEntity { return MonthlyStatisticsEntity( amountTaken = amountTaken, - month = month, + month = month ) } internal fun AchievementEntity.toAchievement(): Achievement { return Achievement( isAchieved = isAchieved, - day = day, + day = day ) } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/AchievementRepositoryImpl.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/AchievementRepositoryImpl.kt index 3b1cec2..e77558a 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/AchievementRepositoryImpl.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/AchievementRepositoryImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics.data.repository import androidx.lifecycle.LiveData @@ -9,7 +24,7 @@ import com.brandyodhiambo.statistics.data.mapper.toAchievement import com.brandyodhiambo.statistics.data.mapper.toAchievementsEntity class AchievementRepositoryImpl( - private val achievementDao: AchievementDao, + private val achievementDao: AchievementDao ) : AchievementRepository { override suspend fun insertAchievement(achievement: Achievement) { achievementDao.insertAchievement(achievement.toAchievementsEntity()) diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/DailyStatisticsRepositoryImpl.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/DailyStatisticsRepositoryImpl.kt index 51fb2ba..ff6258b 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/DailyStatisticsRepositoryImpl.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/DailyStatisticsRepositoryImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics.data.repository import androidx.lifecycle.LiveData @@ -9,7 +24,7 @@ import com.brandyodhiambo.statistics.data.mapper.toDailyStatistics import com.brandyodhiambo.statistics.data.mapper.toDailyStatisticsEntity class DailyStatisticsRepositoryImpl( - private val dailyStatisticsDao: DailyStatisticsDao, + private val dailyStatisticsDao: DailyStatisticsDao ) : DailyStatisticsRepository { override suspend fun insertDailyStatistics(dailyStatistics: DailyStatistics) { dailyStatisticsDao.insertDailyStatistic(dailyStatistics.toDailyStatisticsEntity()) diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/MonthlyStatisticsRepositoryImpl.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/MonthlyStatisticsRepositoryImpl.kt index 85bae5d..3e97d6a 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/MonthlyStatisticsRepositoryImpl.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/MonthlyStatisticsRepositoryImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics.data.repository import androidx.lifecycle.LiveData @@ -9,7 +24,7 @@ import com.brandyodhiambo.statistics.data.mapper.toMonthlyStatistics import com.brandyodhiambo.statistics.data.mapper.toMonthlyStatisticsEntity class MonthlyStatisticsRepositoryImpl( - private val monthlyStatisticalDao: MonthlyStatisticsDao, + private val monthlyStatisticalDao: MonthlyStatisticsDao ) : MonthlyStatisticsRepository { override suspend fun insertMonthlyStatistics(monthlyStatistics: MonthlyStatistics) { monthlyStatisticalDao.insertMonthlyStatistic(monthlyStatistics.toMonthlyStatisticsEntity()) diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/WeeklyStatisticsRepositoryImpl.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/WeeklyStatisticsRepositoryImpl.kt index 94dc8f5..f840daf 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/WeeklyStatisticsRepositoryImpl.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/WeeklyStatisticsRepositoryImpl.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics.data.repository import androidx.lifecycle.LiveData @@ -9,7 +24,7 @@ import com.brandyodhiambo.statistics.data.mapper.toWeeklyStatistics import com.brandyodhiambo.statistics.data.mapper.toWeeklyStatisticsEntity class WeeklyStatisticsRepositoryImpl( - private val weeklyStatisticDao: WeeklyStatisticDao, + private val weeklyStatisticDao: WeeklyStatisticDao ) : WeeklyStatisticRepository { override suspend fun insertWeeklyStatistic(weeklyStatistic: WeeklyStatistics) { weeklyStatisticDao.insertWeeklyStatistic(weeklyStatistic.toWeeklyStatisticsEntity()) diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/di/StatisticsModule.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/di/StatisticsModule.kt index 498523d..4f0b32e 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/di/StatisticsModule.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/di/StatisticsModule.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics.di import com.brandyodhiambo.common.domain.repository.DailyStatisticsRepository diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt index b011ea7..5b04ed6 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics.presentation import android.annotation.SuppressLint @@ -5,13 +20,28 @@ import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.* +import androidx.compose.material.Card +import androidx.compose.material.Divider +import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Scaffold +import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.AccountCircle import androidx.compose.material.icons.filled.DateRange @@ -33,7 +63,7 @@ import com.brandyodhiambo.common.R import com.brandyodhiambo.common.domain.model.Achievement import com.brandyodhiambo.designsystem.theme.blackColor import com.brandyodhiambo.designsystem.theme.primaryColor -import com.brandyodhiambo.home.presentation.home_screen.HomeViewModel +import com.brandyodhiambo.home.presentation.homeScreen.HomeViewModel import com.mahmoud.composecharts.barchart.BarChart import com.mahmoud.composecharts.barchart.BarChartEntity import com.ramcosta.composedestinations.annotation.Destination @@ -45,7 +75,7 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator fun StatisticsScreen( navigator: DestinationsNavigator, statisticsViewModel: StatisticsViewModel = hiltViewModel(), - homeViewModel: HomeViewModel = hiltViewModel(), + homeViewModel: HomeViewModel = hiltViewModel() ) { val dailyStatistics = statisticsViewModel.dailyStatisticsFromDB.observeAsState() val weeklyStatistics = statisticsViewModel.weeklyStatisticsFromDB.observeAsState() @@ -93,16 +123,16 @@ fun StatisticsScreen( Achievement(isAchieved = false, "Wed"), Achievement(isAchieved = true, "Thu"), Achievement(isAchieved = false, "Fri"), - Achievement(isAchieved = false, "Sat"), + Achievement(isAchieved = false, "Sat") ) Scaffold( - backgroundColor = primaryColor, + backgroundColor = primaryColor ) { paddingValues -> Box( modifier = Modifier .fillMaxSize() - .padding(paddingValues), + .padding(paddingValues) ) { LazyColumn { item { @@ -110,16 +140,16 @@ fun StatisticsScreen( modifier = Modifier .fillMaxSize() .padding(top = 16.dp, start = 16.dp, end = 16.dp), - elevation = 4.dp, + elevation = 4.dp ) { Column( - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(8.dp) ) { Row( modifier = Modifier .fillMaxWidth() .padding(top = 8.dp, start = 8.dp, end = 8.dp), - horizontalArrangement = Arrangement.SpaceEvenly, + horizontalArrangement = Arrangement.SpaceEvenly ) { Box( modifier = Modifier @@ -130,22 +160,22 @@ fun StatisticsScreen( primaryColor } else { primaryColor.copy( - alpha = 0.2f, + alpha = 0.2f ) }, - shape = RoundedCornerShape(8.dp), + shape = RoundedCornerShape(8.dp) ).clickable { setGraphDaily.value = true setGraphWeek.value = false setGraphMonthly.value = false }, - contentAlignment = Alignment.Center, + contentAlignment = Alignment.Center ) { Text( text = "Daily", style = MaterialTheme.typography.h6, fontWeight = FontWeight.Normal, - color = blackColor, + color = blackColor ) } Box( @@ -157,22 +187,22 @@ fun StatisticsScreen( primaryColor } else { primaryColor.copy( - alpha = 0.2f, + alpha = 0.2f ) }, - shape = RoundedCornerShape(8.dp), + shape = RoundedCornerShape(8.dp) ).clickable { setGraphDaily.value = false setGraphWeek.value = true setGraphMonthly.value = false }, - contentAlignment = Alignment.Center, + contentAlignment = Alignment.Center ) { Text( text = "Weekly", style = MaterialTheme.typography.h6, fontWeight = FontWeight.Normal, - color = blackColor, + color = blackColor ) } Box( @@ -184,22 +214,22 @@ fun StatisticsScreen( primaryColor } else { primaryColor.copy( - alpha = 0.2f, + alpha = 0.2f ) }, - shape = RoundedCornerShape(8.dp), + shape = RoundedCornerShape(8.dp) ).clickable { setGraphDaily.value = false setGraphWeek.value = false setGraphMonthly.value = true }, - contentAlignment = Alignment.Center, + contentAlignment = Alignment.Center ) { Text( text = "Monthly", style = MaterialTheme.typography.h6, fontWeight = FontWeight.Normal, - color = blackColor, + color = blackColor ) } } @@ -209,7 +239,7 @@ fun StatisticsScreen( barChartData = barChartDataDaily, verticalAxisValues = verticalAxisValues, isShowHorizontalLines = true, - isShowVerticalAxis = true, + isShowVerticalAxis = true ) } if (setGraphWeek.value) { @@ -218,7 +248,7 @@ fun StatisticsScreen( barChartData = barChartDataWeek, verticalAxisValues = verticalAxisValues, isShowHorizontalLines = true, - isShowVerticalAxis = true, + isShowVerticalAxis = true ) } if (setGraphMonthly.value) { @@ -227,7 +257,7 @@ fun StatisticsScreen( barChartData = barChartDataMonth, verticalAxisValues = verticalAxisValues, isShowHorizontalLines = true, - isShowVerticalAxis = true, + isShowVerticalAxis = true ) } } @@ -235,7 +265,7 @@ fun StatisticsScreen( } item { Last7DayGoals( - weekAchivement = weekAchiement, + weekAchivement = weekAchiement ) } item { @@ -244,7 +274,7 @@ fun StatisticsScreen( currentWeeklyAverage = weeklyAverage.toInt(), currentMonthlyAverage = monthlyAverage.toInt(), currentAverage = average.toInt(), - currentDrinkFrequency = drinkFrequency, + currentDrinkFrequency = drinkFrequency ) } } @@ -259,20 +289,20 @@ fun Last7DayGoals(weekAchivement: List) { .height(135.dp) .padding(top = 8.dp, start = 16.dp, end = 16.dp) .fillMaxWidth(), - elevation = 4.dp, + elevation = 4.dp ) { Column( - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(8.dp) ) { Text( text = "Last 7 Days Goals Achieve", fontSize = 16.sp, fontWeight = FontWeight.SemiBold, - color = primaryColor, + color = primaryColor ) LazyRow( verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceEvenly, + horizontalArrangement = Arrangement.SpaceEvenly ) { items(weekAchivement.takeLast(7)) { weeks -> WeeksAcheive(weeks = weeks) @@ -284,10 +314,10 @@ fun Last7DayGoals(weekAchivement: List) { @Composable fun WeeksAcheive( - weeks: Achievement, + weeks: Achievement ) { Column( - horizontalAlignment = Alignment.CenterHorizontally, + horizontalAlignment = Alignment.CenterHorizontally ) { if (weeks.isAchieved) { GoldCup() @@ -306,7 +336,7 @@ fun GoldCup() { modifier = Modifier .size(48.dp) .padding(4.dp), - elevation = 4.dp, + elevation = 4.dp ) { Image( painter = painterResource(id = R.drawable.ic_cup), @@ -314,7 +344,7 @@ fun GoldCup() { modifier = Modifier .size(48.dp) .padding(8.dp), - contentDescription = null, + contentDescription = null ) } } @@ -327,7 +357,7 @@ fun BlackCup() { modifier = Modifier .size(48.dp) .padding(4.dp), - elevation = 4.dp, + elevation = 4.dp ) { Image( painter = painterResource(id = R.drawable.ic_black_cup), @@ -335,7 +365,7 @@ fun BlackCup() { modifier = Modifier .size(48.dp) .padding(8.dp), - contentDescription = null, + contentDescription = null ) } } @@ -346,191 +376,191 @@ fun DrinkWaterReport( currentWeeklyAverage: Int, currentMonthlyAverage: Int, currentDrinkFrequency: Int, - currentAverage: Int, + currentAverage: Int ) { Card( modifier = Modifier .fillMaxWidth() .padding(top = 8.dp, start = 16.dp, end = 16.dp), - elevation = 4.dp, + elevation = 4.dp ) { Column( - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(8.dp) ) { Text( text = "Drink Water Report", fontSize = 16.sp, fontWeight = FontWeight.SemiBold, - color = primaryColor, + color = primaryColor ) Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Icon( imageVector = Icons.Default.DateRange, tint = primaryColor, - contentDescription = null, + contentDescription = null ) Spacer(modifier = Modifier.width(8.dp)) Text( text = "Daily Average", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } Text( text = "$currentDailyAverage ml/day", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = primaryColor, + color = primaryColor ) } Divider( modifier = Modifier.height(1.dp).padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Icon( imageVector = Icons.Default.DateRange, tint = primaryColor, - contentDescription = null, + contentDescription = null ) Spacer(modifier = Modifier.width(8.dp)) Text( text = "Weekly Average", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } Text( text = "$currentWeeklyAverage ml/day", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = primaryColor, + color = primaryColor ) } Divider( modifier = Modifier.height(1.dp).padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Icon( imageVector = Icons.Default.DateRange, tint = primaryColor, - contentDescription = null, + contentDescription = null ) Spacer(modifier = Modifier.width(8.dp)) Text( text = "Monthly Average", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } Text( text = "$currentMonthlyAverage ml/day", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = primaryColor, + color = primaryColor ) } Divider( modifier = Modifier.height(1.dp).padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Icon( imageVector = Icons.Default.Star, tint = primaryColor, - contentDescription = null, + contentDescription = null ) Spacer(modifier = Modifier.width(8.dp)) Text( text = "Average Completion", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } Text( text = "$currentAverage%", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = primaryColor, + color = primaryColor ) } Divider( modifier = Modifier.height(1.dp).padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Icon( imageVector = Icons.Default.AccountCircle, tint = primaryColor, - contentDescription = null, + contentDescription = null ) Spacer(modifier = Modifier.width(8.dp)) Text( text = "Drink Frequency", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } Text( text = "$currentDrinkFrequency Times/day", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = primaryColor, + color = primaryColor ) } } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt index 4499040..7d290e4 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsViewModel.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics.presentation import androidx.lifecycle.ViewModel @@ -11,7 +26,7 @@ import javax.inject.Inject class StatisticsViewModel @Inject constructor( private val dailyStatisticsRepository: DailyStatisticsRepository, private val weeklyStatisticsRepository: WeeklyStatisticRepository, - private val monthlyStatisticsRepository: MonthlyStatisticsRepository, + private val monthlyStatisticsRepository: MonthlyStatisticsRepository ) : ViewModel() { val dailyStatisticsFromDB = dailyStatisticsRepository.getDailyStatistics() diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt index b69ac01..d1f94e0 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics.worker import android.content.Context @@ -9,12 +24,12 @@ import androidx.work.OneTimeWorkRequestBuilder import androidx.work.PeriodicWorkRequest import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkManager -import com.brandyodhiambo.statistics.worker.daily_worker.DailyWorker -import com.brandyodhiambo.statistics.worker.daily_worker.DailyWorker.Companion.DAILY_WORK_NAME -import com.brandyodhiambo.statistics.worker.monthly_worker.MonthlyWorker -import com.brandyodhiambo.statistics.worker.monthly_worker.MonthlyWorker.Companion.MONTHLY_WORK_NAME -import com.brandyodhiambo.statistics.worker.weekly_worker.WeeklyWorker -import com.brandyodhiambo.statistics.worker.weekly_worker.WeeklyWorker.Companion.WEEKLY_WORK_NAME +import com.brandyodhiambo.statistics.worker.dailyWorker.DailyWorker +import com.brandyodhiambo.statistics.worker.dailyWorker.DailyWorker.Companion.DAILY_WORK_NAME +import com.brandyodhiambo.statistics.worker.monthlyWorker.MonthlyWorker +import com.brandyodhiambo.statistics.worker.monthlyWorker.MonthlyWorker.Companion.MONTHLY_WORK_NAME +import com.brandyodhiambo.statistics.worker.weeklyWorker.WeeklyWorker +import com.brandyodhiambo.statistics.worker.weeklyWorker.WeeklyWorker.Companion.WEEKLY_WORK_NAME import java.util.concurrent.TimeUnit fun startDailyOnetimeWorkRequest(context: Context) { @@ -24,6 +39,7 @@ fun startDailyOnetimeWorkRequest(context: Context) { val dailyWorkRequest = OneTimeWorkRequestBuilder() .setConstraints(constraints) + .build() WorkManager.getInstance(context).enqueue(dailyWorkRequest) @@ -38,20 +54,20 @@ fun startDailyPeriodicWorkRequest(context: Context) { val workRequest = PeriodicWorkRequestBuilder( 1, - TimeUnit.DAYS, + TimeUnit.DAYS ) .setConstraints(constraints) .setBackoffCriteria( BackoffPolicy.LINEAR, PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, - TimeUnit.MILLISECONDS, + TimeUnit.MILLISECONDS ) .build() WorkManager.getInstance(context).enqueueUniquePeriodicWork( DAILY_WORK_NAME, ExistingPeriodicWorkPolicy.REPLACE, - workRequest, + workRequest ) } @@ -77,20 +93,20 @@ fun startWeeklyPeriodicWorkRequest(context: Context) { val workRequest = PeriodicWorkRequestBuilder( 1, - TimeUnit.DAYS, + TimeUnit.DAYS ) .setConstraints(constraints) .setBackoffCriteria( BackoffPolicy.LINEAR, PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, - TimeUnit.MILLISECONDS, + TimeUnit.MILLISECONDS ) .build() WorkManager.getInstance(context).enqueueUniquePeriodicWork( WEEKLY_WORK_NAME, ExistingPeriodicWorkPolicy.REPLACE, - workRequest, + workRequest ) } @@ -116,19 +132,19 @@ fun startMonthlyPeriodicWorkRequest(context: Context) { val workRequest = PeriodicWorkRequestBuilder( 1, - TimeUnit.DAYS, + TimeUnit.DAYS ) .setConstraints(constraints) .setBackoffCriteria( BackoffPolicy.LINEAR, PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, - TimeUnit.MILLISECONDS, + TimeUnit.MILLISECONDS ) .build() WorkManager.getInstance(context).enqueueUniquePeriodicWork( MONTHLY_WORK_NAME, ExistingPeriodicWorkPolicy.REPLACE, - workRequest, + workRequest ) } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt similarity index 72% rename from feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt rename to feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt index cbca373..84e2d84 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/daily_worker/DailyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt @@ -1,4 +1,19 @@ -package com.brandyodhiambo.statistics.worker.daily_worker +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.brandyodhiambo.statistics.worker.dailyWorker import android.content.Context import androidx.hilt.work.HiltWorker @@ -13,7 +28,6 @@ import com.brandyodhiambo.common.domain.repository.ReminderTimeRepository import com.brandyodhiambo.common.domain.repository.SelectedDrinkRepository import com.brandyodhiambo.common.util.awaitValue import com.brandyodhiambo.common.util.getCurrentDay -import com.brandyodhiambo.common.util.isEndOfDay import dagger.assisted.Assisted import dagger.assisted.AssistedInject import java.time.LocalDateTime @@ -38,8 +52,12 @@ class DailyWorker @AssistedInject constructor( override suspend fun doWork(): Result { return try { val amountTaken = levelRepository.getLevel().awaitValue()?.amountTaken ?: 1f + val currentHour = LocalDateTime.now().hour + val currentMinute = LocalDateTime.now().minute - if (isEndOfDay(dateTime = LocalDateTime.now())) { + val endOfDayHour = 23 + val endOfDayMinute = 59 + if (currentHour >= endOfDayHour && currentMinute >= endOfDayMinute) { dailyStatisticsRepository.insertDailyStatistics( DailyStatistics( amountTaken = amountTaken, diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt similarity index 60% rename from feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt rename to feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt index 91fb8ef..e8ab643 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthly_worker/MonthlyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt @@ -1,4 +1,19 @@ -package com.brandyodhiambo.statistics.worker.monthly_worker +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.brandyodhiambo.statistics.worker.monthlyWorker import android.content.Context import androidx.hilt.work.HiltWorker @@ -9,10 +24,10 @@ import com.brandyodhiambo.common.domain.repository.MonthlyStatisticsRepository import com.brandyodhiambo.common.domain.repository.WeeklyStatisticRepository import com.brandyodhiambo.common.util.awaitValue import com.brandyodhiambo.common.util.getCurrentMonth -import com.brandyodhiambo.common.util.isEndOfMonth import dagger.assisted.Assisted import dagger.assisted.AssistedInject import java.time.LocalDate +import java.time.temporal.TemporalAdjusters @HiltWorker class MonthlyWorker @AssistedInject constructor( @@ -23,17 +38,20 @@ class MonthlyWorker @AssistedInject constructor( ) : CoroutineWorker(context, params) { companion object { - const val MONTHLY_WORK_NAME = "com.brandyodhiambo.common.worker.monthly_worker.MonthlyWorker" + const val MONTHLY_WORK_NAME = + "com.brandyodhiambo.common.worker.monthly_worker.MonthlyWorker" private const val TAG = "MonthlyWorker" } override suspend fun doWork(): Result { return try { val amountTaken = - weeklyStatisticRepository.getWeeklyStatistic().awaitValue()?.sumByDouble { it.amountTaken.toDouble() } + weeklyStatisticRepository.getWeeklyStatistic().awaitValue() + ?.sumByDouble { it.amountTaken.toDouble() } val totalAmountTaken = amountTaken?.div(4) // 4 weeks in a month - if (isEndOfMonth(LocalDate.now())) { + val lastDayOfMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()) + if (LocalDate.now() == lastDayOfMonth) { monthlyStatisticsRepository.insertMonthlyStatistics( MonthlyStatistics( amountTaken = totalAmountTaken?.toFloat() ?: 0f, diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt similarity index 63% rename from feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt rename to feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt index 7c7cca8..c047c70 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weekly_worker/WeeklyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt @@ -1,4 +1,19 @@ -package com.brandyodhiambo.statistics.worker.weekly_worker +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.brandyodhiambo.statistics.worker.weeklyWorker import android.content.Context import androidx.hilt.work.HiltWorker @@ -9,10 +24,11 @@ import com.brandyodhiambo.common.domain.repository.DailyStatisticsRepository import com.brandyodhiambo.common.domain.repository.WeeklyStatisticRepository import com.brandyodhiambo.common.util.awaitValue import com.brandyodhiambo.common.util.getCurrentWeekNumber -import com.brandyodhiambo.common.util.isEndOfWeek import dagger.assisted.Assisted import dagger.assisted.AssistedInject +import java.time.DayOfWeek import java.time.LocalDate +import java.time.temporal.TemporalAdjusters @HiltWorker class WeeklyWorker @AssistedInject constructor( @@ -28,10 +44,12 @@ class WeeklyWorker @AssistedInject constructor( override suspend fun doWork(): Result { return try { - val amountTaken = dailyStatisticsRepository.getDailyStatistics().awaitValue()?.sumByDouble { it.amountTaken.toDouble() } + val amountTaken = dailyStatisticsRepository.getDailyStatistics().awaitValue() + ?.sumByDouble { it.amountTaken.toDouble() } val totalAmountTaken = amountTaken?.div(7) // 7 days in a week - if (isEndOfWeek(LocalDate.now())) { + val lastDayOfWeek = LocalDate.now().with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)) + if (LocalDate.now() == lastDayOfWeek) { weeklyStatisticRepository.insertWeeklyStatistic( WeeklyStatistics( amountTaken = totalAmountTaken?.toFloat() ?: 0f, @@ -39,6 +57,7 @@ class WeeklyWorker @AssistedInject constructor( ), ) } + Result.success() } catch (e: Exception) { Result.failure() diff --git a/feature/statistics/src/test/java/com/brandyodhiambo/statistics/ExampleUnitTest.kt b/feature/statistics/src/test/java/com/brandyodhiambo/statistics/ExampleUnitTest.kt index 6a6287a..deb0cd8 100644 --- a/feature/statistics/src/test/java/com/brandyodhiambo/statistics/ExampleUnitTest.kt +++ b/feature/statistics/src/test/java/com/brandyodhiambo/statistics/ExampleUnitTest.kt @@ -1,9 +1,23 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics +import junit.framework.TestCase.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +28,4 @@ class ExampleUnitTest { fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/ktlint.gradle b/ktlint.gradle new file mode 100644 index 0000000..6ac58c4 --- /dev/null +++ b/ktlint.gradle @@ -0,0 +1,12 @@ +apply plugin: "org.jlleitschuh.gradle.ktlint" +ktlint { + debug.set(true) + verbose.set(true) + android.set(false) + outputToConsole.set(true) + outputColorName.set("RED") + filter { + exclude("**/generated/**") + include("**/kotlin/**") + } +} \ No newline at end of file diff --git a/spotless.gradle b/spotless.gradle new file mode 100644 index 0000000..1f99636 --- /dev/null +++ b/spotless.gradle @@ -0,0 +1,33 @@ +apply plugin: "com.diffplug.spotless" +spotless { + java { + target '**/*.java' + googleJavaFormat().aosp() + removeUnusedImports() + trimTrailingWhitespace() + indentWithSpaces() + licenseHeaderFile(rootProject.file("spotless/copyright.java")) + endWithNewline() + } + kotlin { + target "**/*.kt" + trimTrailingWhitespace() + ktlint() + indentWithSpaces() + licenseHeaderFile(rootProject.file("spotless/copyright.kt")) + endWithNewline() + } + + format 'misc', { + target '**/*.gradle', '**/*.md', '**/.gitignore' + indentWithSpaces() + trimTrailingWhitespace() + endWithNewline() + } + format 'xml', { + target '**/*.xml' + indentWithSpaces() + trimTrailingWhitespace() + endWithNewline() + } +} \ No newline at end of file diff --git a/spotless/copyright.java b/spotless/copyright.java new file mode 100644 index 0000000..933f7c5 --- /dev/null +++ b/spotless/copyright.java @@ -0,0 +1,15 @@ +/* + * Copyright (C)$YEAR Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ \ No newline at end of file diff --git a/spotless/copyright.kt b/spotless/copyright.kt new file mode 100644 index 0000000..933f7c5 --- /dev/null +++ b/spotless/copyright.kt @@ -0,0 +1,15 @@ +/* + * Copyright (C)$YEAR Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ \ No newline at end of file From 92fc91405fe319899da1ad2ec425bc8537db4b61 Mon Sep 17 00:00:00 2001 From: brandy-kay Date: Mon, 21 Aug 2023 19:18:38 +0300 Subject: [PATCH 05/10] completes statistics screen --- .../brandyodhiambo/common/util/Function.kt | 14 +- .../com/brandyodhiambo/di/DatabaseModule.kt | 4 + .../brandyodhiambo/home/data/mapper/Mapper.kt | 16 +++ .../repository/AchievementRepositoryImpl.kt | 6 +- .../com/brandyodhiambo/home/di/HomeModule.kt | 9 ++ .../achievement/AchievementViewModel.kt | 35 +++++ .../component/CongratulationDialog.kt | 131 +----------------- .../presentation/homeScreen/HomeScreen.kt | 27 +++- .../presentation/homeScreen/HomeViewModel.kt | 1 - .../statistics/data/mapper/Mapper.kt | 16 --- .../presentation/StatisticsScreen.kt | 46 +++--- .../statistics/worker/WorkerRequest.kt | 6 +- 12 files changed, 138 insertions(+), 173 deletions(-) rename feature/{statistics/src/main/java/com/brandyodhiambo/statistics => home/src/main/java/com/brandyodhiambo/home}/data/repository/AchievementRepositoryImpl.kt (90%) create mode 100644 feature/home/src/main/java/com/brandyodhiambo/home/presentation/achievement/AchievementViewModel.kt diff --git a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt index cee46a8..fc96798 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt @@ -22,12 +22,9 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.withContext import java.text.SimpleDateFormat -import java.time.DayOfWeek import java.time.LocalDate import java.time.LocalDateTime -import java.time.LocalTime import java.time.format.TextStyle -import java.time.temporal.TemporalAdjusters import java.time.temporal.WeekFields import java.util.* @@ -72,6 +69,17 @@ fun getCurrentYear(): String { val now = LocalDateTime.now() return now.year.toString() } + +fun isEndOfDay(dateTime: LocalDateTime): Boolean { + val currentHour = dateTime.hour + val currentMinute = dateTime.minute + + val endOfDayHour = 23 + val endOfDayMinute = 59 + + return currentHour >= endOfDayHour && currentMinute >= endOfDayMinute +} + suspend fun LiveData.awaitValue(): T = withContext(Dispatchers.Default) { val flow = MutableSharedFlow(replay = 1) val observer = androidx.lifecycle.Observer { diff --git a/core/database/src/main/java/com/brandyodhiambo/di/DatabaseModule.kt b/core/database/src/main/java/com/brandyodhiambo/di/DatabaseModule.kt index 1e9d81d..15097ff 100644 --- a/core/database/src/main/java/com/brandyodhiambo/di/DatabaseModule.kt +++ b/core/database/src/main/java/com/brandyodhiambo/di/DatabaseModule.kt @@ -89,6 +89,10 @@ object DatabaseModule { @Singleton fun provideMonthlyStatisticsDao(database: QuenchDatabase) = database.monthlyStatisticsDao() + @Provides + @Singleton + fun provideAchievementDao(database: QuenchDatabase) = database.achievementDao() + @Provides @Singleton fun provideGson(): Gson { diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/data/mapper/Mapper.kt b/feature/home/src/main/java/com/brandyodhiambo/home/data/mapper/Mapper.kt index 95c65d1..7fbdb8b 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/data/mapper/Mapper.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/data/mapper/Mapper.kt @@ -15,6 +15,7 @@ */ package com.brandyodhiambo.home.data.mapper +import com.brandyodhiambo.common.domain.model.Achievement import com.brandyodhiambo.common.domain.model.GoalWaterIntake import com.brandyodhiambo.common.domain.model.IdealWaterIntake import com.brandyodhiambo.common.domain.model.Level @@ -22,6 +23,7 @@ import com.brandyodhiambo.common.domain.model.ReminderTime import com.brandyodhiambo.common.domain.model.SelectedDrink import com.brandyodhiambo.common.domain.model.SleepTime import com.brandyodhiambo.common.domain.model.WakeTime +import com.brandyodhiambo.entity.AchievementEntity import com.brandyodhiambo.entity.GoalWaterIntakeEntity import com.brandyodhiambo.entity.IdealWaterIntakeEntity import com.brandyodhiambo.entity.LevelEntity @@ -142,3 +144,17 @@ internal fun ReminderTime.toReminderEntity(): ReminderTimeEntity { days = days ) } + +internal fun AchievementEntity.toAchievement(): Achievement { + return Achievement( + isAchieved = isAchieved, + day = day + ) +} + +internal fun Achievement.toAchievementsEntity(): AchievementEntity { + return AchievementEntity( + isAchieved = isAchieved, + day = day + ) +} diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/AchievementRepositoryImpl.kt b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/AchievementRepositoryImpl.kt similarity index 90% rename from feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/AchievementRepositoryImpl.kt rename to feature/home/src/main/java/com/brandyodhiambo/home/data/repository/AchievementRepositoryImpl.kt index e77558a..04017b3 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/repository/AchievementRepositoryImpl.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/data/repository/AchievementRepositoryImpl.kt @@ -13,15 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.brandyodhiambo.statistics.data.repository +package com.brandyodhiambo.home.data.repository import androidx.lifecycle.LiveData import androidx.lifecycle.Transformations import com.brandyodhiambo.common.domain.model.Achievement import com.brandyodhiambo.common.domain.repository.AchievementRepository import com.brandyodhiambo.dao.AchievementDao -import com.brandyodhiambo.statistics.data.mapper.toAchievement -import com.brandyodhiambo.statistics.data.mapper.toAchievementsEntity +import com.brandyodhiambo.home.data.mapper.toAchievement +import com.brandyodhiambo.home.data.mapper.toAchievementsEntity class AchievementRepositoryImpl( private val achievementDao: AchievementDao diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/di/HomeModule.kt b/feature/home/src/main/java/com/brandyodhiambo/home/di/HomeModule.kt index 266e55e..4247e36 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/di/HomeModule.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/di/HomeModule.kt @@ -15,6 +15,7 @@ */ package com.brandyodhiambo.home.di +import com.brandyodhiambo.common.domain.repository.AchievementRepository import com.brandyodhiambo.common.domain.repository.GoalWaterIntakeRepository import com.brandyodhiambo.common.domain.repository.IdealWaterIntakeRepository import com.brandyodhiambo.common.domain.repository.LevelRepository @@ -22,6 +23,7 @@ import com.brandyodhiambo.common.domain.repository.ReminderTimeRepository import com.brandyodhiambo.common.domain.repository.SelectedDrinkRepository import com.brandyodhiambo.common.domain.repository.SleepTimeRepository import com.brandyodhiambo.common.domain.repository.WakeTimeRepository +import com.brandyodhiambo.dao.AchievementDao import com.brandyodhiambo.dao.GoalWaterIntakeDao import com.brandyodhiambo.dao.IdealWaterIntakeDao import com.brandyodhiambo.dao.LevelDao @@ -29,6 +31,7 @@ import com.brandyodhiambo.dao.ReminderTimeDao import com.brandyodhiambo.dao.SelectedDrinkDao import com.brandyodhiambo.dao.SleepTimeDao import com.brandyodhiambo.dao.WakeTimeDao +import com.brandyodhiambo.home.data.repository.AchievementRepositoryImpl import com.brandyodhiambo.home.data.repository.GoalWaterIntakeRepositoryImpl import com.brandyodhiambo.home.data.repository.IdealWaterInkateRepositoryImpl import com.brandyodhiambo.home.data.repository.LevelRepositoryImpl @@ -87,4 +90,10 @@ object HomeModule { fun provideReminderTimeRepository(reminderTimeDao: ReminderTimeDao): ReminderTimeRepository { return ReminderTimeRepositoryImpl(reminderTimeDao = reminderTimeDao) } + + @Provides + @Singleton + fun provideAchievementRepository(achievementDao: AchievementDao): AchievementRepository { + return AchievementRepositoryImpl(achievementDao = achievementDao) + } } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/achievement/AchievementViewModel.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/achievement/AchievementViewModel.kt new file mode 100644 index 0000000..aadfd3f --- /dev/null +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/achievement/AchievementViewModel.kt @@ -0,0 +1,35 @@ +package com.brandyodhiambo.home.presentation.achievement + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.brandyodhiambo.common.domain.model.Achievement +import com.brandyodhiambo.common.domain.repository.AchievementRepository +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class AchievementViewModel @Inject constructor( + private val achievementRepository: AchievementRepository +) : ViewModel() { + + val isAchieved = achievementRepository.getAchievement() + + fun insertIsAchieved(achievement: Achievement) { + viewModelScope.launch { + achievementRepository.insertAchievement(achievement) + } + } + + fun deleteAchievement(achievement: Achievement) { + viewModelScope.launch { + achievementRepository.deleteAchievement(achievement) + } + } + + fun deleteAllAchievement() { + viewModelScope.launch { + achievementRepository.deleteAllAchievement() + } + } +} diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CongratulationDialog.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CongratulationDialog.kt index 2ba719e..df131be 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CongratulationDialog.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/component/CongratulationDialog.kt @@ -15,43 +15,33 @@ */ package com.brandyodhiambo.home.presentation.component -import android.content.Intent -import android.widget.Toast import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -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.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Card import androidx.compose.material.Text import androidx.compose.material.TextButton import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.brandyodhiambo.common.R import com.brandyodhiambo.designsystem.theme.primaryColor @Composable fun CongratulationsDialog( - openDialogCustom: MutableState + onOkayClicked: () -> Unit, + onCancelClicked: () -> Unit ) { val context = LocalContext.current Card( @@ -75,119 +65,6 @@ fun CongratulationsDialog( contentDescription = null ) } - Text( - text = "Share With Friends Now!!", - textAlign = TextAlign.Center, - modifier = Modifier - .fillMaxWidth(), - maxLines = 2, - overflow = TextOverflow.Ellipsis - ) - Spacer(modifier = Modifier.height(8.dp)) - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceEvenly - ) { - Image( - painter = painterResource(id = R.drawable.facebook), - contentDescription = null, - contentScale = ContentScale.Fit, - colorFilter = ColorFilter.tint( - color = primaryColor - ), - modifier = Modifier - .width(50.dp) - .height(50.dp) - .clickable { - val intent = - context.packageManager.getLaunchIntentForPackage("com.facebook.katana") - if (intent != null) { - context.startActivity(intent) - } else { - Toast - .makeText( - context, - "Facebook is not installed", - Toast.LENGTH_SHORT - ) - .show() - } - } - - ) - Image( - painter = painterResource(id = R.drawable.twitter), - contentDescription = null, - contentScale = ContentScale.Fit, - colorFilter = ColorFilter.tint( - color = primaryColor - ), - modifier = Modifier - .width(50.dp) - .height(50.dp) - .clickable { - val intent = - context.packageManager.getLaunchIntentForPackage("com.twitter.android") - if (intent != null) { - context.startActivity(intent) - } else { - Toast - .makeText( - context, - "Twitter is not installed", - Toast.LENGTH_SHORT - ) - .show() - } - } - - ) - Image( - painter = painterResource(id = R.drawable.whatsapp), - contentDescription = null, - contentScale = ContentScale.Fit, - modifier = Modifier - .width(50.dp) - .height(50.dp) - .clickable { - val intent = - context.packageManager.getLaunchIntentForPackage("com.whatsapp") - if (intent != null) { - context.startActivity(intent) - } else { - Toast - .makeText( - context, - "Whatsapp is not installed", - Toast.LENGTH_SHORT - ) - .show() - } - } - - ) - - Image( - painter = painterResource(id = R.drawable.ic_more), - contentDescription = null, - contentScale = ContentScale.Fit, - modifier = Modifier - .width(50.dp) - .height(50.dp) - .clickable { - val sendIntent = Intent() - sendIntent.action = Intent.ACTION_SEND - sendIntent.putExtra( - Intent.EXTRA_TEXT, - "Quench App" - ) - sendIntent.type = "text/plain" - context.startActivity(sendIntent) - } - - ) - } Row( Modifier @@ -197,7 +74,7 @@ fun CongratulationsDialog( horizontalArrangement = Arrangement.SpaceAround ) { TextButton(onClick = { - openDialogCustom.value = false + onCancelClicked() }) { Text( "Cancel", @@ -207,7 +84,7 @@ fun CongratulationsDialog( ) } TextButton(onClick = { - openDialogCustom.value = false + onOkayClicked() }) { Text( "Okay", diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt index c371f4e..991a2d8 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt @@ -57,6 +57,7 @@ import androidx.compose.ui.unit.sp import androidx.compose.ui.window.Dialog import androidx.hilt.navigation.compose.hiltViewModel import com.brandyodhiambo.common.R +import com.brandyodhiambo.common.domain.model.Achievement import com.brandyodhiambo.common.domain.model.Days import com.brandyodhiambo.common.domain.model.GoalWaterIntake import com.brandyodhiambo.common.domain.model.IdealWaterIntake @@ -64,10 +65,13 @@ import com.brandyodhiambo.common.domain.model.Level import com.brandyodhiambo.common.domain.model.ReminderTime import com.brandyodhiambo.common.domain.model.SelectedDrink import com.brandyodhiambo.common.presentation.component.WaterIntakeDialog +import com.brandyodhiambo.common.util.getCurrentDay +import com.brandyodhiambo.common.util.isEndOfDay import com.brandyodhiambo.designsystem.components.CircularButton import com.brandyodhiambo.designsystem.theme.lightBlue import com.brandyodhiambo.designsystem.theme.primaryColor import com.brandyodhiambo.designsystem.theme.roboto +import com.brandyodhiambo.home.presentation.achievement.AchievementViewModel import com.brandyodhiambo.home.presentation.component.CircularRating import com.brandyodhiambo.home.presentation.component.CongratulationsDialog import com.brandyodhiambo.home.presentation.component.DeleteDialog @@ -76,12 +80,14 @@ import com.brandyodhiambo.home.presentation.component.IdealIntakeGoalDialog import com.brandyodhiambo.home.presentation.component.SelectDrinkComposable import com.brandyodhiambo.home.presentation.component.TimeSetterDialog import com.ramcosta.composedestinations.annotation.Destination +import java.time.LocalDateTime @SuppressLint("UnusedMaterialScaffoldPaddingParameter") @Destination @Composable fun HomeScreen( - viewModel: HomeViewModel = hiltViewModel() + viewModel: HomeViewModel = hiltViewModel(), + achievementViewModel: AchievementViewModel = hiltViewModel() ) { val openTimeDialog = remember { mutableStateOf(false) } val openDeleteDialog = remember { mutableStateOf(false) } @@ -196,15 +202,30 @@ fun HomeScreen( if ((waterTaken >= goalWaterIntake) && (goalWaterIntake != 0)) { openCongratulationsDialog.value = true - } if (openCongratulationsDialog.value) { Dialog(onDismissRequest = { openCongratulationsDialog.value }) { - CongratulationsDialog(openDialogCustom = openCongratulationsDialog) + CongratulationsDialog( + onCancelClicked = { + openCongratulationsDialog.value = false + }, + onOkayClicked = { + openCongratulationsDialog.value = false + } + ) } } + if (isEndOfDay(LocalDateTime.now()) && openCongratulationsDialog.value) { + achievementViewModel.insertIsAchieved( + Achievement( + isAchieved = true, + day = getCurrentDay() + ) + ) + } + if (openTimeDialog.value) { Dialog(onDismissRequest = { openTimeDialog.value }) { TimeSetterDialog( diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeViewModel.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeViewModel.kt index 9ce837b..54b98b3 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeViewModel.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeViewModel.kt @@ -45,7 +45,6 @@ class HomeViewModel @Inject constructor( private val levelRepository: LevelRepository, private val reminderTimeRepository: ReminderTimeRepository ) : ViewModel() { - /* * ideal water intake value and functions * */ diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt index 1d8b7a3..90e0e8b 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/data/mapper/Mapper.kt @@ -15,11 +15,9 @@ */ package com.brandyodhiambo.statistics.data.mapper -import com.brandyodhiambo.common.domain.model.Achievement import com.brandyodhiambo.common.domain.model.DailyStatistics import com.brandyodhiambo.common.domain.model.MonthlyStatistics import com.brandyodhiambo.common.domain.model.WeeklyStatistics -import com.brandyodhiambo.entity.AchievementEntity import com.brandyodhiambo.entity.DailyStatisticsEntity import com.brandyodhiambo.entity.MonthlyStatisticsEntity import com.brandyodhiambo.entity.WeeklyStatisticsEntity @@ -65,17 +63,3 @@ internal fun MonthlyStatistics.toMonthlyStatisticsEntity(): MonthlyStatisticsEnt month = month ) } - -internal fun AchievementEntity.toAchievement(): Achievement { - return Achievement( - isAchieved = isAchieved, - day = day - ) -} - -internal fun Achievement.toAchievementsEntity(): AchievementEntity { - return AchievementEntity( - isAchieved = isAchieved, - day = day - ) -} diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt index 5b04ed6..fac9b39 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/presentation/StatisticsScreen.kt @@ -63,6 +63,7 @@ import com.brandyodhiambo.common.R import com.brandyodhiambo.common.domain.model.Achievement import com.brandyodhiambo.designsystem.theme.blackColor import com.brandyodhiambo.designsystem.theme.primaryColor +import com.brandyodhiambo.home.presentation.achievement.AchievementViewModel import com.brandyodhiambo.home.presentation.homeScreen.HomeViewModel import com.mahmoud.composecharts.barchart.BarChart import com.mahmoud.composecharts.barchart.BarChartEntity @@ -75,7 +76,8 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator fun StatisticsScreen( navigator: DestinationsNavigator, statisticsViewModel: StatisticsViewModel = hiltViewModel(), - homeViewModel: HomeViewModel = hiltViewModel() + homeViewModel: HomeViewModel = hiltViewModel(), + achievementViewModel: AchievementViewModel = hiltViewModel() ) { val dailyStatistics = statisticsViewModel.dailyStatisticsFromDB.observeAsState() val weeklyStatistics = statisticsViewModel.weeklyStatisticsFromDB.observeAsState() @@ -106,7 +108,8 @@ fun StatisticsScreen( val monthlyAverage = monthlyStatistics.value?.map { it.amountTaken }?.average() ?: 0.0 val dailyAverage = dailyStatistics.value?.map { it.amountTaken }?.average() ?: 0.0 - val drinkFrequency = goalWaterIntake.value?.waterIntake?.div(idealWaterIntake.value?.waterIntake ?: 1) ?: 0 + val drinkFrequency = + goalWaterIntake.value?.waterIntake?.div(idealWaterIntake.value?.waterIntake ?: 1) ?: 0 val average = if (setGraphDaily.value) { dailyAverage @@ -116,15 +119,7 @@ fun StatisticsScreen( monthlyAverage } - val weekAchiement = listOf( - Achievement(isAchieved = true, "Sun"), - Achievement(isAchieved = true, "Mon"), - Achievement(isAchieved = false, "Tue"), - Achievement(isAchieved = false, "Wed"), - Achievement(isAchieved = true, "Thu"), - Achievement(isAchieved = false, "Fri"), - Achievement(isAchieved = false, "Sat") - ) + val weekAchievement = achievementViewModel.isAchieved.observeAsState(initial = emptyList()) Scaffold( backgroundColor = primaryColor @@ -265,7 +260,7 @@ fun StatisticsScreen( } item { Last7DayGoals( - weekAchivement = weekAchiement + weekAchivement = weekAchievement.value ?: emptyList() ) } item { @@ -292,7 +287,8 @@ fun Last7DayGoals(weekAchivement: List) { elevation = 4.dp ) { Column( - modifier = Modifier.padding(8.dp) + modifier = Modifier.padding(8.dp), + horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "Last 7 Days Goals Achieve", @@ -300,12 +296,24 @@ fun Last7DayGoals(weekAchivement: List) { fontWeight = FontWeight.SemiBold, color = primaryColor ) - LazyRow( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceEvenly + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.fillMaxSize() ) { - items(weekAchivement.takeLast(7)) { weeks -> - WeeksAcheive(weeks = weeks) + if (weekAchivement.isEmpty()) { + Text( + text = "You have no achievements yet", + fontSize = 16.sp, + fontWeight = FontWeight.Normal + ) + } + LazyRow( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceEvenly + ) { + items(weekAchivement.takeLast(7)) { weeks -> + WeeksAcheive(weeks = weeks) + } } } } @@ -324,7 +332,7 @@ fun WeeksAcheive( } else { BlackCup() } - Text(text = weeks.day, fontSize = 16.sp, fontWeight = FontWeight.W400) + Text(text = weeks.day.take(3), fontSize = 16.sp, fontWeight = FontWeight.W400) } } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt index d1f94e0..642eabc 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt @@ -39,7 +39,11 @@ fun startDailyOnetimeWorkRequest(context: Context) { val dailyWorkRequest = OneTimeWorkRequestBuilder() .setConstraints(constraints) - + .setBackoffCriteria( + BackoffPolicy.LINEAR, + PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, + TimeUnit.MILLISECONDS + ) .build() WorkManager.getInstance(context).enqueue(dailyWorkRequest) From 20a277aeb8ea53c8d9d3675df774311c2b874255 Mon Sep 17 00:00:00 2001 From: brandy-kay Date: Mon, 21 Aug 2023 19:19:25 +0300 Subject: [PATCH 06/10] completes statistics screen --- .../java/com/brandyodhiambo/quench/ui/MainActivity.kt | 10 +++++----- .../statistics/worker/dailyWorker/DailyWorker.kt | 6 +++--- .../statistics/worker/monthlyWorker/MonthlyWorker.kt | 6 +++--- .../statistics/worker/weeklyWorker/WeeklyWorker.kt | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt index f0b773c..d017aa0 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt @@ -61,7 +61,7 @@ class MainActivity : ComponentActivity() { QuenchTheme { Surface( modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colors.background, + color = MaterialTheme.colors.background ) { startDailyOnetimeWorkRequest(applicationContext) startMonthlyOnetimeWorkRequest(applicationContext) @@ -73,7 +73,7 @@ class MainActivity : ComponentActivity() { val scheduler = AlarmSchedularImpl(this) val alarmItem = AlarmData( time = LocalDateTime.now().withHour(hours).withMinute(minutes), - message = getString(R.string.it_s_time_to_drink_water), + message = getString(R.string.it_s_time_to_drink_water) ) alarmItem.let(scheduler::schedule) val navController = rememberAnimatedNavController() @@ -85,9 +85,9 @@ class MainActivity : ComponentActivity() { engine = navHostEngine, dependenciesContainerBuilder = { dependency( - currentNavigator(), + currentNavigator() ) - }, + } ) } } @@ -98,7 +98,7 @@ class MainActivity : ComponentActivity() { fun DestinationScope<*>.currentNavigator(): FeatureNavigator { return FeatureNavigator( navController = navController, - navGraph = navBackStackEntry.destination.navGraph(), + navGraph = navBackStackEntry.destination.navGraph() ) } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt index 84e2d84..2d55b91 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt @@ -41,7 +41,7 @@ class DailyWorker @AssistedInject constructor( private val idealWaterIntakeRepository: IdealWaterIntakeRepository, private val selectedDrinkRepository: SelectedDrinkRepository, private val reminderTimeRepository: ReminderTimeRepository, - private val dailyStatisticsRepository: DailyStatisticsRepository, + private val dailyStatisticsRepository: DailyStatisticsRepository ) : CoroutineWorker(context, params) { companion object { @@ -61,8 +61,8 @@ class DailyWorker @AssistedInject constructor( dailyStatisticsRepository.insertDailyStatistics( DailyStatistics( amountTaken = amountTaken, - day = getCurrentDay(), - ), + day = getCurrentDay() + ) ) goalWaterIntakeRepository.deleteAllGoalWaterIntakes() idealWaterIntakeRepository.deleteAllIdealWaterIntakes() diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt index e8ab643..f91bb62 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt @@ -34,7 +34,7 @@ class MonthlyWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, private val weeklyStatisticRepository: WeeklyStatisticRepository, - private val monthlyStatisticsRepository: MonthlyStatisticsRepository, + private val monthlyStatisticsRepository: MonthlyStatisticsRepository ) : CoroutineWorker(context, params) { companion object { @@ -55,8 +55,8 @@ class MonthlyWorker @AssistedInject constructor( monthlyStatisticsRepository.insertMonthlyStatistics( MonthlyStatistics( amountTaken = totalAmountTaken?.toFloat() ?: 0f, - month = getCurrentMonth(), - ), + month = getCurrentMonth() + ) ) } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt index c047c70..930cad6 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt @@ -35,7 +35,7 @@ class WeeklyWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, private val dailyStatisticsRepository: DailyStatisticsRepository, - private val weeklyStatisticRepository: WeeklyStatisticRepository, + private val weeklyStatisticRepository: WeeklyStatisticRepository ) : CoroutineWorker(context, params) { companion object { const val WEEKLY_WORK_NAME = "com.brandyodhiambo.common.worker.weekly_worker.WeeklyWorker" @@ -53,8 +53,8 @@ class WeeklyWorker @AssistedInject constructor( weeklyStatisticRepository.insertWeeklyStatistic( WeeklyStatistics( amountTaken = totalAmountTaken?.toFloat() ?: 0f, - week = getCurrentWeekNumber().toString(), - ), + week = getCurrentWeekNumber().toString() + ) ) } From 5f28c39e578e57ff55e48bb95f355895b59fb02f Mon Sep 17 00:00:00 2001 From: brandy-kay Date: Tue, 22 Aug 2023 17:26:57 +0300 Subject: [PATCH 07/10] works on settings screen --- feature/settings/build.gradle.kts | 1 + .../settings/presentation/SettingsScreen.kt | 256 +++++++++--------- 2 files changed, 126 insertions(+), 131 deletions(-) diff --git a/feature/settings/build.gradle.kts b/feature/settings/build.gradle.kts index 4d7d975..5450c8c 100644 --- a/feature/settings/build.gradle.kts +++ b/feature/settings/build.gradle.kts @@ -53,6 +53,7 @@ dependencies { // RamCosta Navigation implementation("io.github.raamcosta.compose-destinations:core:1.5.20-beta") + implementation(project(mapOf("path" to ":feature:home"))) ksp("io.github.raamcosta.compose-destinations:ksp:1.5.15-beta") // Navigation animation diff --git a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt index 74cf640..b598e6e 100644 --- a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt +++ b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt @@ -16,8 +16,16 @@ package com.brandyodhiambo.settings.presentation import android.annotation.SuppressLint +import android.content.Context import android.content.Intent +import android.media.MediaPlayer +import android.media.RingtoneManager +import android.net.Uri +import android.os.Build import android.provider.MediaStore +import android.provider.Settings +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* // ktlint-disable no-wildcard-imports @@ -36,9 +44,13 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.window.Dialog +import androidx.hilt.navigation.compose.hiltViewModel import com.brandyodhiambo.common.R +import com.brandyodhiambo.common.domain.model.GoalWaterIntake +import com.brandyodhiambo.common.presentation.component.WaterIntakeDialog import com.brandyodhiambo.designsystem.theme.blackColor import com.brandyodhiambo.designsystem.theme.primaryColor +import com.brandyodhiambo.home.presentation.homeScreen.HomeViewModel import com.brandyodhiambo.settings.presentation.component.CustomReminderDialog import com.ramcosta.composedestinations.annotation.Destination @@ -50,34 +62,37 @@ interface SettingsNavigator { @Destination @Composable fun SettingScreen( - navigator: SettingsNavigator + navigator: SettingsNavigator, + homeViewModel: HomeViewModel = hiltViewModel(), ) { val openIntakeDialog = remember { mutableStateOf(false) } - val openGenderDialog = remember { mutableStateOf(false) } val openTimeDialog = remember { mutableStateOf(false) } val openWaterUnitDialog = remember { mutableStateOf(false) } val openWeightUnitDialog = remember { mutableStateOf(false) } + val context = LocalContext.current + Scaffold( - backgroundColor = primaryColor + backgroundColor = primaryColor, ) { paddingValues -> Box( modifier = Modifier .fillMaxSize() - .padding(paddingValues) + .padding(paddingValues), ) { LazyColumn { item { UnitsWaterIntake( openTimeFormatDialog = openTimeDialog, openWaterUnitDialog = openWaterUnitDialog, - openWeightUnitDialog = openWeightUnitDialog + openWeightUnitDialog = openWeightUnitDialog, ) } item { Goals( openDialog = openIntakeDialog, - openGenderDialog = openGenderDialog + currentIntake = homeViewModel.goalWaterIntakeValue.value, + currentForm = homeViewModel.goalWaterForm.value, ) } item { @@ -87,17 +102,23 @@ fun SettingScreen( if (openIntakeDialog.value) { Dialog(onDismissRequest = { openIntakeDialog.value }) { - // WaterIntakeDialog(openCustomDialog = openIntakeDialog) - } - } - - if (openGenderDialog.value) { - Dialog(onDismissRequest = { openGenderDialog.value }) { - val gender = listOf("Male", "Female", "Other") - CustomReminderDialog( - openDialog = openGenderDialog, - items = gender, - title = "Gender" + WaterIntakeDialog( + openCustomDialog = openIntakeDialog, + currentWaterIntakeText = homeViewModel.goalWaterIntakeValue.value, + currentWaterIntakeFormText = homeViewModel.goalWaterForm.value, + onCurrentWaterIntakeTextChange = { + homeViewModel.setGoalWaterIntakeValue(it) + }, + onCurrentWaterIntakeFormTextChange = { + homeViewModel.setGoalWaterForm(it) + }, + onOkayClick = { + val goalWaterIntakeToInsert = GoalWaterIntake( + waterIntake = homeViewModel.goalWaterIntakeValue.value.toInt(), + form = homeViewModel.goalWaterForm.value, + ) + homeViewModel.insertGoalWaterIntake(goalWaterIntakeToInsert) + }, ) } } @@ -107,7 +128,7 @@ fun SettingScreen( CustomReminderDialog( openDialog = openTimeDialog, items = time, - title = "Time Format" + title = "Time Format", ) } } @@ -118,7 +139,7 @@ fun SettingScreen( CustomReminderDialog( openDialog = openWaterUnitDialog, items = waterUnit, - title = "Water Unit" + title = "Water Unit", ) } } @@ -129,7 +150,7 @@ fun SettingScreen( CustomReminderDialog( openDialog = openWeightUnitDialog, items = weightUnit, - title = "Weight Unit" + title = "Weight Unit", ) } } @@ -141,29 +162,29 @@ fun SettingScreen( fun UnitsWaterIntake( openTimeFormatDialog: MutableState, openWaterUnitDialog: MutableState, - openWeightUnitDialog: MutableState + openWeightUnitDialog: MutableState, ) { Card( modifier = Modifier .fillMaxWidth() .padding(top = 8.dp, start = 16.dp, end = 16.dp), - elevation = 4.dp + elevation = 4.dp, ) { Column( - modifier = Modifier.padding(8.dp) + modifier = Modifier.padding(8.dp), ) { Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = "Water Unit", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor + color = blackColor, ) TextButton(onClick = { openWaterUnitDialog.value = true }) { @@ -171,7 +192,7 @@ fun UnitsWaterIntake( text = "ml", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor + color = primaryColor, ) } } @@ -180,20 +201,20 @@ fun UnitsWaterIntake( .height(1.dp) .padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp + thickness = 1.dp, ) Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = "Weight Unit", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor + color = blackColor, ) TextButton(onClick = { openWeightUnitDialog.value = true }) { @@ -201,7 +222,7 @@ fun UnitsWaterIntake( text = "Kg", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor + color = primaryColor, ) } } @@ -210,27 +231,27 @@ fun UnitsWaterIntake( .height(1.dp) .padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp + thickness = 1.dp, ) Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = "Time Format", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor + color = blackColor, ) TextButton(onClick = { openTimeFormatDialog.value = true }) { Text( text = "12 hours", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor + color = primaryColor, ) } } @@ -245,67 +266,71 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { modifier = Modifier .fillMaxWidth() .padding(top = 8.dp, start = 16.dp, end = 16.dp, bottom = 16.dp), - elevation = 4.dp + elevation = 4.dp, ) { Column( - modifier = Modifier.padding(8.dp) + modifier = Modifier.padding(8.dp), ) { Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Row( - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = "Reminder Mode", - fontSize = 16.sp, - fontWeight = FontWeight.W400, - color = blackColor - ) - } - IconButton(onClick = { - }) { - Image( - painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null - ) - } - } - Divider( - modifier = Modifier - .height(1.dp) - .padding(start = 8.dp, end = 8.dp), - color = Color.Gray, - thickness = 1.dp - ) - Row( - modifier = Modifier - .fillMaxWidth() - .padding(8.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Row( - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Text( text = "Reminder Sound", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor + color = blackColor, ) } IconButton(onClick = { - val intent = Intent(MediaStore.INTENT_ACTION_MUSIC_PLAYER) - context.startActivity(intent) + try { + if (checkSystemWritePermission(context = context)) { + val ringtoneManager = RingtoneManager(context) + ringtoneManager.setType(RingtoneManager.TYPE_NOTIFICATION) + val cursor = ringtoneManager.cursor + val titles = Array(cursor.count) { null } + val uris = Array(cursor.count) { null } + cursor.moveToFirst() + for (i in 0 until cursor.count) { + titles[i] = cursor.getString(RingtoneManager.TITLE_COLUMN_INDEX) + uris[i] = ringtoneManager.getRingtoneUri(i) + cursor.moveToNext() + } + + val builder = android.app.AlertDialog.Builder(context) + builder.setTitle("Select a notification tone") + builder.setItems(titles) { _, which -> + + val mediaPlayer = MediaPlayer.create(context, uris[which]) + mediaPlayer.start() + + RingtoneManager.setActualDefaultRingtoneUri( + context, + RingtoneManager.TYPE_NOTIFICATION, + uris[which], + ) + } + builder.show() + } else { + Toast.makeText( + context, + "Allow modify system settings ==> ON ", + Toast.LENGTH_LONG, + ).show() + } + } catch (e: Exception) { + Toast.makeText(context, "unable to set as Ringtone ", Toast.LENGTH_SHORT).show() + } }) { Image( painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null + contentDescription = null, ) } } @@ -314,23 +339,23 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { .height(1.dp) .padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp + thickness = 1.dp, ) Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Row( - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Text( text = "Notifications", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor + color = blackColor, ) } IconButton(onClick = { @@ -338,7 +363,7 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { }) { Image( painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null + contentDescription = null, ) } } @@ -349,75 +374,33 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { @Composable fun Goals( openDialog: MutableState, - openGenderDialog: MutableState + currentIntake: String, + currentForm: String, ) { Card( modifier = Modifier .fillMaxWidth() .padding(top = 8.dp, start = 16.dp, end = 16.dp), - elevation = 4.dp + elevation = 4.dp, ) { Column( - modifier = Modifier.padding(8.dp) + modifier = Modifier.padding(8.dp), ) { Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { - Row( - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = "Gender", - fontSize = 16.sp, - fontWeight = FontWeight.W400, - color = blackColor - ) - } Row( verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier.clickable { - openGenderDialog.value = true - } - ) { - Text( - text = "Male", - fontSize = 16.sp, - fontWeight = FontWeight.W300, - color = primaryColor - ) - Image( - painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null - ) - } - } - Divider( - modifier = Modifier - .height(1.dp) - .padding(start = 8.dp, end = 8.dp), - color = Color.Gray, - thickness = 1.dp - ) - Row( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Row( - verticalAlignment = Alignment.CenterVertically ) { Text( text = "Intake Goal", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor + color = blackColor, ) } Row( @@ -425,20 +408,31 @@ fun Goals( horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.clickable { openDialog.value = true - } + }, ) { Text( - text = "2400ml", + text = "$currentIntake $currentForm", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor + color = primaryColor, ) Image( painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null + contentDescription = null, ) } } } } } + +private fun checkSystemWritePermission(context: Context): Boolean { + if (Settings.System.canWrite(context)) return true else openAndroidPermissionsMenu(context) + return false +} + +private fun openAndroidPermissionsMenu(context: Context) { + val intent = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS) + intent.setData(Uri.parse("package:" + context.getPackageName())) + context.startActivity(intent) +} From adc3502abd4ad02a11f99deb1c0372bfcfecff72 Mon Sep 17 00:00:00 2001 From: brandy-kay Date: Thu, 24 Aug 2023 20:19:31 +0300 Subject: [PATCH 08/10] fixed is achieved and graphs --- .../brandyodhiambo/quench/ui/MainActivity.kt | 2 + .../brandyodhiambo/common/util/Function.kt | 10 -- .../presentation/homeScreen/HomeScreen.kt | 125 +++++++-------- .../statistics/worker/WorkerRequest.kt | 147 ++++++++---------- .../worker/achievement/AchievementWorker.kt | 40 +++++ .../worker/dailyWorker/DailyWorker.kt | 36 ++--- .../worker/monthlyWorker/MonthlyWorker.kt | 19 +-- .../worker/weeklyWorker/WeeklyWorker.kt | 22 +-- 8 files changed, 191 insertions(+), 210 deletions(-) create mode 100644 feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt diff --git a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt index d017aa0..68123c4 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt @@ -36,6 +36,7 @@ import com.brandyodhiambo.quench.navigation.FeatureNavigator import com.brandyodhiambo.quench.navigation.NavGraphs import com.brandyodhiambo.quench.util.AlarmSchedularImpl import com.brandyodhiambo.quench.util.createChannel +import com.brandyodhiambo.statistics.worker.startAchievementOnetimeWorkRequest import com.brandyodhiambo.statistics.worker.startDailyOnetimeWorkRequest import com.brandyodhiambo.statistics.worker.startMonthlyOnetimeWorkRequest import com.brandyodhiambo.statistics.worker.startWeeklyOnetimeWorkRequest @@ -66,6 +67,7 @@ class MainActivity : ComponentActivity() { startDailyOnetimeWorkRequest(applicationContext) startMonthlyOnetimeWorkRequest(applicationContext) startWeeklyOnetimeWorkRequest(applicationContext) + startAchievementOnetimeWorkRequest(applicationContext) val reminderTimeFromDb = viewModel.reminderTime.observeAsState() val hours = reminderTimeFromDb.value?.hour ?: 0 diff --git a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt index fc96798..5d6dbdb 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt @@ -70,16 +70,6 @@ fun getCurrentYear(): String { return now.year.toString() } -fun isEndOfDay(dateTime: LocalDateTime): Boolean { - val currentHour = dateTime.hour - val currentMinute = dateTime.minute - - val endOfDayHour = 23 - val endOfDayMinute = 59 - - return currentHour >= endOfDayHour && currentMinute >= endOfDayMinute -} - suspend fun LiveData.awaitValue(): T = withContext(Dispatchers.Default) { val flow = MutableSharedFlow(replay = 1) val observer = androidx.lifecycle.Observer { diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt index 991a2d8..2dbb359 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt @@ -57,7 +57,6 @@ import androidx.compose.ui.unit.sp import androidx.compose.ui.window.Dialog import androidx.hilt.navigation.compose.hiltViewModel import com.brandyodhiambo.common.R -import com.brandyodhiambo.common.domain.model.Achievement import com.brandyodhiambo.common.domain.model.Days import com.brandyodhiambo.common.domain.model.GoalWaterIntake import com.brandyodhiambo.common.domain.model.IdealWaterIntake @@ -65,8 +64,6 @@ import com.brandyodhiambo.common.domain.model.Level import com.brandyodhiambo.common.domain.model.ReminderTime import com.brandyodhiambo.common.domain.model.SelectedDrink import com.brandyodhiambo.common.presentation.component.WaterIntakeDialog -import com.brandyodhiambo.common.util.getCurrentDay -import com.brandyodhiambo.common.util.isEndOfDay import com.brandyodhiambo.designsystem.components.CircularButton import com.brandyodhiambo.designsystem.theme.lightBlue import com.brandyodhiambo.designsystem.theme.primaryColor @@ -80,14 +77,13 @@ import com.brandyodhiambo.home.presentation.component.IdealIntakeGoalDialog import com.brandyodhiambo.home.presentation.component.SelectDrinkComposable import com.brandyodhiambo.home.presentation.component.TimeSetterDialog import com.ramcosta.composedestinations.annotation.Destination -import java.time.LocalDateTime @SuppressLint("UnusedMaterialScaffoldPaddingParameter") @Destination @Composable fun HomeScreen( viewModel: HomeViewModel = hiltViewModel(), - achievementViewModel: AchievementViewModel = hiltViewModel() + achievementViewModel: AchievementViewModel = hiltViewModel(), ) { val openTimeDialog = remember { mutableStateOf(false) } val openDeleteDialog = remember { mutableStateOf(false) } @@ -115,12 +111,12 @@ fun HomeScreen( val minute = reminderTimeFromDb.value?.minute Scaffold( - backgroundColor = primaryColor + backgroundColor = primaryColor, ) { paddingValues -> Box( modifier = Modifier .fillMaxSize() - .padding(paddingValues) + .padding(paddingValues), ) { LazyColumn { item { @@ -130,7 +126,7 @@ fun HomeScreen( waterIntake = waterIntake, form = waterIntakeForm, goalForm = goalForm, - goalWaterIntake = goalWaterIntake + goalWaterIntake = goalWaterIntake, ) } item { @@ -149,16 +145,16 @@ fun HomeScreen( val (amount, taken) = incrementProgressCircle( selectedDrinksFromDB = selectedDrinksFromDB, goalWaterIntake = goalWaterIntake, - viewModel = viewModel + viewModel = viewModel, ) viewModel.deleteAllLevels() viewModel.insertLevel( Level( amountTaken = amount, - waterTaken = taken - ) + waterTaken = taken, + ), ) - } + }, ) } item { @@ -182,7 +178,7 @@ fun HomeScreen( openEmptyStateDialog.value = false selectedDrinkDialog.value = true }, - onDismiss = { openEmptyStateDialog.value = false } + onDismiss = { openEmptyStateDialog.value = false }, ) } } @@ -195,7 +191,7 @@ fun HomeScreen( onConfirmClick = { id -> viewModel.deleteOneSelectedDrink(id) openDeleteDialog.value = false - } + }, ) } } @@ -212,20 +208,11 @@ fun HomeScreen( }, onOkayClicked = { openCongratulationsDialog.value = false - } + }, ) } } - if (isEndOfDay(LocalDateTime.now()) && openCongratulationsDialog.value) { - achievementViewModel.insertIsAchieved( - Achievement( - isAchieved = true, - day = getCurrentDay() - ) - ) - } - if (openTimeDialog.value) { Dialog(onDismissRequest = { openTimeDialog.value }) { TimeSetterDialog( @@ -237,7 +224,7 @@ fun HomeScreen( }, onAllDayClicked = { viewModel.onAllDaySelected( - isAllDay = true + isAllDay = true, ) viewModel.reminderDays.value = listOf( Days("M", viewModel.isAllDaySelected.value), @@ -246,7 +233,7 @@ fun HomeScreen( Days("T", viewModel.isAllDaySelected.value), Days("F", viewModel.isAllDaySelected.value), Days("S", viewModel.isAllDaySelected.value), - Days("S", viewModel.isAllDaySelected.value) + Days("S", viewModel.isAllDaySelected.value), ) }, onConfirmClick = { @@ -263,7 +250,7 @@ fun HomeScreen( amPm = ampm, isReapeated = false, isAllDay = viewModel.isAllDaySelected.value, - days = viewModel.reminderDays.value + days = viewModel.reminderDays.value, ) if (viewModel.reminderTime.value != null) { viewModel.deleteAllRemindTime() @@ -275,10 +262,10 @@ fun HomeScreen( ampm = viewModel.reminderSelectedTime.value.ampm, isRepeated = false, isAllDay = viewModel.isAllDaySelected.value, - days = viewModel.reminderDays.value - ) + days = viewModel.reminderDays.value, + ), ) - } + }, ) } } @@ -298,10 +285,10 @@ fun HomeScreen( onOkayClick = { val goalWaterIntakeToInsert = GoalWaterIntake( waterIntake = viewModel.goalWaterIntakeValue.value.toInt(), - form = viewModel.goalWaterForm.value + form = viewModel.goalWaterForm.value, ) viewModel.insertGoalWaterIntake(goalWaterIntakeToInsert) - } + }, ) } } @@ -321,10 +308,10 @@ fun HomeScreen( onOkayClick = { val idealWaterIntakeToInsert = IdealWaterIntake( waterIntake = viewModel.idealWaterIntakeValue.value.toInt(), - form = viewModel.idealWaterForm.value + form = viewModel.idealWaterForm.value, ) viewModel.insertIdealWaterIntake(idealWaterIntakeToInsert) - } + }, ) } } @@ -347,10 +334,10 @@ fun HomeScreen( SelectedDrink( drinkValue = viewModel.size.value, icon = viewModel.selectedIcon.value, - time = viewModel.selectedTime.value - ) + time = viewModel.selectedTime.value, + ), ) - } + }, ) } } @@ -361,7 +348,7 @@ fun HomeScreen( private fun incrementProgressCircle( selectedDrinksFromDB: State>, goalWaterIntake: Int, - viewModel: HomeViewModel + viewModel: HomeViewModel, ): Pair { // getting the last selected drink var amountTaken = viewModel.levelFromDB.value?.amountTaken ?: 0f @@ -409,49 +396,49 @@ fun WaterIntake( waterIntake: Int, form: String, goalForm: String, - goalWaterIntake: Int + goalWaterIntake: Int, ) { Card( modifier = Modifier .height(100.dp) .padding(16.dp) .fillMaxWidth(), - elevation = 4.dp + elevation = 4.dp, ) { Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), horizontalArrangement = Arrangement.SpaceEvenly, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Image( painter = painterResource(id = R.drawable.ic_glass), - contentDescription = null + contentDescription = null, ) Spacer(modifier = Modifier.width(8.dp)) Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.clickable { idealWaterIntakeDialog.value = true - } + }, ) { Text( text = "Ideal water intake", fontSize = 14.sp, color = Color.Gray, - fontFamily = roboto + fontFamily = roboto, ) Text( text = "$waterIntake $form", fontSize = 16.sp, color = Color.Gray, fontWeight = FontWeight.Bold, - fontFamily = roboto + fontFamily = roboto, ) } } @@ -460,11 +447,11 @@ fun WaterIntake( .fillMaxHeight() .width(2.dp), thickness = 2.dp, - color = primaryColor + color = primaryColor, ) Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Image(painter = painterResource(id = R.drawable.ic_cup), contentDescription = null) Spacer(modifier = Modifier.width(8.dp)) @@ -472,20 +459,20 @@ fun WaterIntake( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.clickable { openGoalDialog.value = true - } + }, ) { Text( text = "Water intake goal", fontSize = 14.sp, color = Color.Gray, - fontFamily = roboto + fontFamily = roboto, ) Text( text = "$goalWaterIntake $goalForm", fontSize = 16.sp, color = Color.Gray, fontWeight = FontWeight.Bold, - fontFamily = roboto + fontFamily = roboto, ) } } @@ -501,32 +488,32 @@ fun WaterRecord( time: String, goalWaterIntake: Int, selectedDrinkDialog: MutableState, - onAddLevelClick: () -> Unit + onAddLevelClick: () -> Unit, ) { Card( modifier = Modifier .fillMaxWidth() .height(350.dp) .padding(start = 16.dp, end = 16.dp), - elevation = 4.dp + elevation = 4.dp, ) { Column( modifier = Modifier .fillMaxSize() .padding(8.dp), - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { Spacer(modifier = Modifier.height(8.dp)) CircularRating( percentage = amountTaken, drunk = waterTaken, - goal = goalWaterIntake + goal = goalWaterIntake, ) Spacer(modifier = Modifier.height(8.dp)) Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceEvenly + horizontalArrangement = Arrangement.SpaceEvenly, ) { CircularButton( backgroundColor = lightBlue, @@ -534,7 +521,7 @@ fun WaterRecord( title = time, onClick = { openDialog.value = true - } + }, ) CircularButton( backgroundColor = lightBlue, @@ -542,7 +529,7 @@ fun WaterRecord( title = "Add Level", onClick = { onAddLevelClick() - } + }, ) CircularButton( backgroundColor = lightBlue, @@ -550,7 +537,7 @@ fun WaterRecord( title = "Add Drink", onClick = { selectedDrinkDialog.value = true - } + }, ) } } @@ -560,13 +547,13 @@ fun WaterRecord( @Composable fun WaterIntakeTimeAndLevel( intake: SelectedDrink, - onDeleteIconClick: (SelectedDrink) -> Unit + onDeleteIconClick: (SelectedDrink) -> Unit, ) { Column( modifier = Modifier .fillMaxSize() .padding(start = 16.dp, end = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { Row( modifier = Modifier @@ -574,48 +561,48 @@ fun WaterIntakeTimeAndLevel( .background(Color.White) .padding(4.dp), horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Row( horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Icon( modifier = Modifier.size(20.dp), painter = painterResource(id = intake.icon), tint = primaryColor, - contentDescription = null + contentDescription = null, ) Text( text = intake.drinkValue, fontFamily = roboto, fontSize = 16.sp, - fontWeight = FontWeight.W400 + fontWeight = FontWeight.W400, ) } Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Text( text = intake.time, fontSize = 14.sp, color = Color.Gray, fontFamily = roboto, - fontWeight = FontWeight.W300 + fontWeight = FontWeight.W300, ) IconButton(onClick = { onDeleteIconClick(intake) }) { Icon( imageVector = Icons.Default.Delete, tint = Color.Gray, - contentDescription = null + contentDescription = null, ) } } } Divider( thickness = 1.dp, - color = Color.Gray + color = Color.Gray, ) } } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt index 642eabc..649b2f8 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/WorkerRequest.kt @@ -16,20 +16,15 @@ package com.brandyodhiambo.statistics.worker import android.content.Context -import androidx.work.BackoffPolicy import androidx.work.Constraints -import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.NetworkType import androidx.work.OneTimeWorkRequestBuilder -import androidx.work.PeriodicWorkRequest -import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkManager +import com.brandyodhiambo.statistics.worker.achievement.AchievementWorker import com.brandyodhiambo.statistics.worker.dailyWorker.DailyWorker -import com.brandyodhiambo.statistics.worker.dailyWorker.DailyWorker.Companion.DAILY_WORK_NAME import com.brandyodhiambo.statistics.worker.monthlyWorker.MonthlyWorker -import com.brandyodhiambo.statistics.worker.monthlyWorker.MonthlyWorker.Companion.MONTHLY_WORK_NAME import com.brandyodhiambo.statistics.worker.weeklyWorker.WeeklyWorker -import com.brandyodhiambo.statistics.worker.weeklyWorker.WeeklyWorker.Companion.WEEKLY_WORK_NAME +import java.util.Calendar import java.util.concurrent.TimeUnit fun startDailyOnetimeWorkRequest(context: Context) { @@ -37,42 +32,26 @@ fun startDailyOnetimeWorkRequest(context: Context) { .setRequiredNetworkType(NetworkType.NOT_REQUIRED) .build() - val dailyWorkRequest = OneTimeWorkRequestBuilder() - .setConstraints(constraints) - .setBackoffCriteria( - BackoffPolicy.LINEAR, - PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, - TimeUnit.MILLISECONDS - ) - .build() + val currentDate = Calendar.getInstance() + val midnight = Calendar.getInstance().apply { + set(Calendar.HOUR_OF_DAY, 23) + set(Calendar.MINUTE, 59) + set(Calendar.SECOND, 0) + set(Calendar.MILLISECOND, 0) + } - WorkManager.getInstance(context).enqueue(dailyWorkRequest) -} + if (currentDate.after(midnight)) { + midnight.add(Calendar.DAY_OF_MONTH, 1) + } -fun startDailyPeriodicWorkRequest(context: Context) { - val constraints = Constraints.Builder() - .setRequiredNetworkType(NetworkType.NOT_REQUIRED) - .setRequiresBatteryNotLow(true) - .setRequiresCharging(true) - .build() + val timeDiff = midnight.timeInMillis - currentDate.timeInMillis - val workRequest = PeriodicWorkRequestBuilder( - 1, - TimeUnit.DAYS - ) + val dailyWorkRequest = OneTimeWorkRequestBuilder() .setConstraints(constraints) - .setBackoffCriteria( - BackoffPolicy.LINEAR, - PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, - TimeUnit.MILLISECONDS - ) + .setInitialDelay(timeDiff, TimeUnit.MILLISECONDS) .build() - WorkManager.getInstance(context).enqueueUniquePeriodicWork( - DAILY_WORK_NAME, - ExistingPeriodicWorkPolicy.REPLACE, - workRequest - ) + WorkManager.getInstance(context).enqueue(dailyWorkRequest) } // weekly requests @@ -81,37 +60,25 @@ fun startWeeklyOnetimeWorkRequest(context: Context) { .setRequiredNetworkType(NetworkType.NOT_REQUIRED) .build() - val weeklyWorkRequest = OneTimeWorkRequestBuilder() - .setConstraints(constraints) - .build() + val currentDate = Calendar.getInstance() - WorkManager.getInstance(context).enqueue(weeklyWorkRequest) -} + val endOfWeek = Calendar.getInstance().apply { + set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY) + set(Calendar.HOUR_OF_DAY, 23) + set(Calendar.MINUTE, 59) + set(Calendar.SECOND, 59) + set(Calendar.MILLISECOND, 999) + add(Calendar.WEEK_OF_YEAR, 1) // Move to the next week + } -fun startWeeklyPeriodicWorkRequest(context: Context) { - val constraints = Constraints.Builder() - .setRequiredNetworkType(NetworkType.NOT_REQUIRED) - .setRequiresBatteryNotLow(true) - .setRequiresCharging(true) - .build() + val timeDiff = endOfWeek.timeInMillis - currentDate.timeInMillis - val workRequest = PeriodicWorkRequestBuilder( - 1, - TimeUnit.DAYS - ) + val weeklyWorkRequest = OneTimeWorkRequestBuilder() .setConstraints(constraints) - .setBackoffCriteria( - BackoffPolicy.LINEAR, - PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, - TimeUnit.MILLISECONDS - ) + .setInitialDelay(timeDiff, TimeUnit.MILLISECONDS) .build() - WorkManager.getInstance(context).enqueueUniquePeriodicWork( - WEEKLY_WORK_NAME, - ExistingPeriodicWorkPolicy.REPLACE, - workRequest - ) + WorkManager.getInstance(context).enqueue(weeklyWorkRequest) } // monthly requests @@ -120,35 +87,53 @@ fun startMonthlyOnetimeWorkRequest(context: Context) { .setRequiredNetworkType(NetworkType.NOT_REQUIRED) .build() - val monthlyWorkRequest = OneTimeWorkRequestBuilder() + val currentDate = Calendar.getInstance() + val endOfMonth = Calendar.getInstance().apply { + set(Calendar.DAY_OF_MONTH, getActualMaximum(Calendar.DAY_OF_MONTH)) + set(Calendar.HOUR_OF_DAY, 23) + set(Calendar.MINUTE, 59) + set(Calendar.SECOND, 59) + set(Calendar.MILLISECOND, 999) + } + + if (currentDate.after(endOfMonth)) { + endOfMonth.add(Calendar.MONTH, 1) + } + + val timeDiff = endOfMonth.timeInMillis - currentDate.timeInMillis + + val endOfMonthWorkRequest = OneTimeWorkRequestBuilder() .setConstraints(constraints) + .setInitialDelay(timeDiff, TimeUnit.MILLISECONDS) .build() - WorkManager.getInstance(context).enqueue(monthlyWorkRequest) + WorkManager.getInstance(context).enqueue(endOfMonthWorkRequest) } -fun startMonthlyPeriodicWorkRequest(context: Context) { +// achievement worker request +fun startAchievementOnetimeWorkRequest(context: Context) { val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.NOT_REQUIRED) - .setRequiresBatteryNotLow(true) - .setRequiresCharging(true) .build() - val workRequest = PeriodicWorkRequestBuilder( - 1, - TimeUnit.DAYS - ) + val currentDate = Calendar.getInstance() + val midnight = Calendar.getInstance().apply { + set(Calendar.HOUR_OF_DAY, 23) + set(Calendar.MINUTE, 59) + set(Calendar.SECOND, 0) + set(Calendar.MILLISECOND, 0) + } + + if (currentDate.after(midnight)) { + midnight.add(Calendar.DAY_OF_MONTH, 1) + } + + val timeDiff = midnight.timeInMillis - currentDate.timeInMillis + + val achievementWorkRequest = OneTimeWorkRequestBuilder() .setConstraints(constraints) - .setBackoffCriteria( - BackoffPolicy.LINEAR, - PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, - TimeUnit.MILLISECONDS - ) + .setInitialDelay(timeDiff, TimeUnit.MILLISECONDS) .build() - WorkManager.getInstance(context).enqueueUniquePeriodicWork( - MONTHLY_WORK_NAME, - ExistingPeriodicWorkPolicy.REPLACE, - workRequest - ) + WorkManager.getInstance(context).enqueue(achievementWorkRequest) } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt new file mode 100644 index 0000000..3e69e91 --- /dev/null +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt @@ -0,0 +1,40 @@ +package com.brandyodhiambo.statistics.worker.achievement + +import android.content.Context +import androidx.hilt.work.HiltWorker +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import com.brandyodhiambo.common.domain.model.Achievement +import com.brandyodhiambo.common.domain.repository.AchievementRepository +import com.brandyodhiambo.common.domain.repository.GoalWaterIntakeRepository +import com.brandyodhiambo.common.domain.repository.LevelRepository +import com.brandyodhiambo.common.util.awaitValue +import com.brandyodhiambo.common.util.getCurrentDay +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject + +@HiltWorker +class AchievementWorker @AssistedInject constructor( + @Assisted context: Context, + @Assisted params: WorkerParameters, + private val achievementRepository: AchievementRepository, + private val levelRepository: LevelRepository, + private val goalWaterIntakeRepository: GoalWaterIntakeRepository, +) : CoroutineWorker(context, params) { + override suspend fun doWork(): Result { + return try { + val amountTaken = levelRepository.getLevel().awaitValue()?.amountTaken ?: 1f + val goalWaterIntake = goalWaterIntakeRepository.getGoalWaterIntake().awaitValue()?.waterIntake ?: 1f + + achievementRepository.insertAchievement( + Achievement( + isAchieved = amountTaken.toInt() >= goalWaterIntake.toInt(), + day = getCurrentDay(), + ), + ) + Result.success() + } catch (e: Exception) { + Result.failure() + } + } +} diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt index 2d55b91..b3aef4a 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt @@ -30,7 +30,6 @@ import com.brandyodhiambo.common.util.awaitValue import com.brandyodhiambo.common.util.getCurrentDay import dagger.assisted.Assisted import dagger.assisted.AssistedInject -import java.time.LocalDateTime @HiltWorker class DailyWorker @AssistedInject constructor( @@ -41,35 +40,24 @@ class DailyWorker @AssistedInject constructor( private val idealWaterIntakeRepository: IdealWaterIntakeRepository, private val selectedDrinkRepository: SelectedDrinkRepository, private val reminderTimeRepository: ReminderTimeRepository, - private val dailyStatisticsRepository: DailyStatisticsRepository + private val dailyStatisticsRepository: DailyStatisticsRepository, ) : CoroutineWorker(context, params) { - companion object { - const val DAILY_WORK_NAME = "com.brandyodhiambo.common.worker.daily_worker.DailyWorker" - private const val TAG = "DailyWorker" - } - override suspend fun doWork(): Result { return try { val amountTaken = levelRepository.getLevel().awaitValue()?.amountTaken ?: 1f - val currentHour = LocalDateTime.now().hour - val currentMinute = LocalDateTime.now().minute + dailyStatisticsRepository.insertDailyStatistics( + DailyStatistics( + amountTaken = amountTaken, + day = getCurrentDay(), + ), + ) + goalWaterIntakeRepository.deleteAllGoalWaterIntakes() + idealWaterIntakeRepository.deleteAllIdealWaterIntakes() + selectedDrinkRepository.deleteAllSelectedDrinks() + reminderTimeRepository.dellAllReminderTimes() + levelRepository.deleteAllLevel() - val endOfDayHour = 23 - val endOfDayMinute = 59 - if (currentHour >= endOfDayHour && currentMinute >= endOfDayMinute) { - dailyStatisticsRepository.insertDailyStatistics( - DailyStatistics( - amountTaken = amountTaken, - day = getCurrentDay() - ) - ) - goalWaterIntakeRepository.deleteAllGoalWaterIntakes() - idealWaterIntakeRepository.deleteAllIdealWaterIntakes() - selectedDrinkRepository.deleteAllSelectedDrinks() - reminderTimeRepository.dellAllReminderTimes() - levelRepository.deleteAllLevel() - } Result.success() } catch (e: Exception) { Result.failure() diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt index f91bb62..17ddcb1 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt @@ -26,15 +26,13 @@ import com.brandyodhiambo.common.util.awaitValue import com.brandyodhiambo.common.util.getCurrentMonth import dagger.assisted.Assisted import dagger.assisted.AssistedInject -import java.time.LocalDate -import java.time.temporal.TemporalAdjusters @HiltWorker class MonthlyWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, private val weeklyStatisticRepository: WeeklyStatisticRepository, - private val monthlyStatisticsRepository: MonthlyStatisticsRepository + private val monthlyStatisticsRepository: MonthlyStatisticsRepository, ) : CoroutineWorker(context, params) { companion object { @@ -50,15 +48,12 @@ class MonthlyWorker @AssistedInject constructor( ?.sumByDouble { it.amountTaken.toDouble() } val totalAmountTaken = amountTaken?.div(4) // 4 weeks in a month - val lastDayOfMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()) - if (LocalDate.now() == lastDayOfMonth) { - monthlyStatisticsRepository.insertMonthlyStatistics( - MonthlyStatistics( - amountTaken = totalAmountTaken?.toFloat() ?: 0f, - month = getCurrentMonth() - ) - ) - } + monthlyStatisticsRepository.insertMonthlyStatistics( + MonthlyStatistics( + amountTaken = totalAmountTaken?.toFloat() ?: 0f, + month = getCurrentMonth(), + ), + ) Result.success() } catch (e: Exception) { diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt index 930cad6..74a4fef 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt @@ -26,16 +26,13 @@ import com.brandyodhiambo.common.util.awaitValue import com.brandyodhiambo.common.util.getCurrentWeekNumber import dagger.assisted.Assisted import dagger.assisted.AssistedInject -import java.time.DayOfWeek -import java.time.LocalDate -import java.time.temporal.TemporalAdjusters @HiltWorker class WeeklyWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, private val dailyStatisticsRepository: DailyStatisticsRepository, - private val weeklyStatisticRepository: WeeklyStatisticRepository + private val weeklyStatisticRepository: WeeklyStatisticRepository, ) : CoroutineWorker(context, params) { companion object { const val WEEKLY_WORK_NAME = "com.brandyodhiambo.common.worker.weekly_worker.WeeklyWorker" @@ -46,17 +43,14 @@ class WeeklyWorker @AssistedInject constructor( return try { val amountTaken = dailyStatisticsRepository.getDailyStatistics().awaitValue() ?.sumByDouble { it.amountTaken.toDouble() } - val totalAmountTaken = amountTaken?.div(7) // 7 days in a week + val totalAmountTaken = amountTaken?.div(7) - val lastDayOfWeek = LocalDate.now().with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)) - if (LocalDate.now() == lastDayOfWeek) { - weeklyStatisticRepository.insertWeeklyStatistic( - WeeklyStatistics( - amountTaken = totalAmountTaken?.toFloat() ?: 0f, - week = getCurrentWeekNumber().toString() - ) - ) - } + weeklyStatisticRepository.insertWeeklyStatistic( + WeeklyStatistics( + amountTaken = totalAmountTaken?.toFloat() ?: 0f, + week = getCurrentWeekNumber().toString(), + ), + ) Result.success() } catch (e: Exception) { From 30af7a230c16b6da8611e48157cff561a370ab51 Mon Sep 17 00:00:00 2001 From: brandy-kay Date: Fri, 25 Aug 2023 15:26:17 +0300 Subject: [PATCH 09/10] fixes achievement worker --- .github/workflows/android_build.yml | 8 +- .../brandyodhiambo/quench/ui/MainScreen.kt | 3 - .../brandyodhiambo/common/util/Function.kt | 23 +--- .../presentation/homeScreen/HomeScreen.kt | 114 +++++++++--------- .../settings/presentation/SettingsScreen.kt | 95 +++++++-------- .../worker/achievement/AchievementWorker.kt | 6 +- .../worker/dailyWorker/DailyWorker.kt | 6 +- .../worker/monthlyWorker/MonthlyWorker.kt | 6 +- .../worker/weeklyWorker/WeeklyWorker.kt | 6 +- 9 files changed, 122 insertions(+), 145 deletions(-) diff --git a/.github/workflows/android_build.yml b/.github/workflows/android_build.yml index 935b358..20d9710 100644 --- a/.github/workflows/android_build.yml +++ b/.github/workflows/android_build.yml @@ -8,9 +8,10 @@ on: jobs: build: + name: 🔨 Build runs-on: ubuntu-latest steps: - - name: Checkout + - name: Checkout code uses: actions/checkout@v2.3.4 - name: Set up JDK 11 @@ -18,8 +19,11 @@ jobs: with: java-version: 11 + - name: Make gradle executable + run: chmod +x ./gradlew + - name: Build with Gradle - run: ./gradlew build + run: ./gradlew build --stacktrace - name: Run Tests run: ./gradlew test diff --git a/app/src/main/java/com/brandyodhiambo/quench/ui/MainScreen.kt b/app/src/main/java/com/brandyodhiambo/quench/ui/MainScreen.kt index 8c72200..5c31d5d 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/ui/MainScreen.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/ui/MainScreen.kt @@ -16,8 +16,6 @@ package com.brandyodhiambo.quench.ui import android.annotation.SuppressLint -import android.os.Build -import androidx.annotation.RequiresApi import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material.Icon @@ -49,7 +47,6 @@ import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.navigation.DestinationsNavigator import kotlinx.coroutines.launch -@RequiresApi(Build.VERSION_CODES.O) @OptIn(ExperimentalPagerApi::class) @SuppressLint("UnusedMaterialScaffoldPaddingParameter") @Composable diff --git a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt index 5d6dbdb..d557a27 100644 --- a/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt +++ b/core/common/src/main/java/com/brandyodhiambo/common/util/Function.kt @@ -15,32 +15,17 @@ */ package com.brandyodhiambo.common.util -import android.annotation.SuppressLint import androidx.lifecycle.LiveData import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.withContext -import java.text.SimpleDateFormat import java.time.LocalDate import java.time.LocalDateTime import java.time.format.TextStyle import java.time.temporal.WeekFields import java.util.* -@SuppressLint("SimpleDateFormat") -fun formatDate(timestamp: Long): String { - val df1 = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") -/* val timeZone = TimeZone.getDefault() - df1.timeZone = timeZone*/ - val result = Date(timestamp) - val startCalendar = Calendar.getInstance() - startCalendar.time = result - val format = SimpleDateFormat("EEEE, MMMM d, yyyy 'at' hh:mm a") - - return format.format(startCalendar.time) -} - fun String.toInitials(): String { return this .split(' ') @@ -53,6 +38,7 @@ fun getCurrentDay(): String { val currentDayOfWeek = now.dayOfWeek return currentDayOfWeek.getDisplayName(TextStyle.FULL, Locale.getDefault()) } + fun getCurrentMonth(): String { val now = LocalDateTime.now() val currentMonth = now.month @@ -65,11 +51,6 @@ fun getCurrentWeekNumber(): Int { return now.get(weekFields.weekOfWeekBasedYear()) } -fun getCurrentYear(): String { - val now = LocalDateTime.now() - return now.year.toString() -} - suspend fun LiveData.awaitValue(): T = withContext(Dispatchers.Default) { val flow = MutableSharedFlow(replay = 1) val observer = androidx.lifecycle.Observer { @@ -80,7 +61,7 @@ suspend fun LiveData.awaitValue(): T = withContext(Dispatchers.Default) { observeForever(observer) } try { - flow.first { value -> + flow.first { withContext(Dispatchers.Main) { removeObserver(observer) } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt index 2dbb359..33d1622 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt @@ -68,7 +68,6 @@ import com.brandyodhiambo.designsystem.components.CircularButton import com.brandyodhiambo.designsystem.theme.lightBlue import com.brandyodhiambo.designsystem.theme.primaryColor import com.brandyodhiambo.designsystem.theme.roboto -import com.brandyodhiambo.home.presentation.achievement.AchievementViewModel import com.brandyodhiambo.home.presentation.component.CircularRating import com.brandyodhiambo.home.presentation.component.CongratulationsDialog import com.brandyodhiambo.home.presentation.component.DeleteDialog @@ -82,8 +81,7 @@ import com.ramcosta.composedestinations.annotation.Destination @Destination @Composable fun HomeScreen( - viewModel: HomeViewModel = hiltViewModel(), - achievementViewModel: AchievementViewModel = hiltViewModel(), + viewModel: HomeViewModel = hiltViewModel() ) { val openTimeDialog = remember { mutableStateOf(false) } val openDeleteDialog = remember { mutableStateOf(false) } @@ -111,12 +109,12 @@ fun HomeScreen( val minute = reminderTimeFromDb.value?.minute Scaffold( - backgroundColor = primaryColor, + backgroundColor = primaryColor ) { paddingValues -> Box( modifier = Modifier .fillMaxSize() - .padding(paddingValues), + .padding(paddingValues) ) { LazyColumn { item { @@ -126,7 +124,7 @@ fun HomeScreen( waterIntake = waterIntake, form = waterIntakeForm, goalForm = goalForm, - goalWaterIntake = goalWaterIntake, + goalWaterIntake = goalWaterIntake ) } item { @@ -145,16 +143,16 @@ fun HomeScreen( val (amount, taken) = incrementProgressCircle( selectedDrinksFromDB = selectedDrinksFromDB, goalWaterIntake = goalWaterIntake, - viewModel = viewModel, + viewModel = viewModel ) viewModel.deleteAllLevels() viewModel.insertLevel( Level( amountTaken = amount, - waterTaken = taken, - ), + waterTaken = taken + ) ) - }, + } ) } item { @@ -178,7 +176,7 @@ fun HomeScreen( openEmptyStateDialog.value = false selectedDrinkDialog.value = true }, - onDismiss = { openEmptyStateDialog.value = false }, + onDismiss = { openEmptyStateDialog.value = false } ) } } @@ -191,7 +189,7 @@ fun HomeScreen( onConfirmClick = { id -> viewModel.deleteOneSelectedDrink(id) openDeleteDialog.value = false - }, + } ) } } @@ -208,7 +206,7 @@ fun HomeScreen( }, onOkayClicked = { openCongratulationsDialog.value = false - }, + } ) } } @@ -224,7 +222,7 @@ fun HomeScreen( }, onAllDayClicked = { viewModel.onAllDaySelected( - isAllDay = true, + isAllDay = true ) viewModel.reminderDays.value = listOf( Days("M", viewModel.isAllDaySelected.value), @@ -233,7 +231,7 @@ fun HomeScreen( Days("T", viewModel.isAllDaySelected.value), Days("F", viewModel.isAllDaySelected.value), Days("S", viewModel.isAllDaySelected.value), - Days("S", viewModel.isAllDaySelected.value), + Days("S", viewModel.isAllDaySelected.value) ) }, onConfirmClick = { @@ -250,7 +248,7 @@ fun HomeScreen( amPm = ampm, isReapeated = false, isAllDay = viewModel.isAllDaySelected.value, - days = viewModel.reminderDays.value, + days = viewModel.reminderDays.value ) if (viewModel.reminderTime.value != null) { viewModel.deleteAllRemindTime() @@ -262,10 +260,10 @@ fun HomeScreen( ampm = viewModel.reminderSelectedTime.value.ampm, isRepeated = false, isAllDay = viewModel.isAllDaySelected.value, - days = viewModel.reminderDays.value, - ), + days = viewModel.reminderDays.value + ) ) - }, + } ) } } @@ -285,10 +283,10 @@ fun HomeScreen( onOkayClick = { val goalWaterIntakeToInsert = GoalWaterIntake( waterIntake = viewModel.goalWaterIntakeValue.value.toInt(), - form = viewModel.goalWaterForm.value, + form = viewModel.goalWaterForm.value ) viewModel.insertGoalWaterIntake(goalWaterIntakeToInsert) - }, + } ) } } @@ -308,10 +306,10 @@ fun HomeScreen( onOkayClick = { val idealWaterIntakeToInsert = IdealWaterIntake( waterIntake = viewModel.idealWaterIntakeValue.value.toInt(), - form = viewModel.idealWaterForm.value, + form = viewModel.idealWaterForm.value ) viewModel.insertIdealWaterIntake(idealWaterIntakeToInsert) - }, + } ) } } @@ -334,10 +332,10 @@ fun HomeScreen( SelectedDrink( drinkValue = viewModel.size.value, icon = viewModel.selectedIcon.value, - time = viewModel.selectedTime.value, - ), + time = viewModel.selectedTime.value + ) ) - }, + } ) } } @@ -348,7 +346,7 @@ fun HomeScreen( private fun incrementProgressCircle( selectedDrinksFromDB: State>, goalWaterIntake: Int, - viewModel: HomeViewModel, + viewModel: HomeViewModel ): Pair { // getting the last selected drink var amountTaken = viewModel.levelFromDB.value?.amountTaken ?: 0f @@ -396,49 +394,49 @@ fun WaterIntake( waterIntake: Int, form: String, goalForm: String, - goalWaterIntake: Int, + goalWaterIntake: Int ) { Card( modifier = Modifier .height(100.dp) .padding(16.dp) .fillMaxWidth(), - elevation = 4.dp, + elevation = 4.dp ) { Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), horizontalArrangement = Arrangement.SpaceEvenly, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Image( painter = painterResource(id = R.drawable.ic_glass), - contentDescription = null, + contentDescription = null ) Spacer(modifier = Modifier.width(8.dp)) Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.clickable { idealWaterIntakeDialog.value = true - }, + } ) { Text( text = "Ideal water intake", fontSize = 14.sp, color = Color.Gray, - fontFamily = roboto, + fontFamily = roboto ) Text( text = "$waterIntake $form", fontSize = 16.sp, color = Color.Gray, fontWeight = FontWeight.Bold, - fontFamily = roboto, + fontFamily = roboto ) } } @@ -447,11 +445,11 @@ fun WaterIntake( .fillMaxHeight() .width(2.dp), thickness = 2.dp, - color = primaryColor, + color = primaryColor ) Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Image(painter = painterResource(id = R.drawable.ic_cup), contentDescription = null) Spacer(modifier = Modifier.width(8.dp)) @@ -459,20 +457,20 @@ fun WaterIntake( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.clickable { openGoalDialog.value = true - }, + } ) { Text( text = "Water intake goal", fontSize = 14.sp, color = Color.Gray, - fontFamily = roboto, + fontFamily = roboto ) Text( text = "$goalWaterIntake $goalForm", fontSize = 16.sp, color = Color.Gray, fontWeight = FontWeight.Bold, - fontFamily = roboto, + fontFamily = roboto ) } } @@ -488,32 +486,32 @@ fun WaterRecord( time: String, goalWaterIntake: Int, selectedDrinkDialog: MutableState, - onAddLevelClick: () -> Unit, + onAddLevelClick: () -> Unit ) { Card( modifier = Modifier .fillMaxWidth() .height(350.dp) .padding(start = 16.dp, end = 16.dp), - elevation = 4.dp, + elevation = 4.dp ) { Column( modifier = Modifier .fillMaxSize() .padding(8.dp), - horizontalAlignment = Alignment.CenterHorizontally, + horizontalAlignment = Alignment.CenterHorizontally ) { Spacer(modifier = Modifier.height(8.dp)) CircularRating( percentage = amountTaken, drunk = waterTaken, - goal = goalWaterIntake, + goal = goalWaterIntake ) Spacer(modifier = Modifier.height(8.dp)) Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceEvenly, + horizontalArrangement = Arrangement.SpaceEvenly ) { CircularButton( backgroundColor = lightBlue, @@ -521,7 +519,7 @@ fun WaterRecord( title = time, onClick = { openDialog.value = true - }, + } ) CircularButton( backgroundColor = lightBlue, @@ -529,7 +527,7 @@ fun WaterRecord( title = "Add Level", onClick = { onAddLevelClick() - }, + } ) CircularButton( backgroundColor = lightBlue, @@ -537,7 +535,7 @@ fun WaterRecord( title = "Add Drink", onClick = { selectedDrinkDialog.value = true - }, + } ) } } @@ -547,13 +545,13 @@ fun WaterRecord( @Composable fun WaterIntakeTimeAndLevel( intake: SelectedDrink, - onDeleteIconClick: (SelectedDrink) -> Unit, + onDeleteIconClick: (SelectedDrink) -> Unit ) { Column( modifier = Modifier .fillMaxSize() .padding(start = 16.dp, end = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, + horizontalAlignment = Alignment.CenterHorizontally ) { Row( modifier = Modifier @@ -561,48 +559,48 @@ fun WaterIntakeTimeAndLevel( .background(Color.White) .padding(4.dp), horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Row( horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Icon( modifier = Modifier.size(20.dp), painter = painterResource(id = intake.icon), tint = primaryColor, - contentDescription = null, + contentDescription = null ) Text( text = intake.drinkValue, fontFamily = roboto, fontSize = 16.sp, - fontWeight = FontWeight.W400, + fontWeight = FontWeight.W400 ) } Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = intake.time, fontSize = 14.sp, color = Color.Gray, fontFamily = roboto, - fontWeight = FontWeight.W300, + fontWeight = FontWeight.W300 ) IconButton(onClick = { onDeleteIconClick(intake) }) { Icon( imageVector = Icons.Default.Delete, tint = Color.Gray, - contentDescription = null, + contentDescription = null ) } } } Divider( thickness = 1.dp, - color = Color.Gray, + color = Color.Gray ) } } diff --git a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt index b598e6e..aa484fb 100644 --- a/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt +++ b/feature/settings/src/main/java/com/brandyodhiambo/settings/presentation/SettingsScreen.kt @@ -21,11 +21,8 @@ import android.content.Intent import android.media.MediaPlayer import android.media.RingtoneManager import android.net.Uri -import android.os.Build -import android.provider.MediaStore import android.provider.Settings import android.widget.Toast -import androidx.appcompat.app.AppCompatActivity import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* // ktlint-disable no-wildcard-imports @@ -63,7 +60,7 @@ interface SettingsNavigator { @Composable fun SettingScreen( navigator: SettingsNavigator, - homeViewModel: HomeViewModel = hiltViewModel(), + homeViewModel: HomeViewModel = hiltViewModel() ) { val openIntakeDialog = remember { mutableStateOf(false) } val openTimeDialog = remember { mutableStateOf(false) } @@ -73,26 +70,26 @@ fun SettingScreen( val context = LocalContext.current Scaffold( - backgroundColor = primaryColor, + backgroundColor = primaryColor ) { paddingValues -> Box( modifier = Modifier .fillMaxSize() - .padding(paddingValues), + .padding(paddingValues) ) { LazyColumn { item { UnitsWaterIntake( openTimeFormatDialog = openTimeDialog, openWaterUnitDialog = openWaterUnitDialog, - openWeightUnitDialog = openWeightUnitDialog, + openWeightUnitDialog = openWeightUnitDialog ) } item { Goals( openDialog = openIntakeDialog, currentIntake = homeViewModel.goalWaterIntakeValue.value, - currentForm = homeViewModel.goalWaterForm.value, + currentForm = homeViewModel.goalWaterForm.value ) } item { @@ -115,10 +112,10 @@ fun SettingScreen( onOkayClick = { val goalWaterIntakeToInsert = GoalWaterIntake( waterIntake = homeViewModel.goalWaterIntakeValue.value.toInt(), - form = homeViewModel.goalWaterForm.value, + form = homeViewModel.goalWaterForm.value ) homeViewModel.insertGoalWaterIntake(goalWaterIntakeToInsert) - }, + } ) } } @@ -128,7 +125,7 @@ fun SettingScreen( CustomReminderDialog( openDialog = openTimeDialog, items = time, - title = "Time Format", + title = "Time Format" ) } } @@ -139,7 +136,7 @@ fun SettingScreen( CustomReminderDialog( openDialog = openWaterUnitDialog, items = waterUnit, - title = "Water Unit", + title = "Water Unit" ) } } @@ -150,7 +147,7 @@ fun SettingScreen( CustomReminderDialog( openDialog = openWeightUnitDialog, items = weightUnit, - title = "Weight Unit", + title = "Weight Unit" ) } } @@ -162,29 +159,29 @@ fun SettingScreen( fun UnitsWaterIntake( openTimeFormatDialog: MutableState, openWaterUnitDialog: MutableState, - openWeightUnitDialog: MutableState, + openWeightUnitDialog: MutableState ) { Card( modifier = Modifier .fillMaxWidth() .padding(top = 8.dp, start = 16.dp, end = 16.dp), - elevation = 4.dp, + elevation = 4.dp ) { Column( - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(8.dp) ) { Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Text( text = "Water Unit", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) TextButton(onClick = { openWaterUnitDialog.value = true }) { @@ -192,7 +189,7 @@ fun UnitsWaterIntake( text = "ml", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor, + color = primaryColor ) } } @@ -201,20 +198,20 @@ fun UnitsWaterIntake( .height(1.dp) .padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Text( text = "Weight Unit", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) TextButton(onClick = { openWeightUnitDialog.value = true }) { @@ -222,7 +219,7 @@ fun UnitsWaterIntake( text = "Kg", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor, + color = primaryColor ) } } @@ -231,27 +228,27 @@ fun UnitsWaterIntake( .height(1.dp) .padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Text( text = "Time Format", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) TextButton(onClick = { openTimeFormatDialog.value = true }) { Text( text = "12 hours", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor, + color = primaryColor ) } } @@ -266,26 +263,26 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { modifier = Modifier .fillMaxWidth() .padding(top = 8.dp, start = 16.dp, end = 16.dp, bottom = 16.dp), - elevation = 4.dp, + elevation = 4.dp ) { Column( - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(8.dp) ) { Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = "Reminder Sound", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } IconButton(onClick = { @@ -313,7 +310,7 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { RingtoneManager.setActualDefaultRingtoneUri( context, RingtoneManager.TYPE_NOTIFICATION, - uris[which], + uris[which] ) } builder.show() @@ -321,7 +318,7 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { Toast.makeText( context, "Allow modify system settings ==> ON ", - Toast.LENGTH_LONG, + Toast.LENGTH_LONG ).show() } } catch (e: Exception) { @@ -330,7 +327,7 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { }) { Image( painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null, + contentDescription = null ) } } @@ -339,23 +336,23 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { .height(1.dp) .padding(start = 8.dp, end = 8.dp), color = Color.Gray, - thickness = 1.dp, + thickness = 1.dp ) Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = "Notifications", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } IconButton(onClick = { @@ -363,7 +360,7 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { }) { Image( painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null, + contentDescription = null ) } } @@ -375,32 +372,32 @@ fun ReminderWaterIntake(navigator: SettingsNavigator) { fun Goals( openDialog: MutableState, currentIntake: String, - currentForm: String, + currentForm: String ) { Card( modifier = Modifier .fillMaxWidth() .padding(top = 8.dp, start = 16.dp, end = 16.dp), - elevation = 4.dp, + elevation = 4.dp ) { Column( - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(8.dp) ) { Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + horizontalArrangement = Arrangement.SpaceBetween ) { Row( - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = "Intake Goal", fontSize = 16.sp, fontWeight = FontWeight.W400, - color = blackColor, + color = blackColor ) } Row( @@ -408,17 +405,17 @@ fun Goals( horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.clickable { openDialog.value = true - }, + } ) { Text( text = "$currentIntake $currentForm", fontSize = 16.sp, fontWeight = FontWeight.W300, - color = primaryColor, + color = primaryColor ) Image( painter = painterResource(id = R.drawable.ic_chevron_right), - contentDescription = null, + contentDescription = null ) } } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt index 3e69e91..583b959 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt @@ -19,7 +19,7 @@ class AchievementWorker @AssistedInject constructor( @Assisted params: WorkerParameters, private val achievementRepository: AchievementRepository, private val levelRepository: LevelRepository, - private val goalWaterIntakeRepository: GoalWaterIntakeRepository, + private val goalWaterIntakeRepository: GoalWaterIntakeRepository ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { return try { @@ -29,8 +29,8 @@ class AchievementWorker @AssistedInject constructor( achievementRepository.insertAchievement( Achievement( isAchieved = amountTaken.toInt() >= goalWaterIntake.toInt(), - day = getCurrentDay(), - ), + day = getCurrentDay() + ) ) Result.success() } catch (e: Exception) { diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt index b3aef4a..458c569 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/dailyWorker/DailyWorker.kt @@ -40,7 +40,7 @@ class DailyWorker @AssistedInject constructor( private val idealWaterIntakeRepository: IdealWaterIntakeRepository, private val selectedDrinkRepository: SelectedDrinkRepository, private val reminderTimeRepository: ReminderTimeRepository, - private val dailyStatisticsRepository: DailyStatisticsRepository, + private val dailyStatisticsRepository: DailyStatisticsRepository ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { @@ -49,8 +49,8 @@ class DailyWorker @AssistedInject constructor( dailyStatisticsRepository.insertDailyStatistics( DailyStatistics( amountTaken = amountTaken, - day = getCurrentDay(), - ), + day = getCurrentDay() + ) ) goalWaterIntakeRepository.deleteAllGoalWaterIntakes() idealWaterIntakeRepository.deleteAllIdealWaterIntakes() diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt index 17ddcb1..05c5cd4 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/monthlyWorker/MonthlyWorker.kt @@ -32,7 +32,7 @@ class MonthlyWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, private val weeklyStatisticRepository: WeeklyStatisticRepository, - private val monthlyStatisticsRepository: MonthlyStatisticsRepository, + private val monthlyStatisticsRepository: MonthlyStatisticsRepository ) : CoroutineWorker(context, params) { companion object { @@ -51,8 +51,8 @@ class MonthlyWorker @AssistedInject constructor( monthlyStatisticsRepository.insertMonthlyStatistics( MonthlyStatistics( amountTaken = totalAmountTaken?.toFloat() ?: 0f, - month = getCurrentMonth(), - ), + month = getCurrentMonth() + ) ) Result.success() diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt index 74a4fef..a68add5 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/weeklyWorker/WeeklyWorker.kt @@ -32,7 +32,7 @@ class WeeklyWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, private val dailyStatisticsRepository: DailyStatisticsRepository, - private val weeklyStatisticRepository: WeeklyStatisticRepository, + private val weeklyStatisticRepository: WeeklyStatisticRepository ) : CoroutineWorker(context, params) { companion object { const val WEEKLY_WORK_NAME = "com.brandyodhiambo.common.worker.weekly_worker.WeeklyWorker" @@ -48,8 +48,8 @@ class WeeklyWorker @AssistedInject constructor( weeklyStatisticRepository.insertWeeklyStatistic( WeeklyStatistics( amountTaken = totalAmountTaken?.toFloat() ?: 0f, - week = getCurrentWeekNumber().toString(), - ), + week = getCurrentWeekNumber().toString() + ) ) Result.success() From 75f03566b57e907d0fff262d4c25e14553240b1b Mon Sep 17 00:00:00 2001 From: brandy-kay Date: Fri, 25 Aug 2023 16:18:58 +0300 Subject: [PATCH 10/10] fixes achievement worker --- .../brandyodhiambo/quench/ui/MainActivity.kt | 12 +- .../presentation/homeScreen/HomeScreen.kt | 113 +++++++++--------- .../worker/achievement/AchievementWorker.kt | 6 +- 3 files changed, 65 insertions(+), 66 deletions(-) diff --git a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt index 68123c4..e17f875 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt @@ -62,12 +62,12 @@ class MainActivity : ComponentActivity() { QuenchTheme { Surface( modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colors.background + color = MaterialTheme.colors.background, ) { + startAchievementOnetimeWorkRequest(applicationContext) startDailyOnetimeWorkRequest(applicationContext) startMonthlyOnetimeWorkRequest(applicationContext) startWeeklyOnetimeWorkRequest(applicationContext) - startAchievementOnetimeWorkRequest(applicationContext) val reminderTimeFromDb = viewModel.reminderTime.observeAsState() val hours = reminderTimeFromDb.value?.hour ?: 0 @@ -75,7 +75,7 @@ class MainActivity : ComponentActivity() { val scheduler = AlarmSchedularImpl(this) val alarmItem = AlarmData( time = LocalDateTime.now().withHour(hours).withMinute(minutes), - message = getString(R.string.it_s_time_to_drink_water) + message = getString(R.string.it_s_time_to_drink_water), ) alarmItem.let(scheduler::schedule) val navController = rememberAnimatedNavController() @@ -87,9 +87,9 @@ class MainActivity : ComponentActivity() { engine = navHostEngine, dependenciesContainerBuilder = { dependency( - currentNavigator() + currentNavigator(), ) - } + }, ) } } @@ -100,7 +100,7 @@ class MainActivity : ComponentActivity() { fun DestinationScope<*>.currentNavigator(): FeatureNavigator { return FeatureNavigator( navController = navController, - navGraph = navBackStackEntry.destination.navGraph() + navGraph = navBackStackEntry.destination.navGraph(), ) } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt index 33d1622..b8e2f29 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt @@ -81,7 +81,7 @@ import com.ramcosta.composedestinations.annotation.Destination @Destination @Composable fun HomeScreen( - viewModel: HomeViewModel = hiltViewModel() + viewModel: HomeViewModel = hiltViewModel(), ) { val openTimeDialog = remember { mutableStateOf(false) } val openDeleteDialog = remember { mutableStateOf(false) } @@ -109,12 +109,12 @@ fun HomeScreen( val minute = reminderTimeFromDb.value?.minute Scaffold( - backgroundColor = primaryColor + backgroundColor = primaryColor, ) { paddingValues -> Box( modifier = Modifier .fillMaxSize() - .padding(paddingValues) + .padding(paddingValues), ) { LazyColumn { item { @@ -124,7 +124,7 @@ fun HomeScreen( waterIntake = waterIntake, form = waterIntakeForm, goalForm = goalForm, - goalWaterIntake = goalWaterIntake + goalWaterIntake = goalWaterIntake, ) } item { @@ -143,16 +143,16 @@ fun HomeScreen( val (amount, taken) = incrementProgressCircle( selectedDrinksFromDB = selectedDrinksFromDB, goalWaterIntake = goalWaterIntake, - viewModel = viewModel + viewModel = viewModel, ) viewModel.deleteAllLevels() viewModel.insertLevel( Level( amountTaken = amount, - waterTaken = taken - ) + waterTaken = taken, + ), ) - } + }, ) } item { @@ -176,7 +176,7 @@ fun HomeScreen( openEmptyStateDialog.value = false selectedDrinkDialog.value = true }, - onDismiss = { openEmptyStateDialog.value = false } + onDismiss = { openEmptyStateDialog.value = false }, ) } } @@ -189,11 +189,10 @@ fun HomeScreen( onConfirmClick = { id -> viewModel.deleteOneSelectedDrink(id) openDeleteDialog.value = false - } + }, ) } } - if ((waterTaken >= goalWaterIntake) && (goalWaterIntake != 0)) { openCongratulationsDialog.value = true } @@ -206,7 +205,7 @@ fun HomeScreen( }, onOkayClicked = { openCongratulationsDialog.value = false - } + }, ) } } @@ -222,7 +221,7 @@ fun HomeScreen( }, onAllDayClicked = { viewModel.onAllDaySelected( - isAllDay = true + isAllDay = true, ) viewModel.reminderDays.value = listOf( Days("M", viewModel.isAllDaySelected.value), @@ -231,7 +230,7 @@ fun HomeScreen( Days("T", viewModel.isAllDaySelected.value), Days("F", viewModel.isAllDaySelected.value), Days("S", viewModel.isAllDaySelected.value), - Days("S", viewModel.isAllDaySelected.value) + Days("S", viewModel.isAllDaySelected.value), ) }, onConfirmClick = { @@ -248,7 +247,7 @@ fun HomeScreen( amPm = ampm, isReapeated = false, isAllDay = viewModel.isAllDaySelected.value, - days = viewModel.reminderDays.value + days = viewModel.reminderDays.value, ) if (viewModel.reminderTime.value != null) { viewModel.deleteAllRemindTime() @@ -260,10 +259,10 @@ fun HomeScreen( ampm = viewModel.reminderSelectedTime.value.ampm, isRepeated = false, isAllDay = viewModel.isAllDaySelected.value, - days = viewModel.reminderDays.value - ) + days = viewModel.reminderDays.value, + ), ) - } + }, ) } } @@ -283,10 +282,10 @@ fun HomeScreen( onOkayClick = { val goalWaterIntakeToInsert = GoalWaterIntake( waterIntake = viewModel.goalWaterIntakeValue.value.toInt(), - form = viewModel.goalWaterForm.value + form = viewModel.goalWaterForm.value, ) viewModel.insertGoalWaterIntake(goalWaterIntakeToInsert) - } + }, ) } } @@ -306,10 +305,10 @@ fun HomeScreen( onOkayClick = { val idealWaterIntakeToInsert = IdealWaterIntake( waterIntake = viewModel.idealWaterIntakeValue.value.toInt(), - form = viewModel.idealWaterForm.value + form = viewModel.idealWaterForm.value, ) viewModel.insertIdealWaterIntake(idealWaterIntakeToInsert) - } + }, ) } } @@ -332,10 +331,10 @@ fun HomeScreen( SelectedDrink( drinkValue = viewModel.size.value, icon = viewModel.selectedIcon.value, - time = viewModel.selectedTime.value - ) + time = viewModel.selectedTime.value, + ), ) - } + }, ) } } @@ -346,7 +345,7 @@ fun HomeScreen( private fun incrementProgressCircle( selectedDrinksFromDB: State>, goalWaterIntake: Int, - viewModel: HomeViewModel + viewModel: HomeViewModel, ): Pair { // getting the last selected drink var amountTaken = viewModel.levelFromDB.value?.amountTaken ?: 0f @@ -394,49 +393,49 @@ fun WaterIntake( waterIntake: Int, form: String, goalForm: String, - goalWaterIntake: Int + goalWaterIntake: Int, ) { Card( modifier = Modifier .height(100.dp) .padding(16.dp) .fillMaxWidth(), - elevation = 4.dp + elevation = 4.dp, ) { Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), horizontalArrangement = Arrangement.SpaceEvenly, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Image( painter = painterResource(id = R.drawable.ic_glass), - contentDescription = null + contentDescription = null, ) Spacer(modifier = Modifier.width(8.dp)) Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.clickable { idealWaterIntakeDialog.value = true - } + }, ) { Text( text = "Ideal water intake", fontSize = 14.sp, color = Color.Gray, - fontFamily = roboto + fontFamily = roboto, ) Text( text = "$waterIntake $form", fontSize = 16.sp, color = Color.Gray, fontWeight = FontWeight.Bold, - fontFamily = roboto + fontFamily = roboto, ) } } @@ -445,11 +444,11 @@ fun WaterIntake( .fillMaxHeight() .width(2.dp), thickness = 2.dp, - color = primaryColor + color = primaryColor, ) Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Image(painter = painterResource(id = R.drawable.ic_cup), contentDescription = null) Spacer(modifier = Modifier.width(8.dp)) @@ -457,20 +456,20 @@ fun WaterIntake( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.clickable { openGoalDialog.value = true - } + }, ) { Text( text = "Water intake goal", fontSize = 14.sp, color = Color.Gray, - fontFamily = roboto + fontFamily = roboto, ) Text( text = "$goalWaterIntake $goalForm", fontSize = 16.sp, color = Color.Gray, fontWeight = FontWeight.Bold, - fontFamily = roboto + fontFamily = roboto, ) } } @@ -486,32 +485,32 @@ fun WaterRecord( time: String, goalWaterIntake: Int, selectedDrinkDialog: MutableState, - onAddLevelClick: () -> Unit + onAddLevelClick: () -> Unit, ) { Card( modifier = Modifier .fillMaxWidth() .height(350.dp) .padding(start = 16.dp, end = 16.dp), - elevation = 4.dp + elevation = 4.dp, ) { Column( modifier = Modifier .fillMaxSize() .padding(8.dp), - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { Spacer(modifier = Modifier.height(8.dp)) CircularRating( percentage = amountTaken, drunk = waterTaken, - goal = goalWaterIntake + goal = goalWaterIntake, ) Spacer(modifier = Modifier.height(8.dp)) Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceEvenly + horizontalArrangement = Arrangement.SpaceEvenly, ) { CircularButton( backgroundColor = lightBlue, @@ -519,7 +518,7 @@ fun WaterRecord( title = time, onClick = { openDialog.value = true - } + }, ) CircularButton( backgroundColor = lightBlue, @@ -527,7 +526,7 @@ fun WaterRecord( title = "Add Level", onClick = { onAddLevelClick() - } + }, ) CircularButton( backgroundColor = lightBlue, @@ -535,7 +534,7 @@ fun WaterRecord( title = "Add Drink", onClick = { selectedDrinkDialog.value = true - } + }, ) } } @@ -545,13 +544,13 @@ fun WaterRecord( @Composable fun WaterIntakeTimeAndLevel( intake: SelectedDrink, - onDeleteIconClick: (SelectedDrink) -> Unit + onDeleteIconClick: (SelectedDrink) -> Unit, ) { Column( modifier = Modifier .fillMaxSize() .padding(start = 16.dp, end = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { Row( modifier = Modifier @@ -559,48 +558,48 @@ fun WaterIntakeTimeAndLevel( .background(Color.White) .padding(4.dp), horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Row( horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Icon( modifier = Modifier.size(20.dp), painter = painterResource(id = intake.icon), tint = primaryColor, - contentDescription = null + contentDescription = null, ) Text( text = intake.drinkValue, fontFamily = roboto, fontSize = 16.sp, - fontWeight = FontWeight.W400 + fontWeight = FontWeight.W400, ) } Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Text( text = intake.time, fontSize = 14.sp, color = Color.Gray, fontFamily = roboto, - fontWeight = FontWeight.W300 + fontWeight = FontWeight.W300, ) IconButton(onClick = { onDeleteIconClick(intake) }) { Icon( imageVector = Icons.Default.Delete, tint = Color.Gray, - contentDescription = null + contentDescription = null, ) } } } Divider( thickness = 1.dp, - color = Color.Gray + color = Color.Gray, ) } } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt index 583b959..3e69e91 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt @@ -19,7 +19,7 @@ class AchievementWorker @AssistedInject constructor( @Assisted params: WorkerParameters, private val achievementRepository: AchievementRepository, private val levelRepository: LevelRepository, - private val goalWaterIntakeRepository: GoalWaterIntakeRepository + private val goalWaterIntakeRepository: GoalWaterIntakeRepository, ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { return try { @@ -29,8 +29,8 @@ class AchievementWorker @AssistedInject constructor( achievementRepository.insertAchievement( Achievement( isAchieved = amountTaken.toInt() >= goalWaterIntake.toInt(), - day = getCurrentDay() - ) + day = getCurrentDay(), + ), ) Result.success() } catch (e: Exception) {