From 0c183b9cc752f7a773efb98923216bffe8decc07 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:20:38 +0200 Subject: [PATCH 01/21] #40 timer info class and subclasses, used for display of a timer --- .../timer_functional/FunctionalCustomTimer.kt | 4 +++ .../FunctionalEndlessTimer.kt | 4 +++ .../FunctionalPomodoroTimer.kt | 4 +++ .../timer_functional/FunctionalTimer.kt | 4 +++ .../timer_functional/HoursMinutesSeconds.kt | 3 ++ .../local/models/timer_functional/Time.kt | 4 +++ .../local/models/timer_info/BreakTimerInfo.kt | 31 +++++++++++++++++ .../models/timer_info/CustomTimerInfo.kt | 27 +++++++++++++++ .../models/timer_info/EndlessTimerInfo.kt | 25 ++++++++++++++ .../data/local/models/timer_info/TimerInfo.kt | 26 +++++++++++++++ .../data/local/models/timer_info/TimerJson.kt | 16 +++++++++ .../data/local/models/timer_info/TimerType.kt | 7 ++++ .../studeez/domain/ConfigurationService.kt | 4 +++ .../ugent/sel/studeez/domain/Performance.kt | 27 --------------- .../be/ugent/sel/studeez/domain/TimerDAO.kt | 4 +++ .../FirebaseConfigurationService.kt | 4 +++ .../domain/implementation/FirebaseTimerDAO.kt | 4 +++ .../domain/implementation/ToTimerConverter.kt | 33 +++++++++++++++++++ .../timer_overview/TimerOverviewScreen.kt | 2 ++ .../timer_overview/TimerOverviewViewModel.kt | 4 +++ 20 files changed, 210 insertions(+), 27 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/BreakTimerInfo.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/CustomTimerInfo.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/EndlessTimerInfo.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerInfo.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerJson.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerType.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/ConfigurationService.kt delete mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/Performance.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/TimerDAO.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseConfigurationService.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt new file mode 100644 index 0000000..abbb2a2 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.data.local.models.timer_functional + +class FunctionalCustomTimer { +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt new file mode 100644 index 0000000..c602f5c --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.data.local.models.timer_functional + +class FunctionalEndlessTimer { +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt new file mode 100644 index 0000000..f9698be --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.data.local.models.timer_functional + +class FunctionalPomodoroTimer { +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt new file mode 100644 index 0000000..ba1989f --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.data.local.models.timer_functional + +class FunctionalTimer { +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt new file mode 100644 index 0000000..f651a68 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt @@ -0,0 +1,3 @@ +package be.ugent.sel.studeez.data.local.models.timer_functional + +data class HoursMinutesSeconds() diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt new file mode 100644 index 0000000..24e1245 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.data.local.models.timer_functional + +class Time { +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/BreakTimerInfo.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/BreakTimerInfo.kt new file mode 100644 index 0000000..735f917 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/BreakTimerInfo.kt @@ -0,0 +1,31 @@ +package be.ugent.sel.studeez.data.local.models.timer_info + +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer + +class BreakTimerInfo( + name: String, + description: String, + private val studyTime: Int, + private val breakTime: Int, + private val repeats: Int, + id: String = "" +): TimerInfo(id, name, description) { + + + override fun getFunctionalTimer(): FunctionalTimer { + return FunctionalPomodoroTimer(studyTime, breakTime, repeats) + } + + override fun asJson() : Map { + return mapOf( + "type" to "break", + "name" to name, + "description" to description, + "studyTime" to studyTime, + "breakTime" to breakTime, + "repeats" to repeats, + ) + } + +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/CustomTimerInfo.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/CustomTimerInfo.kt new file mode 100644 index 0000000..5e06536 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/CustomTimerInfo.kt @@ -0,0 +1,27 @@ +package be.ugent.sel.studeez.data.local.models.timer_info + +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer + +class CustomTimerInfo( + name: String, + description: String, + private val studyTime: Int, + id: String = "" +): TimerInfo(id, name, description) { + + + override fun getFunctionalTimer(): FunctionalTimer { + return FunctionalCustomTimer(studyTime) + } + + override fun asJson() : Map { + return mapOf( + "type" to "custom", + "name" to name, + "description" to description, + "studyTime" to studyTime, + ) + } + +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/EndlessTimerInfo.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/EndlessTimerInfo.kt new file mode 100644 index 0000000..d459a4e --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/EndlessTimerInfo.kt @@ -0,0 +1,25 @@ +package be.ugent.sel.studeez.data.local.models.timer_info + +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer + +class EndlessTimerInfo( + name: String, + description: String, + id: String = "" +): TimerInfo(id, name, description) { + + + override fun getFunctionalTimer(): FunctionalTimer { + return FunctionalEndlessTimer() + } + + override fun asJson() : Map { + return mapOf( + "type" to "endless", + "name" to name, + "description" to description + ) + } + +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerInfo.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerInfo.kt new file mode 100644 index 0000000..343e7e3 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerInfo.kt @@ -0,0 +1,26 @@ +package be.ugent.sel.studeez.data.local.models.timer_info + +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer + +/** + * Deze klasse stelt de de info van een timer weer. Elke timer heeft een id, naam en descriptie + */ +abstract class TimerInfo( + val id: String, + val name: String, + val description: String +) { + + /** + * Geef de functionele timer terug die kan gebruikt worden tijden een sessie. + */ + abstract fun getFunctionalTimer(): FunctionalTimer + + /** + * Geef deze timer weer als json. Wordt gebruikt om terug op te slaan in de databank. + * TODO implementaties hebben nog hardgecodeerde strings. + */ + abstract fun asJson(): Map + +} + diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerJson.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerJson.kt new file mode 100644 index 0000000..37a7b9f --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerJson.kt @@ -0,0 +1,16 @@ +package be.ugent.sel.studeez.data.local.models.timer_info + +import com.google.firebase.firestore.DocumentId + +/** + * Timers uit de databank (remote config en firestore) worden als eerste stap omgezet naar dit type. + */ +data class TimerJson( + val type: String = "", + val name: String = "", + val description: String = "", + val studyTime: Int = 0, + val breakTime: Int = 0, + val repeats: Int = 0, + @DocumentId val id: String = "" +) diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerType.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerType.kt new file mode 100644 index 0000000..20fb36d --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_info/TimerType.kt @@ -0,0 +1,7 @@ +package be.ugent.sel.studeez.data.local.models.timer_info + +enum class TimerType { + BREAK, + ENDLESS, + CUSTOM +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/ConfigurationService.kt b/app/src/main/java/be/ugent/sel/studeez/domain/ConfigurationService.kt new file mode 100644 index 0000000..c20b772 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/ConfigurationService.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.domain + +interface ConfigurationService { +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/Performance.kt b/app/src/main/java/be/ugent/sel/studeez/domain/Performance.kt deleted file mode 100644 index e987b37..0000000 --- a/app/src/main/java/be/ugent/sel/studeez/domain/Performance.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2022 Google LLC - -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 - - https://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 be.ugent.sel.studeez.domain - -import com.google.firebase.perf.ktx.trace -import com.google.firebase.perf.metrics.Trace - -/** - * Trace a block with Firebase performance. - * - * Supports both suspend and regular methods. - */ -inline fun trace(name: String, block: Trace.() -> T): T = Trace.create(name).trace(block) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/TimerDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/TimerDAO.kt new file mode 100644 index 0000000..5498696 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/TimerDAO.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.domain + +interface TimerDAO { +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseConfigurationService.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseConfigurationService.kt new file mode 100644 index 0000000..1e11fd8 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseConfigurationService.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.domain.implementation + +class FirebaseConfigurationService { +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt new file mode 100644 index 0000000..c0b0a26 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.domain.implementation + +class FirebaseTimerDAO { +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt new file mode 100644 index 0000000..1720d66 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt @@ -0,0 +1,33 @@ +package be.ugent.sel.studeez.domain.implementation + +import be.ugent.sel.studeez.data.local.models.timer_info.* +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken + +class JsonToTimerConverter { + + private val timerInfoMap: Map = mapOf( + "endless" to TimerFactory { EndlessTimerInfo(it.name, it.description) }, + "custom" to TimerFactory { CustomTimerInfo(it.name, it.description, it.studyTime) }, + "break" to TimerFactory { PomodoroTimerInfo( + it.name, + it.description, + it.studyTime, + it.breakTime, + it.repeats + ) } + ) + + private fun getTimer(timerJson: TimerJson): TimerInfo{ + return timerInfoMap.getValue(timerJson.type).makeTimer(timerJson) + } + + fun convertToTimerInfoList(a: List): List { + return a.map(this::getTimer) + } + + fun jsonToTimerJsonList(json: String): List { + val type = object : TypeToken>() {}.type + return Gson().fromJson(json, type) + } +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt new file mode 100644 index 0000000..f8c8f54 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt @@ -0,0 +1,2 @@ +package be.ugent.sel.studeez.screens.timer_overview + diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt new file mode 100644 index 0000000..62b30ab --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.screens.timer_overview + +class TimerOverviewViewModel { +} \ No newline at end of file From 2a546146a3cbe9d546c703d12fa9fd86a326ed13 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:21:53 +0200 Subject: [PATCH 02/21] Configuration service fetches default timers --- .../studeez/domain/ConfigurationService.kt | 7 ++++ .../FirebaseConfigurationService.kt | 36 ++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/ConfigurationService.kt b/app/src/main/java/be/ugent/sel/studeez/domain/ConfigurationService.kt index c20b772..26aeba5 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/ConfigurationService.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/ConfigurationService.kt @@ -1,4 +1,11 @@ package be.ugent.sel.studeez.domain +import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo + interface ConfigurationService { + + suspend fun fetchConfiguration(): Boolean + + fun getDefaultTimers(): List + } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseConfigurationService.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseConfigurationService.kt index 1e11fd8..e3db024 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseConfigurationService.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseConfigurationService.kt @@ -1,4 +1,38 @@ package be.ugent.sel.studeez.domain.implementation -class FirebaseConfigurationService { +import be.ugent.sel.studeez.data.local.models.timer_info.* +import be.ugent.sel.studeez.domain.ConfigurationService +import com.google.firebase.ktx.Firebase +import com.google.firebase.remoteconfig.ktx.get +import com.google.firebase.remoteconfig.ktx.remoteConfig +import com.google.firebase.remoteconfig.ktx.remoteConfigSettings +import com.google.gson.Gson +import kotlinx.coroutines.tasks.await +import javax.inject.Inject + +class FirebaseConfigurationService @Inject constructor() : ConfigurationService { + + init { + // fetch configs elke keer als app wordt opgestart + val configSettings = remoteConfigSettings { minimumFetchIntervalInSeconds = 0 } + remoteConfig.setConfigSettingsAsync(configSettings) + } + + private val remoteConfig + get() = Firebase.remoteConfig + + override suspend fun fetchConfiguration(): Boolean { + return remoteConfig.fetchAndActivate().await() + } + + override fun getDefaultTimers(): List { + val jsonString: String = remoteConfig[DEFAULT_TIMERS].asString() + // Json is een lijst van timers + val timerJsonList: List = ToTimerConverter().jsonToTimerJsonList(jsonString) + return ToTimerConverter().convertToTimerInfoList(timerJsonList) + } + + companion object { + private const val DEFAULT_TIMERS = "default_timers" + } } \ No newline at end of file From ce57425957a711e1ea00b11a35f36fd8e0678145 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:25:57 +0200 Subject: [PATCH 03/21] #40 DAO to fetch the timers from the database. User timers only or combined (user + default) --- .../be/ugent/sel/studeez/domain/TimerDAO.kt | 15 +++++ .../domain/implementation/FirebaseTimerDAO.kt | 61 ++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/TimerDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/TimerDAO.kt index 5498696..ab3edcb 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/TimerDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/TimerDAO.kt @@ -1,4 +1,19 @@ package be.ugent.sel.studeez.domain +import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo +import be.ugent.sel.studeez.data.local.models.timer_info.TimerJson +import kotlinx.coroutines.flow.Flow + interface TimerDAO { + + fun getUserTimers(): Flow> + + fun getAllTimers(): Flow> + + fun saveTimer(newTimer: TimerInfo) + + fun updateTimer(timerInfo: TimerInfo) + + fun deleteTimer(timerInfo: TimerInfo) + } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt index c0b0a26..a25c37c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt @@ -1,4 +1,63 @@ package be.ugent.sel.studeez.domain.implementation -class FirebaseTimerDAO { +import be.ugent.sel.studeez.data.local.models.timer_info.* +import be.ugent.sel.studeez.data.local.models.timer_info.TimerType.* +import be.ugent.sel.studeez.domain.AccountDAO +import be.ugent.sel.studeez.domain.TimerDAO +import com.google.firebase.firestore.CollectionReference +import com.google.firebase.firestore.DocumentSnapshot +import com.google.firebase.firestore.FirebaseFirestore +import com.google.firebase.firestore.ktx.snapshots +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map +import javax.inject.Inject + +class FirebaseTimerDAO @Inject constructor( + private val firestore: FirebaseFirestore, + private val configurationService: FirebaseConfigurationService, + private val auth: AccountDAO +) : TimerDAO { + + override fun getUserTimers(): Flow> { + return currentUserTimersCollection() + .snapshots() + .map { it.toObjects(TimerJson::class.java) } + .map { ToTimerConverter().convertToTimerInfoList(it) } + } + + override fun getAllTimers(): Flow> { + // Wrap default timers in een flow en combineer met de userTimer flow. + val defaultTimers: List = configurationService.getDefaultTimers() + val defaultTimersFlow: Flow> = flowOf(defaultTimers) + val userTimersFlow: Flow> = getUserTimers() + return defaultTimersFlow.combine(userTimersFlow) { defaultTimersList, userTimersList -> + defaultTimersList + userTimersList + } + } + + override fun saveTimer(newTimer: TimerInfo) { + currentUserTimersCollection().add(newTimer.asJson()) + } + + override fun updateTimer(timerInfo: TimerInfo) { + currentUserTimersCollection().document(timerInfo.id).set(timerInfo.asJson()) + } + + override fun deleteTimer(timerInfo: TimerInfo) { + currentUserTimersCollection().document(timerInfo.id).delete() + } + + private fun currentUserTimersCollection(): CollectionReference = + firestore.collection(USER_COLLECTION) + .document(auth.currentUserId) + .collection(TIMER_COLLECTION) + + + companion object { + private const val TIMER_COLLECTION = "timers" + private const val USER_COLLECTION = "users" + } + } \ No newline at end of file From 505f5c882abe1603896801e690d315787732a033 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:27:05 +0200 Subject: [PATCH 04/21] converter to convert TimerJson to TimerInfo --- .../domain/implementation/ToTimerConverter.kt | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt index 1720d66..0aed6ee 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt @@ -4,26 +4,50 @@ import be.ugent.sel.studeez.data.local.models.timer_info.* import com.google.gson.Gson import com.google.gson.reflect.TypeToken -class JsonToTimerConverter { +/** + * Wordt gebruikt door de ConfigurationService en door de TimerDAO. + * + * ConfigurationService: configuration wordt gefetched als een json-string, + * die wordt omgezet naar een TimerJson, die hier wordt omgezet naar de juiste TimerInfo + * + * timerDAO: Timers worden direct naar TimerJson gefetched, die hier ook worden omgezet naar + * de juiste timerInfo + */ +class ToTimerConverter { - private val timerInfoMap: Map = mapOf( - "endless" to TimerFactory { EndlessTimerInfo(it.name, it.description) }, - "custom" to TimerFactory { CustomTimerInfo(it.name, it.description, it.studyTime) }, - "break" to TimerFactory { PomodoroTimerInfo( + fun interface TimerFactory { + fun makeTimer(map: TimerJson) : TimerInfo + } + + private val timerInfoMap: Map = mapOf( + TimerType.ENDLESS to TimerFactory { EndlessTimerInfo( + it.name, + it.description, + it.id + ) }, + TimerType.CUSTOM to TimerFactory { CustomTimerInfo( + it.name, + it.description, + it.studyTime, + it.id + ) }, + TimerType.BREAK to TimerFactory { BreakTimerInfo( it.name, it.description, it.studyTime, it.breakTime, - it.repeats + it.repeats, + it.id ) } ) private fun getTimer(timerJson: TimerJson): TimerInfo{ - return timerInfoMap.getValue(timerJson.type).makeTimer(timerJson) + val type: TimerType = TimerType.valueOf(timerJson.type.uppercase()) + return timerInfoMap.getValue(type).makeTimer(timerJson) } - fun convertToTimerInfoList(a: List): List { - return a.map(this::getTimer) + fun convertToTimerInfoList(timerJsonList: List): List { + return timerJsonList.map(this::getTimer) } fun jsonToTimerJsonList(json: String): List { From 28b3260191923eca5b2126a639db2fdf4812baf4 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:28:13 +0200 Subject: [PATCH 05/21] added timerdao and config service binds --- .../java/be/ugent/sel/studeez/di/DatabaseModule.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt b/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt index c82696e..e3c466c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt +++ b/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt @@ -1,11 +1,7 @@ package be.ugent.sel.studeez.di -import be.ugent.sel.studeez.domain.AccountDAO -import be.ugent.sel.studeez.domain.LogService -import be.ugent.sel.studeez.domain.UserDAO -import be.ugent.sel.studeez.domain.implementation.FirebaseAccountDAO -import be.ugent.sel.studeez.domain.implementation.FirebaseUserDAO -import be.ugent.sel.studeez.domain.implementation.LogServiceImpl +import be.ugent.sel.studeez.domain.* +import be.ugent.sel.studeez.domain.implementation.* import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -18,6 +14,9 @@ abstract class DatabaseModule { @Binds abstract fun provideUserDAO(impl: FirebaseUserDAO): UserDAO + @Binds abstract fun provideTimerDAO(impl: FirebaseTimerDAO): TimerDAO + @Binds abstract fun provideLogService(impl: LogServiceImpl): LogService + @Binds abstract fun provideConfigurationService(impl: FirebaseConfigurationService): ConfigurationService } \ No newline at end of file From 16eb7d14f27d74021244397275cf6e0ba0153fac Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:29:46 +0200 Subject: [PATCH 06/21] #40 added timer overview to destinations --- .../java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt index 3ac8d47..747141b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt @@ -5,5 +5,6 @@ object StudeezDestinations { const val SIGN_UP_SCREEN = "signup" const val LOGIN_SCREEN = "login" const val HOME_SCREEN = "home" + const val TIMER_OVERVIEW_SCREEN = "timer_overview" } \ No newline at end of file From cf97565dec67e737c02ae73c49c651b1ef288fbe Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:30:53 +0200 Subject: [PATCH 07/21] #40 added onTimersClick implementation --- .../be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt index 8eb4945..d8a2c6f 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt @@ -25,7 +25,8 @@ class DrawerViewModel @Inject constructor( } fun onTimersClick(openAndPopup: (String, String) -> Unit) { - // TODO + // TODO is niet altijd het homescreen + openAndPopup(StudeezDestinations.TIMER_OVERVIEW_SCREEN, StudeezDestinations.HOME_SCREEN) } fun onSettingsClick(openAndPopup: (String, String) -> Unit) { From 79dcede47ba7f40b5cd1c46964d29cd6eec2d551 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:31:35 +0200 Subject: [PATCH 08/21] fetch configutation on startup --- .../be/ugent/sel/studeez/screens/splash/SplashViewModel.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/splash/SplashViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/splash/SplashViewModel.kt index 6f0f18c..4e1dfbd 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/splash/SplashViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/splash/SplashViewModel.kt @@ -2,6 +2,7 @@ package be.ugent.sel.studeez.screens.splash import androidx.compose.runtime.mutableStateOf import be.ugent.sel.studeez.domain.AccountDAO +import be.ugent.sel.studeez.domain.ConfigurationService import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.StudeezViewModel @@ -11,10 +12,15 @@ import javax.inject.Inject @HiltViewModel class SplashViewModel @Inject constructor( private val accountDAO: AccountDAO, + private val configurationService: ConfigurationService, logService: LogService ) : StudeezViewModel(logService) { val showError = mutableStateOf(false) + init { + launchCatching { configurationService.fetchConfiguration() } + } + fun onAppStart(openAndPopUp: (String, String) -> Unit) { showError.value = false From 049138bbc555ea405e96f639e0bbe6cc16788211 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:32:32 +0200 Subject: [PATCH 09/21] #40 basic timer overview screen (to be extended) --- .../timer_overview/TimerOverviewScreen.kt | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt index f8c8f54..dcf7516 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewScreen.kt @@ -1,2 +1,102 @@ package be.ugent.sel.studeez.screens.timer_overview +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel +import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.common.composable.BasicButton +import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate +import be.ugent.sel.studeez.common.ext.basicButton +import be.ugent.sel.studeez.common.ext.card +import be.ugent.sel.studeez.data.local.models.timer_info.CustomTimerInfo +import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo +import be.ugent.sel.studeez.resources + +@Composable +fun TimerOverviewScreen( + openAndPopUp: (String, String) -> Unit, + viewModel: TimerOverviewViewModel = hiltViewModel() +) { + + val timers = viewModel.getUserTimers().collectAsState(initial = emptyList()) + + PrimaryScreenTemplate( + title = resources().getString(R.string.timers), + openAndPopUp = openAndPopUp + ) { + + Column { + LazyColumn( + verticalArrangement = Arrangement.spacedBy(7.dp) + ) { + // Default Timers, cannot be edited + items(viewModel.getDefaultTimers()) { + TimerEntry(timerInfo = it, canEdit = false) + } + + // User timers, can be edited + items(timers.value) { + TimerEntry(timerInfo = it, true) { timerInfo -> + viewModel.update(timerInfo) + } + } + } + BasicButton(R.string.add_timer, Modifier.basicButton()) { + // TODO + } + } + + } +} + +@Composable +fun TimerEntry(timerInfo: TimerInfo, canEdit: Boolean, update: (TimerInfo) -> Unit = {}) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Column { + Text( + text = timerInfo.name, + fontWeight = FontWeight.Bold, + fontSize = 20.sp + ) + Text( + text = timerInfo.description, + fontWeight = FontWeight.Light, + fontSize = 15.sp + ) + } + if (canEdit) { + BasicButton(R.string.edit, Modifier.card()) { + // TODO + } + } + + } +} + +@Preview +@Composable +fun TimerEntryPreview() { + val timerInfo = CustomTimerInfo( + "my preview timer", + "This is the description of the timer", + 60 + ) + TimerEntry(timerInfo = timerInfo, true) { } +} \ No newline at end of file From 880236e1ce3981c8d1013eedb231a2b455220e55 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:33:18 +0200 Subject: [PATCH 10/21] #40 viewmodel for overview screen --- .../timer_overview/TimerOverviewViewModel.kt | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt index 62b30ab..c2be1e9 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt @@ -1,4 +1,34 @@ package be.ugent.sel.studeez.screens.timer_overview -class TimerOverviewViewModel { +import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo +import be.ugent.sel.studeez.domain.ConfigurationService +import be.ugent.sel.studeez.domain.LogService +import be.ugent.sel.studeez.domain.TimerDAO +import be.ugent.sel.studeez.screens.StudeezViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +@HiltViewModel +class TimerOverviewViewModel @Inject constructor( + private val configurationService: ConfigurationService, + private val timerDAO: TimerDAO, + logService: LogService +) : StudeezViewModel(logService) { + + fun getUserTimers() : Flow> { + return timerDAO.getUserTimers() + } + + fun getDefaultTimers(): List { + return configurationService.getDefaultTimers() + } + + fun update(timerInfo: TimerInfo) = timerDAO.updateTimer(timerInfo) + + fun delete(timerInfo: TimerInfo) =timerDAO.deleteTimer(timerInfo) + + fun save(timerInfo: TimerInfo) = timerDAO.saveTimer(timerInfo) + + } \ No newline at end of file From 89eda17bc28d93bb338c853c81d939a4fc42833c Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:34:19 +0200 Subject: [PATCH 11/21] #40 timer_overview screen added to navgraph --- app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index 53cf341..471dfc5 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -22,6 +22,7 @@ import be.ugent.sel.studeez.screens.home.HomeScreen import be.ugent.sel.studeez.screens.log_in.LoginScreen import be.ugent.sel.studeez.screens.sign_up.SignUpScreen import be.ugent.sel.studeez.screens.splash.SplashScreen +import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewScreen import be.ugent.sel.studeez.ui.theme.StudeezTheme import kotlinx.coroutines.CoroutineScope @@ -95,4 +96,8 @@ fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) { composable(StudeezDestinations.HOME_SCREEN) { HomeScreen(openAndPopUp) } + + composable(StudeezDestinations.TIMER_OVERVIEW_SCREEN) { + TimerOverviewScreen(openAndPopUp) + } } \ No newline at end of file From d7f316675cca8a4ced6a170b456a0de6a4932ddf Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:37:19 +0200 Subject: [PATCH 12/21] #65 functional timer abstract class and subclasses --- .../timer_functional/FunctionalCustomTimer.kt | 14 +++++++- .../FunctionalEndlessTimer.kt | 10 +++++- .../FunctionalPomodoroTimer.kt | 32 ++++++++++++++++++- .../timer_functional/FunctionalTimer.kt | 17 +++++++++- .../timer_functional/HoursMinutesSeconds.kt | 2 +- .../local/models/timer_functional/Time.kt | 28 +++++++++++++++- 6 files changed, 97 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt index abbb2a2..7cae544 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalCustomTimer.kt @@ -1,4 +1,16 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -class FunctionalCustomTimer { +class FunctionalCustomTimer(studyTime: Int): FunctionalTimer(studyTime) { + + override fun tick() { + if (time.getTime() == 0) { + view = "Done!" + } else { + time.minOne() + } + } + + override fun hasEnded(): Boolean { + return time.getTime() == 0 + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt index c602f5c..45eecda 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalEndlessTimer.kt @@ -1,4 +1,12 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -class FunctionalEndlessTimer { +class FunctionalEndlessTimer() : FunctionalTimer(0){ + + override fun hasEnded(): Boolean { + return false + } + + override fun tick() { + time.plusOne() + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt index f9698be..ef0bf03 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalPomodoroTimer.kt @@ -1,4 +1,34 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -class FunctionalPomodoroTimer { +class FunctionalPomodoroTimer( + private var studyTime: Int, + private var breakTime: Int, repeats: Int +): FunctionalTimer(studyTime) { + + private var breaksRemaining = repeats + private var isInBreak = false + + override fun tick() { + if (time.getTime() == 0 && breaksRemaining == 0){ + view = "Done!" + return + } + + if (time.getTime() == 0) { + if (isInBreak) { + breaksRemaining-- + view = "Focus! ($breaksRemaining breaks remaining)" + time.setTime(studyTime) + } else { + view = "Take a break!" + time.setTime(breakTime) + } + isInBreak = !isInBreak + } + time.minOne() + } + + override fun hasEnded(): Boolean { + return breaksRemaining == 0 && time.getTime() == 0 + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt index ba1989f..e6965ab 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/FunctionalTimer.kt @@ -1,4 +1,19 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -class FunctionalTimer { +abstract class FunctionalTimer(initialValue: Int) { + protected val time: Time = Time(initialValue) + protected var view: String = "Focus" + + fun getHoursMinutesSeconds(): HoursMinutesSeconds { + return time.getAsHMS() + } + + fun getViewString(): String { + return view + } + + abstract fun tick() + + abstract fun hasEnded(): Boolean + } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt index f651a68..0712424 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt @@ -1,3 +1,3 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -data class HoursMinutesSeconds() +data class HoursMinutesSeconds(val hours: Int, val minutes: Int, val seconds: Int) \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt index 24e1245..250996e 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt @@ -1,4 +1,30 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -class Time { +class Time(initialTime: Int) { + + private var time = initialTime + + fun minOne() { + time-- + } + + fun plusOne() { + time++ + } + + fun setTime(newTime: Int) { + time = newTime + } + + fun getTime(): Int { + return time + } + + fun getAsHMS(): HoursMinutesSeconds { + val hours: Int = time / (60 * 60) + val minutes: Int = (time / (60)) % 60 + val seconds: Int = time % 60 + return HoursMinutesSeconds(hours, minutes, seconds) + } + } \ No newline at end of file From d43d326b41ffe8805f3f41342e6b93924f054a00 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 16 Apr 2023 23:38:05 +0200 Subject: [PATCH 13/21] #40 added some keywords for timer display --- app/src/main/res/values/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d070672..021f3b1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -38,6 +38,8 @@ Timers + Edit + Add timer Settings From b43d775039d7471e83fa63c30c9b8013a70c6e51 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Mon, 17 Apr 2023 10:05:09 +0200 Subject: [PATCH 14/21] #65 added session screen to destinations --- .../be/ugent/sel/studeez/navigation/StudeezDestinations.kt | 1 + .../be/ugent/sel/studeez/screens/session/SessionScreen.kt | 2 ++ .../be/ugent/sel/studeez/screens/session/SessionViewModel.kt | 4 ++++ 3 files changed, 7 insertions(+) create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt index 747141b..697932f 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt @@ -6,5 +6,6 @@ object StudeezDestinations { const val LOGIN_SCREEN = "login" const val HOME_SCREEN = "home" const val TIMER_OVERVIEW_SCREEN = "timer_overview" + const val SESSION_SCREEN = "session" } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt new file mode 100644 index 0000000..b885fed --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt @@ -0,0 +1,2 @@ +package be.ugent.sel.studeez.screens.session + diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt new file mode 100644 index 0000000..b5b1279 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.screens.session + +class SessionViewModel { +} \ No newline at end of file From 26f98480f47face68194c43a6afa00a447814612 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Mon, 17 Apr 2023 10:07:11 +0200 Subject: [PATCH 15/21] padding on hours minutes seconds --- .../local/models/timer_functional/HoursMinutesSeconds.kt | 3 ++- .../sel/studeez/data/local/models/timer_functional/Time.kt | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt index 0712424..856aa26 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt @@ -1,3 +1,4 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -data class HoursMinutesSeconds(val hours: Int, val minutes: Int, val seconds: Int) \ No newline at end of file +data class HoursMinutesSeconds(val hours: String, val minutes: String, val seconds: String +) \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt index 250996e..ff89516 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt @@ -24,7 +24,12 @@ class Time(initialTime: Int) { val hours: Int = time / (60 * 60) val minutes: Int = (time / (60)) % 60 val seconds: Int = time % 60 - return HoursMinutesSeconds(hours, minutes, seconds) + + return HoursMinutesSeconds( + hours.toString().padStart(2, '0'), + minutes.toString().padStart(2, '0'), + seconds.toString().padStart(2, '0') + ) } } \ No newline at end of file From ffaedf55426781cdf78698d7ba033b00642a51e3 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Mon, 17 Apr 2023 10:09:05 +0200 Subject: [PATCH 16/21] #65 sessionsclick now routes to sessionscreen --- .../java/be/ugent/sel/studeez/screens/home/HomeViewModel.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeViewModel.kt index 6a791d0..1c057bb 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeViewModel.kt @@ -5,6 +5,7 @@ import androidx.compose.material.rememberScaffoldState import be.ugent.sel.studeez.data.local.models.User import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.LogService +import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.navigation.StudeezDestinations.HOME_SCREEN import be.ugent.sel.studeez.navigation.StudeezDestinations.LOGIN_SCREEN import be.ugent.sel.studeez.screens.StudeezViewModel @@ -19,7 +20,7 @@ class HomeViewModel @Inject constructor( ) : StudeezViewModel(logService) { fun onStartSessionClick(openAndPopUp: (String, String) -> Unit) { - // TODO openAndPopUp(StudeezDestinations.xxx, StudeezDestinations.HOME_SCREEN) + openAndPopUp(StudeezDestinations.SESSION_SCREEN, StudeezDestinations.HOME_SCREEN) } fun onLogoutClick(openAndPopup: (String, String) -> Unit) { From 169a7d34692cb2b5229a6da0ab4d243ebc3b1179 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Mon, 17 Apr 2023 10:11:19 +0200 Subject: [PATCH 17/21] #65 sessionscreen --- .../studeez/screens/session/SessionScreen.kt | 56 +++++++++++++++++++ .../screens/session/SessionViewModel.kt | 18 +++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt index b885fed..e87bac5 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionScreen.kt @@ -1,2 +1,58 @@ package be.ugent.sel.studeez.screens.session +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel +import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate +import be.ugent.sel.studeez.resources +import kotlinx.coroutines.delay + +@Composable +fun SessionScreen( + openAndPopUp: (String, String) -> Unit, + viewModel: SessionViewModel = hiltViewModel() +) { + PrimaryScreenTemplate( + title = resources().getString(R.string.start_session), + openAndPopUp = openAndPopUp + ) { + Timer(viewModel) + } +} + +@Composable +private fun Timer(viewModel: SessionViewModel = hiltViewModel()) { + var tikker by remember { mutableStateOf(false) } + LaunchedEffect(tikker) { + delay(1000) + viewModel.getTimer().tick() + tikker = !tikker + } + + val hms = viewModel.getTimer().getHoursMinutesSeconds() + Column { + Text( + text = "${hms.hours} : ${hms.minutes} : ${hms.seconds}", + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center, + fontWeight = FontWeight.Bold, + fontSize = 80.sp + ) + Text( + text = viewModel.getTimer().getViewString(), + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center, + fontWeight = FontWeight.Light, + fontSize = 30.sp + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt index b5b1279..7326212 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt @@ -1,4 +1,20 @@ package be.ugent.sel.studeez.screens.session -class SessionViewModel { +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer +import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer +import be.ugent.sel.studeez.domain.LogService +import be.ugent.sel.studeez.screens.StudeezViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class SessionViewModel @Inject constructor( + logService: LogService +) : StudeezViewModel(logService) { + + private val timer: FunctionalTimer = FunctionalPomodoroTimer(15, 5, 3) + + fun getTimer() : FunctionalTimer { + return timer + } } \ No newline at end of file From 85f8abacf0b6ca69ef4868d5fdca169affbda2a5 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Mon, 17 Apr 2023 10:12:27 +0200 Subject: [PATCH 18/21] #65 added session screen to navgraph --- app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index 471dfc5..fbc8693 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -20,6 +20,7 @@ import be.ugent.sel.studeez.common.snackbar.SnackbarManager import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.home.HomeScreen import be.ugent.sel.studeez.screens.log_in.LoginScreen +import be.ugent.sel.studeez.screens.session.SessionScreen import be.ugent.sel.studeez.screens.sign_up.SignUpScreen import be.ugent.sel.studeez.screens.splash.SplashScreen import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewScreen @@ -100,4 +101,8 @@ fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) { composable(StudeezDestinations.TIMER_OVERVIEW_SCREEN) { TimerOverviewScreen(openAndPopUp) } + + composable(StudeezDestinations.SESSION_SCREEN) { + SessionScreen(openAndPopUp) + } } \ No newline at end of file From 0174114c6cb462d729b893658ab5813e62e85334 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Mon, 17 Apr 2023 11:01:21 +0200 Subject: [PATCH 19/21] fix missing bracket --- .../java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt index 2b1c208..d3460cf 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/drawer/DrawerViewModel.kt @@ -2,6 +2,7 @@ package be.ugent.sel.studeez.screens.drawer import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.LogService +import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.navigation.StudeezDestinations.HOME_SCREEN import be.ugent.sel.studeez.navigation.StudeezDestinations.LOGIN_SCREEN import be.ugent.sel.studeez.screens.StudeezViewModel @@ -25,6 +26,7 @@ class DrawerViewModel @Inject constructor( fun onTimersClick(openAndPopup: (String, String) -> Unit) { // TODO is niet altijd het homescreen openAndPopup(StudeezDestinations.TIMER_OVERVIEW_SCREEN, StudeezDestinations.HOME_SCREEN) + } fun onSettingsClick(open: (String) -> Unit) { // TODO From 894a2d0b82d9d74266a5e1bbf24b1a19e26be270 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Mon, 17 Apr 2023 14:36:12 +0200 Subject: [PATCH 20/21] Update app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt Co-authored-by: Tibo De Peuter --- .../studeez/domain/implementation/ToTimerConverter.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt index 0aed6ee..021f9a0 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/ToTimerConverter.kt @@ -5,13 +5,12 @@ import com.google.gson.Gson import com.google.gson.reflect.TypeToken /** - * Wordt gebruikt door de ConfigurationService en door de TimerDAO. + * Used by ConfigurationService and TimerDAO. * - * ConfigurationService: configuration wordt gefetched als een json-string, - * die wordt omgezet naar een TimerJson, die hier wordt omgezet naar de juiste TimerInfo + * ConfigurationService: configuration is fetched as a JSON-string, + * which is converted into a TimerJson, and converted here into the correct TimerInfo * - * timerDAO: Timers worden direct naar TimerJson gefetched, die hier ook worden omgezet naar - * de juiste timerInfo + * timerDAO: Timers are being fetched directly to TinerJson and convertes into the correct timerInfo */ class ToTimerConverter { From 0e45388242f111f016ae883d0f0535da71ee675b Mon Sep 17 00:00:00 2001 From: lbarraga Date: Mon, 17 Apr 2023 14:36:24 +0200 Subject: [PATCH 21/21] Update app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt Co-authored-by: Tibo De Peuter --- .../be/ugent/sel/studeez/navigation/StudeezDestinations.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt index 144cd45..a6c8290 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt @@ -5,10 +5,11 @@ object StudeezDestinations { const val SIGN_UP_SCREEN = "signup" const val LOGIN_SCREEN = "login" - const val HOME_SCREEN = "home" + const val HOME_SCREEN = "home" const val TIMER_OVERVIEW_SCREEN = "timer_overview" const val SESSION_SCREEN = "session" -// const val TASKS_SCREEN = "tasks" + // const val TASKS_SCREEN = "tasks" + // const val SESSIONS_SCREEN = "sessions" const val PROFILE_SCREEN = "profile" // const val TIMERS_SCREEN = "timers"