From 1eff33a6db0c5d101f9d54d3046cf14e4e5bfb3e Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 09:37:07 +0200 Subject: [PATCH 01/38] start task now goes to timer selection screen --- .../sel/studeez/common/composable/tasks/TaskEntry.kt | 8 +++++--- .../ugent/sel/studeez/screens/session/SessionViewModel.kt | 7 +++++-- .../java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt | 6 +++++- .../be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt | 7 +++++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt index fefb924..bf3a7cf 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt @@ -32,6 +32,7 @@ fun TaskEntry( task: Task, onCheckTask: (Boolean) -> Unit, onDeleteTask: () -> Unit, + onStartTask: () -> Unit ) { Card( modifier = Modifier @@ -95,6 +96,7 @@ fun TaskEntry( modifier = Modifier .padding(end = 5.dp), ) { + onStartTask() } } } @@ -110,7 +112,7 @@ fun TaskEntryPreview() { name = "Test Task", completed = false, ), - {}, {}, + {}, {}, {} ) } @@ -122,7 +124,7 @@ fun CompletedTaskEntryPreview() { name = "Test Task", completed = true, ), - {}, {}, + {}, {}, {}, ) } @@ -134,6 +136,6 @@ fun OverflowTaskEntryPreview() { name = "Test Taskkkkkkkkkkkkkkkkkkkkkkkkkkk", completed = false, ), - {}, {}, + {}, {}, {} ) } \ 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 d5e2bab..4b486fc 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,7 +1,9 @@ package be.ugent.sel.studeez.screens.session +import be.ugent.sel.studeez.data.SelectedTask import be.ugent.sel.studeez.data.SelectedTimerState import be.ugent.sel.studeez.data.SessionReportState +import be.ugent.sel.studeez.data.local.models.task.Task import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.navigation.StudeezDestinations @@ -13,17 +15,18 @@ import javax.inject.Inject class SessionViewModel @Inject constructor( private val selectedTimerState: SelectedTimerState, private val sessionReportState: SessionReportState, + private val selectedTask: SelectedTask, logService: LogService ) : StudeezViewModel(logService) { - private val task : String = "No task selected" // placeholder for tasks implementation + private val task : Task = selectedTask() fun getTimer() : FunctionalTimer { return selectedTimerState.selectedTimer!! } fun getTask(): String { - return task + return task.name } fun endSession(openAndPopUp: (String, String) -> Unit) { diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index 67f0e93..8a35717 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -30,6 +30,7 @@ data class TaskActions( val deleteTask: (Task) -> Unit, val onCheckTask: (Task, Boolean) -> Unit, val editSubject: () -> Unit, + val startTask: (Task) -> Unit ) fun getTaskActions(viewModel: TaskViewModel, open: (String) -> Unit): TaskActions { @@ -39,7 +40,8 @@ fun getTaskActions(viewModel: TaskViewModel, open: (String) -> Unit): TaskAction getSubject = viewModel::getSelectedSubject, deleteTask = viewModel::deleteTask, onCheckTask = { task, isChecked -> viewModel.toggleTaskCompleted(task, isChecked) }, - editSubject = { viewModel.editSubject(open) } + editSubject = { viewModel.editSubject(open) }, + startTask = { task -> viewModel.startTask(task, open) } ) } @@ -75,6 +77,7 @@ fun TaskScreen( task = it, onCheckTask = { isChecked -> taskActions.onCheckTask(it, isChecked) }, onDeleteTask = { taskActions.deleteTask(it) }, + onStartTask = { taskActions.startTask(it) } ) } } @@ -108,6 +111,7 @@ fun TaskScreenPreview() { {}, { _, _ -> run {} }, {}, + {} ) ) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt index 138d32c..37f1c91 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt @@ -1,6 +1,7 @@ package be.ugent.sel.studeez.screens.tasks import be.ugent.sel.studeez.data.SelectedSubject +import be.ugent.sel.studeez.data.SelectedTask import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.data.local.models.task.Task import be.ugent.sel.studeez.domain.LogService @@ -17,6 +18,7 @@ class TaskViewModel @Inject constructor( private val taskDAO: TaskDAO, private val subjectDAO: SubjectDAO, private val selectedSubject: SelectedSubject, + private val selectedTask: SelectedTask, logService: LogService, ) : StudeezViewModel(logService) { fun addTask(open: (String) -> Unit) { @@ -47,4 +49,9 @@ class TaskViewModel @Inject constructor( fun editSubject(open: (String) -> Unit) { open(StudeezDestinations.EDIT_SUBJECT_FORM) } + + fun startTask(task: Task, open: (String) -> Unit) { + selectedTask.set(task) + open(StudeezDestinations.TIMER_SELECTION_SCREEN) + } } \ No newline at end of file From 45f28592abb43d9077572b73c3feaba19985b8c5 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 10:08:02 +0200 Subject: [PATCH 02/38] sessionreport now has the id of the task --- .../be/ugent/sel/studeez/data/local/models/SessionReport.kt | 3 ++- .../data/local/models/timer_functional/FunctionalTimer.kt | 6 ++++-- .../ugent/sel/studeez/screens/session/SessionViewModel.kt | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt index 20a44a8..9ed8450 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt @@ -6,5 +6,6 @@ import com.google.firebase.firestore.DocumentId data class SessionReport( @DocumentId val id: String = "", val studyTime: Int = 0, - val endTime: Timestamp = Timestamp(0, 0) + val endTime: Timestamp = Timestamp(0, 0), + val taskId: String ) \ 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 1f4231a..cf5005f 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 @@ -2,6 +2,7 @@ package be.ugent.sel.studeez.data.local.models.timer_functional import be.ugent.sel.studeez.data.local.models.SessionReport import com.google.firebase.Timestamp +import com.google.firebase.firestore.DocumentReference abstract class FunctionalTimer(initialValue: Int) { var time: Time = Time(initialValue) @@ -17,10 +18,11 @@ abstract class FunctionalTimer(initialValue: Int) { abstract fun hasCurrentCountdownEnded(): Boolean - fun getSessionReport(): SessionReport { + fun getSessionReport(taskId: String): SessionReport { return SessionReport( studyTime = totalStudyTime, - endTime = Timestamp.now() + endTime = Timestamp.now(), + taskId = taskId ) } 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 4b486fc..920d4e0 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 @@ -30,7 +30,7 @@ class SessionViewModel @Inject constructor( } fun endSession(openAndPopUp: (String, String) -> Unit) { - sessionReportState.sessionReport = getTimer().getSessionReport() + sessionReportState.sessionReport = getTimer().getSessionReport(task.id) openAndPopUp(StudeezDestinations.SESSION_RECAP, StudeezDestinations.SESSION_SCREEN) } } \ No newline at end of file From 83fba0de70a520c7e0d7b25944b256f48aa73c25 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 13:55:44 +0200 Subject: [PATCH 03/38] #74 added a feedEntry dataclass --- .../ugent/sel/studeez/data/local/models/FeedEntry.kt | 10 ++++++++++ .../main/java/be/ugent/sel/studeez/domain/FeedDAO.kt | 4 ++++ .../studeez/domain/implementation/FirebaseFeedDAO.kt | 4 ++++ .../java/be/ugent/sel/studeez/screens/home/Feed.kt | 2 ++ .../be/ugent/sel/studeez/screens/home/FeedViewModel.kt | 4 ++++ 5 files changed, 24 insertions(+) create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt new file mode 100644 index 0000000..336a252 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt @@ -0,0 +1,10 @@ +package be.ugent.sel.studeez.data.local.models + +data class FeedEntry( + val argb_color: Long = 0, + val subJectName: String = "", + val taskName: String = "", + val taskId: String = "", // Name of task is not unique + val subjectId: String = "", + val totalStudyTime: Int = 0 +) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt new file mode 100644 index 0000000..cc8ae0c --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.domain + +interface FeedDAO { +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt new file mode 100644 index 0000000..df9ef8f --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.domain.implementation + +class FirebaseFeedDAO { +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt new file mode 100644 index 0000000..af6014f --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt @@ -0,0 +1,2 @@ +package be.ugent.sel.studeez.screens.home + diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt new file mode 100644 index 0000000..52c0be2 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt @@ -0,0 +1,4 @@ +package be.ugent.sel.studeez.screens.home + +class FeedViewModel { +} \ No newline at end of file From 05d93246a68be8db05644e62c4cda560357068ea Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 13:56:08 +0200 Subject: [PATCH 04/38] sessionreport now also has a task and subject id --- .../be/ugent/sel/studeez/data/local/models/SessionReport.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt index 9ed8450..5835538 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt @@ -7,5 +7,6 @@ data class SessionReport( @DocumentId val id: String = "", val studyTime: Int = 0, val endTime: Timestamp = Timestamp(0, 0), - val taskId: String + val taskId: String = "", + val subjectId: String = "" ) \ No newline at end of file From a0ea97dc522b325237a768ceaf35516014a616dd Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 13:57:05 +0200 Subject: [PATCH 05/38] #74 added bind for feedDAO --- app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt | 3 +++ 1 file changed, 3 insertions(+) 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 7ee4992..4c5fea1 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 @@ -33,4 +33,7 @@ abstract class DatabaseModule { @Binds abstract fun provideTaskDAO(impl: FireBaseTaskDAO): TaskDAO + + @Binds + abstract fun provideFeedDAO(impl: FirebaseFeedDAO): FeedDAO } \ No newline at end of file From bee7101befefbd2a8f70059a7088021152b73186 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 13:58:02 +0200 Subject: [PATCH 06/38] #74 added FeedDAO and firebase implementation --- .../be/ugent/sel/studeez/domain/FeedDAO.kt | 6 +++ .../domain/implementation/FirebaseFeedDAO.kt | 49 ++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt index cc8ae0c..05d4425 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt @@ -1,4 +1,10 @@ package be.ugent.sel.studeez.domain +import be.ugent.sel.studeez.data.local.models.FeedEntry +import kotlinx.coroutines.flow.Flow + interface FeedDAO { + + fun getFeedEntries(): Flow> + } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt index df9ef8f..c406b45 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt @@ -1,4 +1,51 @@ package be.ugent.sel.studeez.domain.implementation -class FirebaseFeedDAO { +import be.ugent.sel.studeez.data.local.models.FeedEntry +import be.ugent.sel.studeez.data.local.models.SessionReport +import be.ugent.sel.studeez.data.local.models.task.Subject +import be.ugent.sel.studeez.data.local.models.task.Task +import be.ugent.sel.studeez.domain.FeedDAO +import be.ugent.sel.studeez.domain.SessionDAO +import be.ugent.sel.studeez.domain.TaskDAO +import kotlinx.coroutines.flow.* +import javax.inject.Inject + +class FirebaseFeedDAO @Inject constructor( + private val sessionDAO: SessionDAO, + private val taskDAO: TaskDAO, + private val subjectDAO: FireBaseSubjectDAO +) : FeedDAO { + + override fun getFeedEntries(): Flow> { + return sessionDAO.getSessions().map {sessionReports -> + sessionReports + .map { sessionReport -> sessionToFeedEntry(sessionReport) } + .groupBy { it.taskId } + .map { fuseFeedEntries(it.component2()) } + } + } + + private fun fuseFeedEntries(entries: List): FeedEntry = + entries.fold(entries[0]) { accEntry, newEntry -> + val newStudyTime = accEntry.totalStudyTime + newEntry.totalStudyTime + accEntry.copy(totalStudyTime = newStudyTime) + } + + + private suspend fun sessionToFeedEntry(sessionReport: SessionReport): FeedEntry { + val subjectId: String = sessionReport.subjectId + val taskId: String = sessionReport.taskId + + val task: Task = taskDAO.getTask(subjectId, taskId) + val subject: Subject = subjectDAO.getSubject(subjectId)!! + + return FeedEntry( + argb_color = subject.argb_color, + subJectName = subject.name, + taskName = task.name, + taskId = task.id, + subjectId = subject.id, + totalStudyTime = sessionReport.studyTime + ) + } } \ No newline at end of file From dab4506a3451b55bcb1a012dd0bdfa7a46e3b512 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 13:59:29 +0200 Subject: [PATCH 07/38] #74 added single getSubject so feed kan fetch only one subject --- .../studeez/domain/implementation/FireBaseSubjectDAO.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt index 7d90fbf..e022863 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt @@ -1,13 +1,16 @@ package be.ugent.sel.studeez.domain.implementation import be.ugent.sel.studeez.data.local.models.task.Subject +import be.ugent.sel.studeez.data.local.models.task.Task import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.SubjectDAO import com.google.firebase.firestore.CollectionReference import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.ktx.snapshots +import com.google.firebase.firestore.ktx.toObject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map +import kotlinx.coroutines.tasks.await import javax.inject.Inject class FireBaseSubjectDAO @Inject constructor( @@ -20,6 +23,10 @@ class FireBaseSubjectDAO @Inject constructor( .map { it.toObjects(Subject::class.java) } } + override suspend fun getSubject(subjectId: String): Subject? { + return currentUserSubjectsCollection().document(subjectId).get().await().toObject() + } + override fun saveSubject(newSubject: Subject) { currentUserSubjectsCollection().add(newSubject) } From 2c7c96d73a1f4632ccdfb1feda717c881fa984dd Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 13:59:44 +0200 Subject: [PATCH 08/38] #74 added single getTask so feed kan fetch only one Task --- .../sel/studeez/domain/implementation/FireBaseTaskDAO.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt index b8855e6..963c93b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt @@ -8,8 +8,11 @@ import be.ugent.sel.studeez.domain.TaskDAO import com.google.firebase.firestore.CollectionReference import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.ktx.snapshots +import com.google.firebase.firestore.ktx.toObject import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map +import kotlinx.coroutines.tasks.await import javax.inject.Inject class FireBaseTaskDAO @Inject constructor( @@ -22,6 +25,10 @@ class FireBaseTaskDAO @Inject constructor( .map { it.toObjects(Task::class.java) } } + override suspend fun getTask(subjectId: String, taskId: String): Task { + return selectedSubjectTasksCollection(subjectId).document(taskId).get().await().toObject()!! + } + override fun saveTask(newTask: Task) { selectedSubjectTasksCollection(newTask.subjectId).add(newTask) } From 1c224446a847f6c2e6f09f8e05956e84ad26a92f Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 14:00:42 +0200 Subject: [PATCH 09/38] added getSubject to interface --- app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt index 2749fac..da6abbe 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt @@ -12,4 +12,5 @@ interface SubjectDAO { fun deleteSubject(oldSubject: Subject) fun updateSubject(newSubject: Subject) + suspend fun getSubject(subjectId: String): Subject? } \ No newline at end of file From 07ff75476d0a309992c7b533dff1da03c64540c2 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 14:00:52 +0200 Subject: [PATCH 10/38] added getTask to interface --- app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt index 0f629ea..988a10d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt @@ -15,4 +15,6 @@ interface TaskDAO { fun deleteTask(oldTask: Task) fun toggleTaskCompleted(task: Task, completed: Boolean) + + suspend fun getTask(subjectId: String, taskId: String): Task } \ No newline at end of file From 2db431463db0cbb0372199e721e2431bb8e7c3bf Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 14:02:29 +0200 Subject: [PATCH 11/38] sessionreport needs if of subjectId and taskId --- .../data/local/models/timer_functional/FunctionalTimer.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 cf5005f..656f52f 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 @@ -18,11 +18,12 @@ abstract class FunctionalTimer(initialValue: Int) { abstract fun hasCurrentCountdownEnded(): Boolean - fun getSessionReport(taskId: String): SessionReport { + fun getSessionReport(subjectId: String, taskId: String): SessionReport { return SessionReport( studyTime = totalStudyTime, endTime = Timestamp.now(), - taskId = taskId + taskId = taskId, + subjectId = subjectId ) } From f7b5d5170d73412b4ebe22c3d312e3fb1f1334c7 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 14:02:56 +0200 Subject: [PATCH 12/38] #74 made a feed --- .../be/ugent/sel/studeez/screens/home/Feed.kt | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt index af6014f..0e93a96 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt @@ -1,2 +1,103 @@ package be.ugent.sel.studeez.screens.home +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.Card +import androidx.compose.material.Divider +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.List +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.common.composable.StealthButton +import be.ugent.sel.studeez.data.local.models.FeedEntry +import be.ugent.sel.studeez.data.local.models.task.Subject +import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds + +@Composable +fun Feed( + open: (String) -> Unit, + viewModel: FeedViewModel = hiltViewModel() +) { + val feedEntries = viewModel.getFeedEntries().collectAsState(initial = emptyList()) + + LazyColumn { + items(feedEntries.value) {feedEntry -> + FeedEntryCard(feedEntry = feedEntry) { + viewModel.continueWithTask(open, feedEntry.subjectId, feedEntry.taskId) + } + } + } +} + +@Composable +fun FeedEntryCard( + feedEntry: FeedEntry, + onViewSubject: () -> Unit, +) { + Card( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 10.dp, vertical = 5.dp), + ) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .padding(start = 10.dp) + .weight(3f) + ) { + Box( + modifier = Modifier + .size(20.dp) + .clip(CircleShape) + .background(Color(feedEntry.argb_color)), + ) + Column( + verticalArrangement = Arrangement.spacedBy(0.dp) + ) { + Text( + text = feedEntry.subJectName, + fontWeight = FontWeight.Bold, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + ) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text(text = feedEntry.taskName) + Text(text = HoursMinutesSeconds(feedEntry.totalStudyTime).toString()) + } + } + } + StealthButton( + text = R.string.start, + modifier = Modifier + .padding(start = 10.dp, end = 5.dp) + .weight(1f) + ) { + onViewSubject() + } + } + } +} \ No newline at end of file From 190c3467ec78aaf30f535bf4554c2a4f525d8f18 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 14:03:46 +0200 Subject: [PATCH 13/38] #74 viewmodel of a feed --- .../sel/studeez/screens/home/FeedViewModel.kt | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt index 52c0be2..3b9fb0c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt @@ -1,4 +1,37 @@ package be.ugent.sel.studeez.screens.home -class FeedViewModel { +import androidx.lifecycle.viewModelScope +import be.ugent.sel.studeez.data.SelectedTask +import be.ugent.sel.studeez.data.local.models.FeedEntry +import be.ugent.sel.studeez.domain.FeedDAO +import be.ugent.sel.studeez.domain.LogService +import be.ugent.sel.studeez.domain.TaskDAO +import be.ugent.sel.studeez.navigation.StudeezDestinations +import be.ugent.sel.studeez.screens.StudeezViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class FeedViewModel @Inject constructor( + private val feedDAO: FeedDAO, + private val taskDAO: TaskDAO, + private val selectedTask: SelectedTask, + logService: LogService +) : StudeezViewModel(logService) { + + private val entries: Flow> = feedDAO.getFeedEntries() + + fun getFeedEntries(): Flow> { + return entries + } + + fun continueWithTask(open: (String) -> Unit, subjectId: String, taskId: String) { + viewModelScope.launch { + val task = taskDAO.getTask(subjectId, taskId) + selectedTask.set(task) + open(StudeezDestinations.TIMER_SELECTION_SCREEN) + } + } } \ No newline at end of file From 4728755c5e863b2132a27fce153c4258ffed74b7 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 14:04:20 +0200 Subject: [PATCH 14/38] #74 homescreen now contains a feed --- .../be/ugent/sel/studeez/screens/home/HomeScreen.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index f02852e..b71ada1 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -25,6 +25,7 @@ fun HomeRoute( HomeScreen( onStartSessionClick = { viewModel.onStartSessionClick(open) }, drawerActions = drawerActions, + open = open, navigationBarActions = navigationBarActions, ) } @@ -32,6 +33,7 @@ fun HomeRoute( @Composable fun HomeScreen( onStartSessionClick: () -> Unit, + open: (String) -> Unit, drawerActions: DrawerActions, navigationBarActions: NavigationBarActions ) { @@ -41,9 +43,10 @@ fun HomeScreen( navigationBarActions = navigationBarActions, // TODO barAction = { FriendsAction() } ) { - BasicButton(R.string.start_session, Modifier.basicButton()) { - onStartSessionClick() - } + Feed(open) +// BasicButton(R.string.start_session, Modifier.basicButton()) { +// onStartSessionClick() +// } } } @@ -63,6 +66,7 @@ fun HomeScreenPreview() { HomeScreen( onStartSessionClick = {}, drawerActions = DrawerActions({}, {}, {}, {}, {}), - navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}) + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), + open = {} ) } From 49835108f3976e27b0c93e0b6ecbd7dc213e47b7 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 14:05:43 +0200 Subject: [PATCH 15/38] subject id and taskid as parameters for getSessionReport --- .../be/ugent/sel/studeez/screens/session/SessionViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 920d4e0..cd4c93a 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 @@ -30,7 +30,7 @@ class SessionViewModel @Inject constructor( } fun endSession(openAndPopUp: (String, String) -> Unit) { - sessionReportState.sessionReport = getTimer().getSessionReport(task.id) + sessionReportState.sessionReport = getTimer().getSessionReport(task.subjectId, task.id) openAndPopUp(StudeezDestinations.SESSION_RECAP, StudeezDestinations.SESSION_SCREEN) } } \ No newline at end of file From e1ddf41d09ef719983b723c2473dcf11c043d984 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 14:06:20 +0200 Subject: [PATCH 16/38] #74 added continue string for feed --- app/src/main/res/values/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d51259c..bc00963 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -29,6 +29,9 @@ Home Start session + + Continue + Tasks Task From 260171a972a1b858e66bd52bcfe9392cdb8c9577 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 14:25:18 +0200 Subject: [PATCH 17/38] #74 feedEntry now has an endTime --- .../java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt index 336a252..e24cd24 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt @@ -1,10 +1,13 @@ package be.ugent.sel.studeez.data.local.models +import com.google.firebase.Timestamp + data class FeedEntry( val argb_color: Long = 0, val subJectName: String = "", val taskName: String = "", val taskId: String = "", // Name of task is not unique val subjectId: String = "", - val totalStudyTime: Int = 0 + val totalStudyTime: Int = 0, + val endTime: Timestamp = Timestamp(0, 0) ) From 3f6d416f39446affee82ce284f0d3095b94257fc Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 14:26:07 +0200 Subject: [PATCH 18/38] #74 feed is now sorted on taskdates --- .../domain/implementation/FirebaseFeedDAO.kt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt index c406b45..d742bf3 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt @@ -7,6 +7,7 @@ import be.ugent.sel.studeez.data.local.models.task.Task import be.ugent.sel.studeez.domain.FeedDAO import be.ugent.sel.studeez.domain.SessionDAO import be.ugent.sel.studeez.domain.TaskDAO +import com.google.firebase.Timestamp import kotlinx.coroutines.flow.* import javax.inject.Inject @@ -22,15 +23,22 @@ class FirebaseFeedDAO @Inject constructor( .map { sessionReport -> sessionToFeedEntry(sessionReport) } .groupBy { it.taskId } .map { fuseFeedEntries(it.component2()) } + .sortedByDescending { it.endTime } } } private fun fuseFeedEntries(entries: List): FeedEntry = entries.fold(entries[0]) { accEntry, newEntry -> - val newStudyTime = accEntry.totalStudyTime + newEntry.totalStudyTime - accEntry.copy(totalStudyTime = newStudyTime) + accEntry.copy( + totalStudyTime = accEntry.totalStudyTime + newEntry.totalStudyTime, + endTime = getMostRecent(accEntry.endTime, newEntry.endTime) + ) } + private fun getMostRecent(t1: Timestamp, t2: Timestamp): Timestamp { + return if (t1 < t2) t2 else t1 + } + private suspend fun sessionToFeedEntry(sessionReport: SessionReport): FeedEntry { val subjectId: String = sessionReport.subjectId @@ -45,7 +53,8 @@ class FirebaseFeedDAO @Inject constructor( taskName = task.name, taskId = task.id, subjectId = subject.id, - totalStudyTime = sessionReport.studyTime + totalStudyTime = sessionReport.studyTime, + endTime = sessionReport.endTime ) } } \ No newline at end of file From f3a8c93a3e23969759de35dcfc2193b17cde376f Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 16:10:32 +0200 Subject: [PATCH 19/38] #74 getFeedentries now returns a map with date as key and as value the entries for that day --- app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt | 2 +- .../sel/studeez/domain/implementation/FirebaseFeedDAO.kt | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt index 05d4425..2d91781 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/FeedDAO.kt @@ -5,6 +5,6 @@ import kotlinx.coroutines.flow.Flow interface FeedDAO { - fun getFeedEntries(): Flow> + fun getFeedEntries(): Flow>> } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt index d742bf3..600153a 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt @@ -1,5 +1,6 @@ package be.ugent.sel.studeez.domain.implementation +import android.icu.text.DateFormat import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.data.local.models.SessionReport import be.ugent.sel.studeez.data.local.models.task.Subject @@ -17,16 +18,21 @@ class FirebaseFeedDAO @Inject constructor( private val subjectDAO: FireBaseSubjectDAO ) : FeedDAO { - override fun getFeedEntries(): Flow> { + override fun getFeedEntries(): Flow>> { return sessionDAO.getSessions().map {sessionReports -> sessionReports .map { sessionReport -> sessionToFeedEntry(sessionReport) } .groupBy { it.taskId } .map { fuseFeedEntries(it.component2()) } .sortedByDescending { it.endTime } + .groupBy { getFormattedTime(it) } } } + private fun getFormattedTime(entry: FeedEntry): String { + return DateFormat.getDateInstance().format(entry.endTime.toDate()) + } + private fun fuseFeedEntries(entries: List): FeedEntry = entries.fold(entries[0]) { accEntry, newEntry -> accEntry.copy( From ac1bfe4d49a33ee4cc7ffc049fb0e292017134ea Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 16:10:56 +0200 Subject: [PATCH 20/38] #74 feed now had dates --- .../be/ugent/sel/studeez/screens/home/Feed.kt | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt index 0e93a96..62f285a 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt @@ -1,5 +1,7 @@ package be.ugent.sel.studeez.screens.home +import android.icu.text.DateFormat +import android.icu.text.SimpleDateFormat import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn @@ -21,24 +23,37 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow 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.StealthButton import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds +import com.google.type.Date +import java.time.temporal.TemporalField +import java.util.* @Composable fun Feed( open: (String) -> Unit, viewModel: FeedViewModel = hiltViewModel() ) { - val feedEntries = viewModel.getFeedEntries().collectAsState(initial = emptyList()) + val feedEntries = viewModel.getFeedEntries().collectAsState(initial = emptyMap()) LazyColumn { - items(feedEntries.value) {feedEntry -> - FeedEntryCard(feedEntry = feedEntry) { - viewModel.continueWithTask(open, feedEntry.subjectId, feedEntry.taskId) + + items(feedEntries.value.toList()) {(date, feedEntries) -> + Text( + text = date, + fontWeight = FontWeight.Bold, + fontSize = 20.sp, + modifier = Modifier.padding(horizontal = 10.dp) + ) + feedEntries.forEach { feedEntry -> + FeedEntryCard(feedEntry = feedEntry) { + viewModel.continueWithTask(open, feedEntry.subjectId, feedEntry.taskId) + } } } } From 4e8fb28b0298cc99868c9e43ede74887fec9a16f Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 16:11:46 +0200 Subject: [PATCH 21/38] #74 dao returns map --- .../java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt index 3b9fb0c..aca17c8 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt @@ -21,9 +21,9 @@ class FeedViewModel @Inject constructor( logService: LogService ) : StudeezViewModel(logService) { - private val entries: Flow> = feedDAO.getFeedEntries() + private val entries: Flow>> = feedDAO.getFeedEntries() - fun getFeedEntries(): Flow> { + fun getFeedEntries(): Flow>> { return entries } From afe58572a6b97d4ca6b1aaff8d00c98d23900415 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 16:58:25 +0200 Subject: [PATCH 22/38] #74 fusing entries only on a daily basis --- .../sel/studeez/domain/implementation/FirebaseFeedDAO.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt index 600153a..79e4e68 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt @@ -22,10 +22,14 @@ class FirebaseFeedDAO @Inject constructor( return sessionDAO.getSessions().map {sessionReports -> sessionReports .map { sessionReport -> sessionToFeedEntry(sessionReport) } - .groupBy { it.taskId } - .map { fuseFeedEntries(it.component2()) } .sortedByDescending { it.endTime } .groupBy { getFormattedTime(it) } + .mapValues { (_, entries) -> + entries + .groupBy { it.taskId } + .map { fuseFeedEntries(it.component2()) } + .sortedByDescending { it.endTime } + } } } From b5b32059718448a4c38a5e1596a9faca7fd5ebed Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 16:59:23 +0200 Subject: [PATCH 23/38] #74 UI Refactor --- .../be/ugent/sel/studeez/screens/home/Feed.kt | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt index 62f285a..4a254ac 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt @@ -1,7 +1,5 @@ package be.ugent.sel.studeez.screens.home -import android.icu.text.DateFormat -import android.icu.text.SimpleDateFormat import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn @@ -9,17 +7,13 @@ import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Card import androidx.compose.material.Divider -import androidx.compose.material.Icon import androidx.compose.material.Text -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.List import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -27,12 +21,9 @@ 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.StealthButton +import be.ugent.sel.studeez.common.ext.spacer import be.ugent.sel.studeez.data.local.models.FeedEntry -import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds -import com.google.type.Date -import java.time.temporal.TemporalField -import java.util.* @Composable fun Feed( @@ -44,21 +35,41 @@ fun Feed( LazyColumn { items(feedEntries.value.toList()) {(date, feedEntries) -> - Text( - text = date, - fontWeight = FontWeight.Bold, - fontSize = 20.sp, - modifier = Modifier.padding(horizontal = 10.dp) - ) + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .padding(10.dp), + verticalAlignment = Alignment.CenterVertically + ) { + val totalDayStudyTime: Int = feedEntries.sumOf { it.totalStudyTime } + DateText(date = date) + Text( + text = "${HoursMinutesSeconds(totalDayStudyTime)}", + fontSize = 15.sp, + fontWeight = FontWeight.Bold + ) + } feedEntries.forEach { feedEntry -> FeedEntryCard(feedEntry = feedEntry) { viewModel.continueWithTask(open, feedEntry.subjectId, feedEntry.taskId) } } + Spacer(modifier = Modifier.height(20.dp)) } } } +@Composable +fun DateText(date: String) { + Text( + text = date, + fontWeight = FontWeight.Bold, + fontSize = 20.sp, + modifier = Modifier.padding(horizontal = 10.dp) + ) +} + @Composable fun FeedEntryCard( feedEntry: FeedEntry, From d036afc319e20aec40f1ec5d681805d290366b14 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 17:10:57 +0200 Subject: [PATCH 24/38] Docs --- .../studeez/domain/implementation/FirebaseFeedDAO.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt index 79e4e68..56d9000 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt @@ -18,6 +18,9 @@ class FirebaseFeedDAO @Inject constructor( private val subjectDAO: FireBaseSubjectDAO ) : FeedDAO { + /** + * Return a map as with key the day and value a list of feedentries for that day. + */ override fun getFeedEntries(): Flow>> { return sessionDAO.getSessions().map {sessionReports -> sessionReports @@ -28,7 +31,6 @@ class FirebaseFeedDAO @Inject constructor( entries .groupBy { it.taskId } .map { fuseFeedEntries(it.component2()) } - .sortedByDescending { it.endTime } } } } @@ -37,6 +39,10 @@ class FirebaseFeedDAO @Inject constructor( return DateFormat.getDateInstance().format(entry.endTime.toDate()) } + /** + * Givin a list of entries referencing the same task, in the same day, fuse them into one + * feed-entry by adding the studytime and keeping the most recent end-timestamp + */ private fun fuseFeedEntries(entries: List): FeedEntry = entries.fold(entries[0]) { accEntry, newEntry -> accEntry.copy( @@ -49,7 +55,9 @@ class FirebaseFeedDAO @Inject constructor( return if (t1 < t2) t2 else t1 } - + /** + * Convert a sessionReport to a feedEntry. Fetch Task and Subject to get names + */ private suspend fun sessionToFeedEntry(sessionReport: SessionReport): FeedEntry { val subjectId: String = sessionReport.subjectId val taskId: String = sessionReport.taskId From 9a214ce97cc7118396eb38f4b09496365c7b45ca Mon Sep 17 00:00:00 2001 From: lbarraga Date: Sun, 7 May 2023 17:23:43 +0200 Subject: [PATCH 25/38] change name of button function --- app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt index 4a254ac..7847ceb 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt @@ -6,7 +6,6 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Card -import androidx.compose.material.Divider import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState @@ -21,7 +20,6 @@ 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.StealthButton -import be.ugent.sel.studeez.common.ext.spacer import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds @@ -73,7 +71,7 @@ fun DateText(date: String) { @Composable fun FeedEntryCard( feedEntry: FeedEntry, - onViewSubject: () -> Unit, + continueWithTask: () -> Unit, ) { Card( modifier = Modifier @@ -122,7 +120,7 @@ fun FeedEntryCard( .padding(start = 10.dp, end = 5.dp) .weight(1f) ) { - onViewSubject() + continueWithTask() } } } From c62d15ee99ca56608890885d10e599c24f2c1c7d Mon Sep 17 00:00:00 2001 From: lbarraga Date: Mon, 8 May 2023 17:10:44 +0200 Subject: [PATCH 26/38] comment in homescreen weg --- .../main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index b71ada1..0911fd9 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -44,9 +44,6 @@ fun HomeScreen( // TODO barAction = { FriendsAction() } ) { Feed(open) -// BasicButton(R.string.start_session, Modifier.basicButton()) { -// onStartSessionClick() -// } } } From 9df80f4f935de6743143ce3b7079030715623288 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Mon, 8 May 2023 17:40:23 +0200 Subject: [PATCH 27/38] Fix: double counted entries --- .../ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt index 56d9000..c116fbf 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt @@ -44,7 +44,7 @@ class FirebaseFeedDAO @Inject constructor( * feed-entry by adding the studytime and keeping the most recent end-timestamp */ private fun fuseFeedEntries(entries: List): FeedEntry = - entries.fold(entries[0]) { accEntry, newEntry -> + entries.drop(1).fold(entries[0]) { accEntry, newEntry -> accEntry.copy( totalStudyTime = accEntry.totalStudyTime + newEntry.totalStudyTime, endTime = getMostRecent(accEntry.endTime, newEntry.endTime) From 08c779030e3580f1084b990e8c094f3bcaf0c9f9 Mon Sep 17 00:00:00 2001 From: brreynie Date: Mon, 8 May 2023 21:05:54 +0200 Subject: [PATCH 28/38] refactor FeedEntry --- .../common/composable/TextComposable.kt | 13 +++ .../be/ugent/sel/studeez/screens/home/Feed.kt | 86 ++--------------- .../sel/studeez/screens/home/FeedEntry.kt | 96 +++++++++++++++++++ 3 files changed, 119 insertions(+), 76 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/home/FeedEntry.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/TextComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/TextComposable.kt index 1b921a9..25fa3c4 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/TextComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/TextComposable.kt @@ -3,10 +3,13 @@ package be.ugent.sel.studeez.common.composable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @Composable @@ -23,4 +26,14 @@ fun Headline( fontSize = 34.sp ) } +} + +@Composable +fun DateText(date: String) { + Text( + text = date, + fontWeight = FontWeight.Bold, + fontSize = 20.sp, + modifier = Modifier.padding(horizontal = 10.dp) + ) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt index 7847ceb..af42203 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt @@ -1,26 +1,19 @@ package be.ugent.sel.studeez.screens.home -import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Card 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.draw.clip -import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow +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.StealthButton -import be.ugent.sel.studeez.data.local.models.FeedEntry +import be.ugent.sel.studeez.common.composable.DateText import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds @Composable @@ -29,10 +22,10 @@ fun Feed( viewModel: FeedViewModel = hiltViewModel() ) { val feedEntries = viewModel.getFeedEntries().collectAsState(initial = emptyMap()) - + LazyColumn { - items(feedEntries.value.toList()) {(date, feedEntries) -> + items(feedEntries.value.toList()) { (date, feedEntries) -> Row( horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier @@ -49,7 +42,7 @@ fun Feed( ) } feedEntries.forEach { feedEntry -> - FeedEntryCard(feedEntry = feedEntry) { + FeedEntry(feedEntry = feedEntry) { viewModel.continueWithTask(open, feedEntry.subjectId, feedEntry.taskId) } } @@ -58,70 +51,11 @@ fun Feed( } } +@Preview @Composable -fun DateText(date: String) { - Text( - text = date, - fontWeight = FontWeight.Bold, - fontSize = 20.sp, - modifier = Modifier.padding(horizontal = 10.dp) +fun FeedPreview() { + Feed( + open = {}, + viewModel = hiltViewModel(), ) -} - -@Composable -fun FeedEntryCard( - feedEntry: FeedEntry, - continueWithTask: () -> Unit, -) { - Card( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 10.dp, vertical = 5.dp), - ) { - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - Row( - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .padding(start = 10.dp) - .weight(3f) - ) { - Box( - modifier = Modifier - .size(20.dp) - .clip(CircleShape) - .background(Color(feedEntry.argb_color)), - ) - Column( - verticalArrangement = Arrangement.spacedBy(0.dp) - ) { - Text( - text = feedEntry.subJectName, - fontWeight = FontWeight.Bold, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - ) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - Text(text = feedEntry.taskName) - Text(text = HoursMinutesSeconds(feedEntry.totalStudyTime).toString()) - } - } - } - StealthButton( - text = R.string.start, - modifier = Modifier - .padding(start = 10.dp, end = 5.dp) - .weight(1f) - ) { - continueWithTask() - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedEntry.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedEntry.kt new file mode 100644 index 0000000..a7d1fc1 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedEntry.kt @@ -0,0 +1,96 @@ +package be.ugent.sel.studeez.screens.home + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.Card +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.common.composable.StealthButton +import be.ugent.sel.studeez.data.local.models.FeedEntry +import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds + +@Composable +fun FeedEntry( + feedEntry: FeedEntry, + continueWithTask: () -> Unit, +) { + Card( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 10.dp, vertical = 5.dp), + ) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .padding(start = 10.dp) + .weight(11f) + ) { + Box( + modifier = Modifier + .size(20.dp) + .clip(CircleShape) + .background(Color(feedEntry.argb_color)), + ) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Column( + verticalArrangement = Arrangement.spacedBy(0.dp) + ) { + Text( + text = feedEntry.subJectName, + fontWeight = FontWeight.Bold, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + ) + Text( + text = feedEntry.taskName, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + ) + } + Text(text = HoursMinutesSeconds(feedEntry.totalStudyTime).toString()) + } + } + StealthButton( + text = R.string.continue_task, + modifier = Modifier + .padding(start = 10.dp, end = 5.dp) + .weight(6f) + ) { + continueWithTask() + } + } + } +} + +@Preview +@Composable +fun FeedEntryPreview() { + FeedEntry( + continueWithTask = {}, + feedEntry = FeedEntry( + argb_color = 0xFFFFD200, + subJectName = "Test Subject", + taskName = "Test Taskkkkkkkkkkkkkkkkkkkkkkkkk", + totalStudyTime = 20, + ) + ) +} \ No newline at end of file From d31276ef815a7e055717ea43a30a1639ebd9c13a Mon Sep 17 00:00:00 2001 From: brreynie Date: Mon, 8 May 2023 21:21:14 +0200 Subject: [PATCH 29/38] refactor Feed --- .../sel/studeez/navigation/StudeezNavGraph.kt | 4 +- .../be/ugent/sel/studeez/screens/home/Feed.kt | 43 +++++++++++-------- .../sel/studeez/screens/home/FeedViewModel.kt | 2 +- .../sel/studeez/screens/home/HomeScreen.kt | 17 ++++---- 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt index a09846a..bd12413 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt @@ -15,6 +15,7 @@ import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarViewModel import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions import be.ugent.sel.studeez.screens.home.HomeRoute +import be.ugent.sel.studeez.screens.home.getFeedActions import be.ugent.sel.studeez.screens.log_in.LoginRoute import be.ugent.sel.studeez.screens.profile.EditProfileRoute import be.ugent.sel.studeez.screens.profile.ProfileRoute @@ -67,7 +68,8 @@ fun StudeezNavGraph( open, viewModel = hiltViewModel(), drawerActions = drawerActions, - navigationBarActions = navigationBarActions + navigationBarActions = navigationBarActions, + feedActions = getFeedActions(hiltViewModel(), open), ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt index af42203..96a9623 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt @@ -9,22 +9,40 @@ 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.common.composable.DateText +import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds +import kotlinx.coroutines.flow.Flow + +data class FeedActions( + val getFeedEntries: () -> Flow>>, + val continueTask: (String, String) -> Unit, +) + +fun getFeedActions( + viewmodel: FeedViewModel, + open: (String) -> Unit, +): FeedActions { + return FeedActions( + getFeedEntries = viewmodel::getFeedEntries, + continueTask = { subjectId, taskId -> + viewmodel.continueTask( + open, + subjectId, + taskId, + ) + }, + ) +} @Composable fun Feed( - open: (String) -> Unit, - viewModel: FeedViewModel = hiltViewModel() + feedActions: FeedActions, ) { - val feedEntries = viewModel.getFeedEntries().collectAsState(initial = emptyMap()) - + val feedEntries = feedActions.getFeedEntries().collectAsState(initial = emptyMap()) LazyColumn { - items(feedEntries.value.toList()) { (date, feedEntries) -> Row( horizontalArrangement = Arrangement.SpaceBetween, @@ -43,19 +61,10 @@ fun Feed( } feedEntries.forEach { feedEntry -> FeedEntry(feedEntry = feedEntry) { - viewModel.continueWithTask(open, feedEntry.subjectId, feedEntry.taskId) + feedActions.continueTask(feedEntry.subjectId, feedEntry.taskId) } } Spacer(modifier = Modifier.height(20.dp)) } } -} - -@Preview -@Composable -fun FeedPreview() { - Feed( - open = {}, - viewModel = hiltViewModel(), - ) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt index aca17c8..1f57175 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt @@ -27,7 +27,7 @@ class FeedViewModel @Inject constructor( return entries } - fun continueWithTask(open: (String) -> Unit, subjectId: String, taskId: String) { + fun continueTask(open: (String) -> Unit, subjectId: String, taskId: String) { viewModelScope.launch { val task = taskDAO.getTask(subjectId, taskId) selectedTask.set(task) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index 0911fd9..79f03e3 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -5,15 +5,13 @@ import androidx.compose.material.IconButton import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Person import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview 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.composable.drawer.DrawerActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions -import be.ugent.sel.studeez.common.ext.basicButton import be.ugent.sel.studeez.resources +import kotlinx.coroutines.flow.flowOf @Composable fun HomeRoute( @@ -21,21 +19,22 @@ fun HomeRoute( viewModel: HomeViewModel, drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, + feedActions: FeedActions, ) { HomeScreen( - onStartSessionClick = { viewModel.onStartSessionClick(open) }, drawerActions = drawerActions, open = open, navigationBarActions = navigationBarActions, + feedActions = feedActions, ) } @Composable fun HomeScreen( - onStartSessionClick: () -> Unit, open: (String) -> Unit, drawerActions: DrawerActions, - navigationBarActions: NavigationBarActions + navigationBarActions: NavigationBarActions, + feedActions: FeedActions, ) { PrimaryScreenTemplate( title = resources().getString(R.string.home), @@ -43,7 +42,7 @@ fun HomeScreen( navigationBarActions = navigationBarActions, // TODO barAction = { FriendsAction() } ) { - Feed(open) + Feed(feedActions) } } @@ -61,9 +60,9 @@ fun FriendsAction() { @Composable fun HomeScreenPreview() { HomeScreen( - onStartSessionClick = {}, drawerActions = DrawerActions({}, {}, {}, {}, {}), navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), - open = {} + open = {}, + feedActions = FeedActions({ flowOf() }, { _, _ -> run {} }) ) } From 6ba0018765a4d09bb048d13db64d112c234cacb0 Mon Sep 17 00:00:00 2001 From: brreynie Date: Mon, 8 May 2023 21:51:18 +0200 Subject: [PATCH 30/38] refactor feed to use UiState.Loading --- .../studeez/common/composable/feed/Feed.kt | 99 +++++++++++++++++++ .../composable/feed}/FeedEntry.kt | 2 +- .../common/composable/feed/FeedUiState.kt | 8 ++ .../composable/feed}/FeedViewModel.kt | 14 ++- .../sel/studeez/navigation/StudeezNavGraph.kt | 4 +- .../be/ugent/sel/studeez/screens/home/Feed.kt | 70 ------------- .../sel/studeez/screens/home/HomeScreen.kt | 16 ++- .../sel/studeez/screens/home/HomeViewModel.kt | 19 ---- 8 files changed, 131 insertions(+), 101 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt rename app/src/main/java/be/ugent/sel/studeez/{screens/home => common/composable/feed}/FeedEntry.kt (98%) create mode 100644 app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedUiState.kt rename app/src/main/java/be/ugent/sel/studeez/{screens/home => common/composable/feed}/FeedViewModel.kt (75%) delete mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt delete mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/home/HomeViewModel.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt new file mode 100644 index 0000000..6c7c0c1 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt @@ -0,0 +1,99 @@ +package be.ugent.sel.studeez.common.composable.feed + +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material.CircularProgressIndicator +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +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 be.ugent.sel.studeez.common.composable.DateText +import be.ugent.sel.studeez.data.local.models.FeedEntry +import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf + +data class FeedActions( + val getFeedEntries: () -> Flow>>, + val continueTask: (String, String) -> Unit, +) + +fun getFeedActions( + viewmodel: FeedViewModel, + open: (String) -> Unit, +): FeedActions { + return FeedActions( + getFeedEntries = viewmodel::getFeedEntries, + continueTask = { subjectId, taskId -> + viewmodel.continueTask( + open, + subjectId, + taskId, + ) + }, + ) +} + +@Composable +fun Feed( + feedActions: FeedActions, + uiState: FeedUiState, +) { + when (uiState) { + FeedUiState.Loading -> { + Column( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + CircularProgressIndicator(color = MaterialTheme.colors.onBackground) + } + } + is FeedUiState.Succes -> { +// val feedEntries = feedActions.getFeedEntries().collectAsState(initial = emptyMap()) + val feedEntries = uiState.feedEntries + LazyColumn { + items(feedEntries.toList()) { (date, feedEntries) -> + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .padding(10.dp), + verticalAlignment = Alignment.CenterVertically + ) { + val totalDayStudyTime: Int = feedEntries.sumOf { it.totalStudyTime } + DateText(date = date) + Text( + text = "${HoursMinutesSeconds(totalDayStudyTime)}", + fontSize = 15.sp, + fontWeight = FontWeight.Bold + ) + } + feedEntries.forEach { feedEntry -> + FeedEntry(feedEntry = feedEntry) { + feedActions.continueTask(feedEntry.subjectId, feedEntry.taskId) + } + } + Spacer(modifier = Modifier.height(20.dp)) + } + } + } + } +} + +@Preview +@Composable +fun FeedPreview() { + Feed( + feedActions = FeedActions({ flowOf() }, { _, _ -> run {} }), + uiState = FeedUiState.Loading, + ) +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt similarity index 98% rename from app/src/main/java/be/ugent/sel/studeez/screens/home/FeedEntry.kt rename to app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt index a7d1fc1..6dce710 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.home +package be.ugent.sel.studeez.common.composable.feed import androidx.compose.foundation.background import androidx.compose.foundation.layout.* diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedUiState.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedUiState.kt new file mode 100644 index 0000000..1b938ca --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedUiState.kt @@ -0,0 +1,8 @@ +package be.ugent.sel.studeez.common.composable.feed + +import be.ugent.sel.studeez.data.local.models.FeedEntry + +sealed interface FeedUiState { + object Loading : FeedUiState + data class Succes(val feedEntries: Map>) : FeedUiState +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt similarity index 75% rename from app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt rename to app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt index 1f57175..d31d83a 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.home +package be.ugent.sel.studeez.common.composable.feed import androidx.lifecycle.viewModelScope import be.ugent.sel.studeez.data.SelectedTask @@ -9,13 +9,13 @@ import be.ugent.sel.studeez.domain.TaskDAO import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class FeedViewModel @Inject constructor( - private val feedDAO: FeedDAO, + feedDAO: FeedDAO, private val taskDAO: TaskDAO, private val selectedTask: SelectedTask, logService: LogService @@ -23,6 +23,14 @@ class FeedViewModel @Inject constructor( private val entries: Flow>> = feedDAO.getFeedEntries() + val uiState: StateFlow = feedDAO.getFeedEntries() + .map { FeedUiState.Succes(it) } + .stateIn( + scope = viewModelScope, + initialValue = FeedUiState.Loading, + started = SharingStarted.Eagerly, + ) + fun getFeedEntries(): Flow>> { return entries } diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt index bd12413..5becc44 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt @@ -15,7 +15,6 @@ import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarViewModel import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions import be.ugent.sel.studeez.screens.home.HomeRoute -import be.ugent.sel.studeez.screens.home.getFeedActions import be.ugent.sel.studeez.screens.log_in.LoginRoute import be.ugent.sel.studeez.screens.profile.EditProfileRoute import be.ugent.sel.studeez.screens.profile.ProfileRoute @@ -66,10 +65,9 @@ fun StudeezNavGraph( composable(StudeezDestinations.HOME_SCREEN) { HomeRoute( open, - viewModel = hiltViewModel(), drawerActions = drawerActions, navigationBarActions = navigationBarActions, - feedActions = getFeedActions(hiltViewModel(), open), + feedViewModel = hiltViewModel(), ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt deleted file mode 100644 index 96a9623..0000000 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt +++ /dev/null @@ -1,70 +0,0 @@ -package be.ugent.sel.studeez.screens.home - -import androidx.compose.foundation.layout.* -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.unit.dp -import androidx.compose.ui.unit.sp -import be.ugent.sel.studeez.common.composable.DateText -import be.ugent.sel.studeez.data.local.models.FeedEntry -import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds -import kotlinx.coroutines.flow.Flow - -data class FeedActions( - val getFeedEntries: () -> Flow>>, - val continueTask: (String, String) -> Unit, -) - -fun getFeedActions( - viewmodel: FeedViewModel, - open: (String) -> Unit, -): FeedActions { - return FeedActions( - getFeedEntries = viewmodel::getFeedEntries, - continueTask = { subjectId, taskId -> - viewmodel.continueTask( - open, - subjectId, - taskId, - ) - }, - ) -} - -@Composable -fun Feed( - feedActions: FeedActions, -) { - val feedEntries = feedActions.getFeedEntries().collectAsState(initial = emptyMap()) - LazyColumn { - items(feedEntries.value.toList()) { (date, feedEntries) -> - Row( - horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier - .fillMaxWidth() - .padding(10.dp), - verticalAlignment = Alignment.CenterVertically - ) { - val totalDayStudyTime: Int = feedEntries.sumOf { it.totalStudyTime } - DateText(date = date) - Text( - text = "${HoursMinutesSeconds(totalDayStudyTime)}", - fontSize = 15.sp, - fontWeight = FontWeight.Bold - ) - } - feedEntries.forEach { feedEntry -> - FeedEntry(feedEntry = feedEntry) { - feedActions.continueTask(feedEntry.subjectId, feedEntry.taskId) - } - } - Spacer(modifier = Modifier.height(20.dp)) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index 79f03e3..78d5ddb 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -5,10 +5,13 @@ import androidx.compose.material.IconButton import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Person import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.tooling.preview.Preview import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate import be.ugent.sel.studeez.common.composable.drawer.DrawerActions +import be.ugent.sel.studeez.common.composable.feed.* import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.resources import kotlinx.coroutines.flow.flowOf @@ -16,16 +19,17 @@ import kotlinx.coroutines.flow.flowOf @Composable fun HomeRoute( open: (String) -> Unit, - viewModel: HomeViewModel, drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, - feedActions: FeedActions, + feedViewModel: FeedViewModel, ) { + val feedUiState by feedViewModel.uiState.collectAsState() HomeScreen( drawerActions = drawerActions, open = open, navigationBarActions = navigationBarActions, - feedActions = feedActions, + feedActions = getFeedActions(feedViewModel, open), + feedUiState = feedUiState, ) } @@ -35,6 +39,7 @@ fun HomeScreen( drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, feedActions: FeedActions, + feedUiState: FeedUiState, ) { PrimaryScreenTemplate( title = resources().getString(R.string.home), @@ -42,7 +47,7 @@ fun HomeScreen( navigationBarActions = navigationBarActions, // TODO barAction = { FriendsAction() } ) { - Feed(feedActions) + Feed(feedActions, feedUiState) } } @@ -63,6 +68,7 @@ fun HomeScreenPreview() { drawerActions = DrawerActions({}, {}, {}, {}, {}), navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), open = {}, - feedActions = FeedActions({ flowOf() }, { _, _ -> run {} }) + feedActions = FeedActions({ flowOf() }, { _, _ -> run {} }), + feedUiState = FeedUiState.Loading, ) } 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 deleted file mode 100644 index b27f995..0000000 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeViewModel.kt +++ /dev/null @@ -1,19 +0,0 @@ -package be.ugent.sel.studeez.screens.home - -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.screens.StudeezViewModel -import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject - -@HiltViewModel -class HomeViewModel @Inject constructor( - private val accountDAO: AccountDAO, - logService: LogService -) : StudeezViewModel(logService) { - - fun onStartSessionClick(open: (String) -> Unit) { - open(StudeezDestinations.TIMER_SELECTION_SCREEN) - } -} \ No newline at end of file From 366f236f9865136ce36206a084e938f4c0c14951 Mon Sep 17 00:00:00 2001 From: brreynie Date: Mon, 8 May 2023 22:14:17 +0200 Subject: [PATCH 31/38] add previews for feed --- .../studeez/common/composable/feed/Feed.kt | 70 +++++++++++-------- .../common/composable/feed/FeedViewModel.kt | 6 -- .../sel/studeez/screens/home/HomeScreen.kt | 45 ++++++++++-- 3 files changed, 80 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt index 6c7c0c1..5dac1c0 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt @@ -16,34 +16,11 @@ import androidx.compose.ui.unit.sp import be.ugent.sel.studeez.common.composable.DateText import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf - -data class FeedActions( - val getFeedEntries: () -> Flow>>, - val continueTask: (String, String) -> Unit, -) - -fun getFeedActions( - viewmodel: FeedViewModel, - open: (String) -> Unit, -): FeedActions { - return FeedActions( - getFeedEntries = viewmodel::getFeedEntries, - continueTask = { subjectId, taskId -> - viewmodel.continueTask( - open, - subjectId, - taskId, - ) - }, - ) -} @Composable fun Feed( - feedActions: FeedActions, uiState: FeedUiState, + continueTask: (String, String) -> Unit, ) { when (uiState) { FeedUiState.Loading -> { @@ -58,7 +35,6 @@ fun Feed( } } is FeedUiState.Succes -> { -// val feedEntries = feedActions.getFeedEntries().collectAsState(initial = emptyMap()) val feedEntries = uiState.feedEntries LazyColumn { items(feedEntries.toList()) { (date, feedEntries) -> @@ -79,7 +55,7 @@ fun Feed( } feedEntries.forEach { feedEntry -> FeedEntry(feedEntry = feedEntry) { - feedActions.continueTask(feedEntry.subjectId, feedEntry.taskId) + continueTask(feedEntry.subjectId, feedEntry.taskId) } } Spacer(modifier = Modifier.height(20.dp)) @@ -89,11 +65,49 @@ fun Feed( } } +@Preview +@Composable +fun FeedLoadingPreview() { + Feed( + uiState = FeedUiState.Loading, + continueTask = { _, _ -> run {} }, + ) +} + @Preview @Composable fun FeedPreview() { Feed( - feedActions = FeedActions({ flowOf() }, { _, _ -> run {} }), - uiState = FeedUiState.Loading, + uiState = FeedUiState.Succes( + mapOf( + "08 May 2023" to listOf( + FeedEntry( + argb_color = 0xFFFFD200, + subJectName = "Test Subject", + taskName = "Test Task", + totalStudyTime = 600, + ), + FeedEntry( + argb_color = 0xFFFFD200, + subJectName = "Test Subject", + taskName = "Test Task", + totalStudyTime = 20, + ), + ), + "09 May 2023" to listOf( + FeedEntry( + argb_color = 0xFFFD1200, + subJectName = "Test Subject", + taskName = "Test Task", + ), + FeedEntry( + argb_color = 0xFFFFD200, + subJectName = "Test Subject", + taskName = "Test Task", + ), + ) + ) + ), + continueTask = { _, _ -> run {} }, ) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt index d31d83a..443d0c9 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt @@ -21,8 +21,6 @@ class FeedViewModel @Inject constructor( logService: LogService ) : StudeezViewModel(logService) { - private val entries: Flow>> = feedDAO.getFeedEntries() - val uiState: StateFlow = feedDAO.getFeedEntries() .map { FeedUiState.Succes(it) } .stateIn( @@ -31,10 +29,6 @@ class FeedViewModel @Inject constructor( started = SharingStarted.Eagerly, ) - fun getFeedEntries(): Flow>> { - return entries - } - fun continueTask(open: (String) -> Unit, subjectId: String, taskId: String) { viewModelScope.launch { val task = taskDAO.getTask(subjectId, taskId) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index 78d5ddb..dad3dd2 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -11,10 +11,12 @@ import androidx.compose.ui.tooling.preview.Preview import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate import be.ugent.sel.studeez.common.composable.drawer.DrawerActions -import be.ugent.sel.studeez.common.composable.feed.* +import be.ugent.sel.studeez.common.composable.feed.Feed +import be.ugent.sel.studeez.common.composable.feed.FeedUiState +import be.ugent.sel.studeez.common.composable.feed.FeedViewModel import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions +import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.resources -import kotlinx.coroutines.flow.flowOf @Composable fun HomeRoute( @@ -28,8 +30,8 @@ fun HomeRoute( drawerActions = drawerActions, open = open, navigationBarActions = navigationBarActions, - feedActions = getFeedActions(feedViewModel, open), feedUiState = feedUiState, + continueTask = { subjectId, taskId -> feedViewModel.continueTask(open, subjectId, taskId) }, ) } @@ -38,8 +40,8 @@ fun HomeScreen( open: (String) -> Unit, drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, - feedActions: FeedActions, feedUiState: FeedUiState, + continueTask: (String, String) -> Unit, ) { PrimaryScreenTemplate( title = resources().getString(R.string.home), @@ -47,7 +49,7 @@ fun HomeScreen( navigationBarActions = navigationBarActions, // TODO barAction = { FriendsAction() } ) { - Feed(feedActions, feedUiState) + Feed(feedUiState, continueTask) } } @@ -68,7 +70,36 @@ fun HomeScreenPreview() { drawerActions = DrawerActions({}, {}, {}, {}, {}), navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), open = {}, - feedActions = FeedActions({ flowOf() }, { _, _ -> run {} }), - feedUiState = FeedUiState.Loading, + feedUiState = FeedUiState.Succes( + mapOf( + "08 May 2023" to listOf( + FeedEntry( + argb_color = 0xFFABD200, + subJectName = "Test Subject", + taskName = "Test Task", + totalStudyTime = 600, + ), + FeedEntry( + argb_color = 0xFFFFD200, + subJectName = "Test Subject", + taskName = "Test Task", + totalStudyTime = 20, + ), + ), + "09 May 2023" to listOf( + FeedEntry( + argb_color = 0xFFFD1200, + subJectName = "Test Subject", + taskName = "Test Task", + ), + FeedEntry( + argb_color = 0xFFFF5C89, + subJectName = "Test Subject", + taskName = "Test Task", + ), + ) + ) + ), + continueTask = { _, _ -> run {} }, ) } From 1293ea31133ee40dde21a60e37b2ad9c39e377af Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 9 May 2023 16:17:10 +0200 Subject: [PATCH 32/38] #74 refactor feed --- .../studeez/common/composable/feed/Feed.kt | 115 ++++++++++++------ 1 file changed, 81 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt index 5dac1c0..54be2ea 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt @@ -9,58 +9,105 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource 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 be.ugent.sel.studeez.common.composable.BasicTextButton import be.ugent.sel.studeez.common.composable.DateText +import be.ugent.sel.studeez.common.composable.Headline +import be.ugent.sel.studeez.common.ext.textButton import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds +import be.ugent.sel.studeez.R.string as AppText @Composable fun Feed( uiState: FeedUiState, continueTask: (String, String) -> Unit, + onEmptyFeedHelp: () -> Unit ) { when (uiState) { - FeedUiState.Loading -> { - Column( + FeedUiState.Loading -> LoadingFeed() + is FeedUiState.Succes -> LoadedFeed( + uiState = uiState, + continueTask = continueTask, + onEmptyFeedHelp = onEmptyFeedHelp + ) + } +} + +@Composable +fun LoadedFeed( + uiState: FeedUiState.Succes, + continueTask: (String, String) -> Unit, + onEmptyFeedHelp: () -> Unit, +) { + if (uiState.feedEntries.isEmpty()) EmptyFeed(onEmptyFeedHelp) + else FeedWithElements(uiState = uiState, continueTask = continueTask) +} + +@Composable +fun LoadingFeed() { + Column( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + CircularProgressIndicator(color = MaterialTheme.colors.onBackground) + } +} + +@Composable +fun FeedWithElements( + uiState: FeedUiState.Succes, + continueTask: (String, String) -> Unit, +) { + val feedEntries = uiState.feedEntries + LazyColumn { + items(feedEntries.toList()) { (date, feedEntries) -> + Row( + horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier .fillMaxWidth() - .fillMaxHeight(), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + .padding(10.dp), + verticalAlignment = Alignment.CenterVertically ) { - CircularProgressIndicator(color = MaterialTheme.colors.onBackground) + val totalDayStudyTime: Int = feedEntries.sumOf { it.totalStudyTime } + DateText(date = date) + Text( + text = "${HoursMinutesSeconds(totalDayStudyTime)}", + fontSize = 15.sp, + fontWeight = FontWeight.Bold + ) } - } - is FeedUiState.Succes -> { - val feedEntries = uiState.feedEntries - LazyColumn { - items(feedEntries.toList()) { (date, feedEntries) -> - Row( - horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier - .fillMaxWidth() - .padding(10.dp), - verticalAlignment = Alignment.CenterVertically - ) { - val totalDayStudyTime: Int = feedEntries.sumOf { it.totalStudyTime } - DateText(date = date) - Text( - text = "${HoursMinutesSeconds(totalDayStudyTime)}", - fontSize = 15.sp, - fontWeight = FontWeight.Bold - ) - } - feedEntries.forEach { feedEntry -> - FeedEntry(feedEntry = feedEntry) { - continueTask(feedEntry.subjectId, feedEntry.taskId) - } - } - Spacer(modifier = Modifier.height(20.dp)) + feedEntries.forEach { feedEntry -> + FeedEntry(feedEntry = feedEntry) { + continueTask(feedEntry.subjectId, feedEntry.taskId) } } + Spacer(modifier = Modifier.height(20.dp)) + } + } +} + +@Composable +fun EmptyFeed(onEmptyFeedHelp: () -> Unit) { + Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.fillMaxWidth() + ) { + Headline(text = stringResource(id = AppText.your_feed)) + + BasicTextButton( + AppText.empty_feed_help_text, + Modifier.textButton(), + action = onEmptyFeedHelp, + ) } } } @@ -70,7 +117,7 @@ fun Feed( fun FeedLoadingPreview() { Feed( uiState = FeedUiState.Loading, - continueTask = { _, _ -> run {} }, + continueTask = { _, _ -> run {} }, {} ) } @@ -108,6 +155,6 @@ fun FeedPreview() { ) ) ), - continueTask = { _, _ -> run {} }, + continueTask = { _, _ -> run {} }, {} ) } \ No newline at end of file From 0fb3125f6a4ce5d33e8c42fbde874b0deb38dc05 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 9 May 2023 16:17:46 +0200 Subject: [PATCH 33/38] #74 button to add subject when user has empty feed --- .../ugent/sel/studeez/common/composable/feed/FeedViewModel.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt index 443d0c9..fbd32f4 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt @@ -36,4 +36,8 @@ class FeedViewModel @Inject constructor( open(StudeezDestinations.TIMER_SELECTION_SCREEN) } } + + fun onEmptyFeedHelp(open: (String) -> Unit) { + open(StudeezDestinations.ADD_SUBJECT_FORM) + } } \ No newline at end of file From 9bf77b556c19c5a0bccd75d3ddfed396623e96a1 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 9 May 2023 16:19:03 +0200 Subject: [PATCH 34/38] added function that opens subject add screen --- .../java/be/ugent/sel/studeez/screens/home/HomeScreen.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index dad3dd2..c93527b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -32,6 +32,7 @@ fun HomeRoute( navigationBarActions = navigationBarActions, feedUiState = feedUiState, continueTask = { subjectId, taskId -> feedViewModel.continueTask(open, subjectId, taskId) }, + onEmptyFeedHelp = { feedViewModel.onEmptyFeedHelp(open) } ) } @@ -42,6 +43,7 @@ fun HomeScreen( navigationBarActions: NavigationBarActions, feedUiState: FeedUiState, continueTask: (String, String) -> Unit, + onEmptyFeedHelp: () -> Unit, ) { PrimaryScreenTemplate( title = resources().getString(R.string.home), @@ -49,7 +51,7 @@ fun HomeScreen( navigationBarActions = navigationBarActions, // TODO barAction = { FriendsAction() } ) { - Feed(feedUiState, continueTask) + Feed(feedUiState, continueTask, onEmptyFeedHelp) } } @@ -101,5 +103,6 @@ fun HomeScreenPreview() { ) ), continueTask = { _, _ -> run {} }, + onEmptyFeedHelp = {} ) } From 5be8432b18119ebf3b13465184cd0279fb478afe Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 9 May 2023 16:19:38 +0200 Subject: [PATCH 35/38] edit button on the right --- .../screens/timer_overview/TimerOverviewScreen.kt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) 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 a07dd67..3c25ddf 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 @@ -82,12 +82,13 @@ fun TimerOverviewScreen( items(timers.value) { timerInfo -> TimerEntry( timerInfo = timerInfo, - ) { - StealthButton( - text = R.string.edit, - onClick = { timerOverviewActions.onEditClick(timerInfo) } - ) - } + rightButton = { + StealthButton( + text = R.string.edit, + onClick = { timerOverviewActions.onEditClick(timerInfo) } + ) + } + ) } From 4fa7f97513d3cc00e79f3fc9d5643931b1bce4f6 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 9 May 2023 16:20:39 +0200 Subject: [PATCH 36/38] added padding to custom timer time picker button --- .../screens/timer_selection/TimerSelectionScreen.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt index 2f17e65..d78b4bf 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionScreen.kt @@ -1,10 +1,13 @@ package be.ugent.sel.studeez.screens.timer_selection +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate import be.ugent.sel.studeez.common.composable.StealthButton @@ -99,7 +102,10 @@ fun CustomTimerEntry( ) }, rightButton = { - TimePickerButton(initialSeconds = hms.getTotalSeconds()) { chosenTime -> + TimePickerButton( + initialSeconds = hms.getTotalSeconds(), + modifier = Modifier.padding(horizontal = 5.dp) + ) { chosenTime -> timerInfo.studyTime = chosenTime } } From 5992abf9c767ecbbec01b81888dcca4486366f7e Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 9 May 2023 16:21:08 +0200 Subject: [PATCH 37/38] default of custom timer is 1 hour --- .../screens/timer_selection/TimerSelectionViewModel.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionViewModel.kt index ab42973..a4f646d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionViewModel.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import be.ugent.sel.studeez.data.SelectedTimerState +import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.domain.TimerDAO @@ -21,7 +22,9 @@ class TimerSelectionViewModel @Inject constructor( logService: LogService ) : StudeezViewModel(logService) { - var customTimerStudyTime: MutableState = mutableStateOf(0) + var customTimerStudyTime: MutableState = mutableStateOf( + HoursMinutesSeconds(1, 0, 0).getTotalSeconds() + ) fun getAllTimers() : Flow> { return timerDAO.getAllTimers() From 529adbcab322797c29ed0943cc6ba2b94a8bb1a9 Mon Sep 17 00:00:00 2001 From: Lukas Barragan Torres Date: Tue, 9 May 2023 16:21:37 +0200 Subject: [PATCH 38/38] added feed string --- 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 bc00963..d58be52 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -31,6 +31,8 @@ Continue + This is your feed + Create you first subject and tasks to get started Tasks