diff --git a/.idea/misc.xml b/.idea/misc.xml index 4412b1a..aa62d28 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index c8a133b..d72bedf 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -40,6 +40,7 @@ import be.ugent.sel.studeez.screens.session.SessionRoute import be.ugent.sel.studeez.screens.session_recap.SessionRecapRoute import be.ugent.sel.studeez.screens.sign_up.SignUpRoute import be.ugent.sel.studeez.screens.splash.SplashRoute +import be.ugent.sel.studeez.screens.tasks.TaskRoute import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute import be.ugent.sel.studeez.ui.theme.StudeezTheme @@ -145,7 +146,14 @@ fun StudeezNavGraph( ) } - // TODO Tasks screen + composable(StudeezDestinations.TASKS_SCREEN) { + TaskRoute( + open = open, + viewModel = hiltViewModel(), + drawerActions = drawerActions, + navigationBarActions = navigationBarActions, + ) + } // TODO Sessions screen composable(StudeezDestinations.PROFILE_SCREEN) { diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt new file mode 100644 index 0000000..928ab36 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt @@ -0,0 +1,19 @@ +package be.ugent.sel.studeez.common.composable + +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview +import be.ugent.sel.studeez.data.local.models.task.Subject + +@Composable +fun SubjectEntry( + subject: Subject, +) { + Text(text = subject.name) +} + +@Preview +@Composable +fun SubjectEntryPreview() { + SubjectEntry(subject = Subject(name = "Test Subject")) +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt index 1e4bd0d..7b1d012 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt @@ -1,16 +1,15 @@ package be.ugent.sel.studeez.common.composable.navbar -import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.navigation.StudeezDestinations.HOME_SCREEN import be.ugent.sel.studeez.navigation.StudeezDestinations.PROFILE_SCREEN +import be.ugent.sel.studeez.navigation.StudeezDestinations.TASKS_SCREEN import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel class NavigationBarViewModel @Inject constructor( - private val accountDAO: AccountDAO, logService: LogService ) : StudeezViewModel(logService) { @@ -19,7 +18,7 @@ class NavigationBarViewModel @Inject constructor( } fun onTasksClick(open: (String) -> Unit) { - // TODO + open(TASKS_SCREEN) } fun onSessionsClick(open: (String) -> Unit) { 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 af6b1c0..20a44a8 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,4 +7,4 @@ data class SessionReport( @DocumentId val id: String = "", val studyTime: Int = 0, val endTime: Timestamp = Timestamp(0, 0) - ) \ No newline at end of file +) \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Subject.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Subject.kt new file mode 100644 index 0000000..034711a --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Subject.kt @@ -0,0 +1,11 @@ +package be.ugent.sel.studeez.data.local.models.task + +import com.google.firebase.firestore.DocumentId + +data class Subject( + @DocumentId val id: String = "", + val name: String = "", + val tasks: List = mutableListOf(), + val time: Int = 0, + val color: Int = 0, +) \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Task.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Task.kt new file mode 100644 index 0000000..62ebf7d --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Task.kt @@ -0,0 +1,9 @@ +package be.ugent.sel.studeez.data.local.models.task + +import com.google.firebase.firestore.DocumentId + +data class Task( + @DocumentId val id: String = "", + val name: String = "", + val completed: Boolean = false, +) 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 1b696fe..e4228bb 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 @@ -10,15 +10,24 @@ import dagger.hilt.components.SingletonComponent @Module @InstallIn(SingletonComponent::class) abstract class DatabaseModule { - @Binds abstract fun provideAccountDAO(impl: FirebaseAccountDAO): AccountDAO + @Binds + abstract fun provideAccountDAO(impl: FirebaseAccountDAO): AccountDAO - @Binds abstract fun provideUserDAO(impl: FirebaseUserDAO): UserDAO + @Binds + abstract fun provideUserDAO(impl: FirebaseUserDAO): UserDAO - @Binds abstract fun provideTimerDAO(impl: FirebaseTimerDAO): TimerDAO + @Binds + abstract fun provideTimerDAO(impl: FirebaseTimerDAO): TimerDAO - @Binds abstract fun provideLogService(impl: LogServiceImpl): LogService + @Binds + abstract fun provideLogService(impl: LogServiceImpl): LogService - @Binds abstract fun provideConfigurationService(impl: FirebaseConfigurationService): ConfigurationService + @Binds + abstract fun provideConfigurationService(impl: FirebaseConfigurationService): ConfigurationService - @Binds abstract fun provideSessionDAO(impl: FireBaseSessionDAO): SessionDAO + @Binds + abstract fun provideSessionDAO(impl: FireBaseSessionDAO): SessionDAO + + @Binds + abstract fun provideSubjectDAO(impl: FireBaseSubjectDAO): SubjectDAO } \ No newline at end of file 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 new file mode 100644 index 0000000..dd24b45 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt @@ -0,0 +1,13 @@ +package be.ugent.sel.studeez.domain + +import be.ugent.sel.studeez.data.local.models.task.Subject +import kotlinx.coroutines.flow.Flow + +interface SubjectDAO { + + fun getSubjects(): Flow> + + fun saveSubject(newSubject: Subject) + + fun deleteSubject(oldSubject: Subject) +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseCollectionRoutes.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseCollections.kt similarity index 70% rename from app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseCollectionRoutes.kt rename to app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseCollections.kt index 2471301..a36361c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseCollectionRoutes.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseCollections.kt @@ -1,8 +1,8 @@ package be.ugent.sel.studeez.domain.implementation -object FirebaseCollectionRoutes { +object FireBaseCollections { const val SESSION_COLLECTION = "sessions" const val USER_COLLECTION = "users" const val TIMER_COLLECTION = "timers" - + const val SUBJECT_COLLECTION = "subjects" } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSessionDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSessionDAO.kt index 07afdda..a818236 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSessionDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSessionDAO.kt @@ -31,8 +31,7 @@ class FireBaseSessionDAO @Inject constructor( } private fun currentUserSessionsCollection(): CollectionReference = - firestore.collection(FirebaseCollectionRoutes.USER_COLLECTION) + firestore.collection(FireBaseCollections.USER_COLLECTION) .document(auth.currentUserId) - .collection(FirebaseCollectionRoutes.SESSION_COLLECTION) - + .collection(FireBaseCollections.SESSION_COLLECTION) } \ No newline at end of file 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 new file mode 100644 index 0000000..364bdfc --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt @@ -0,0 +1,35 @@ +package be.ugent.sel.studeez.domain.implementation + +import be.ugent.sel.studeez.data.local.models.task.Subject +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 kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import javax.inject.Inject + +class FireBaseSubjectDAO @Inject constructor( + private val firestore: FirebaseFirestore, + private val auth: AccountDAO, +) : SubjectDAO { + override fun getSubjects(): Flow> { + return currentUserSubjectsCollection() + .snapshots() + .map { it.toObjects(Subject::class.java) } + } + + override fun saveSubject(newSubject: Subject) { + currentUserSubjectsCollection().add(newSubject) + } + + override fun deleteSubject(oldSubject: Subject) { + TODO("Not yet implemented") + } + + private fun currentUserSubjectsCollection(): CollectionReference = + firestore.collection(FireBaseCollections.USER_COLLECTION) + .document(auth.currentUserId) + .collection(FireBaseCollections.SUBJECT_COLLECTION) +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt index 901f9d6..1f37a18 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt @@ -1,11 +1,9 @@ package be.ugent.sel.studeez.domain.implementation import be.ugent.sel.studeez.data.local.models.timer_info.* -import be.ugent.sel.studeez.data.local.models.timer_info.TimerType.* import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.TimerDAO import com.google.firebase.firestore.CollectionReference -import com.google.firebase.firestore.DocumentSnapshot import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.ktx.snapshots import kotlinx.coroutines.flow.Flow @@ -50,8 +48,8 @@ class FirebaseTimerDAO @Inject constructor( } private fun currentUserTimersCollection(): CollectionReference = - firestore.collection(FirebaseCollectionRoutes.USER_COLLECTION) + firestore.collection(FireBaseCollections.USER_COLLECTION) .document(auth.currentUserId) - .collection(FirebaseCollectionRoutes.TIMER_COLLECTION) + .collection(FireBaseCollections.TIMER_COLLECTION) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt index ab10c22..c6d39cd 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt @@ -10,7 +10,7 @@ object StudeezDestinations { const val TIMER_SELECTION_SCREEN = "timer_selection" const val SESSION_SCREEN = "session" const val SESSION_RECAP = "session_recap" - // const val TASKS_SCREEN = "tasks" + const val TASKS_SCREEN = "tasks" // const val SESSIONS_SCREEN = "sessions" const val PROFILE_SCREEN = "profile" 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 new file mode 100644 index 0000000..c4ad625 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -0,0 +1,77 @@ +package be.ugent.sel.studeez.screens.tasks + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material.Button +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +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.SubjectEntry +import be.ugent.sel.studeez.common.composable.drawer.DrawerActions +import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions +import be.ugent.sel.studeez.data.local.models.task.Subject +import be.ugent.sel.studeez.resources +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf + +@Composable +fun TaskRoute( + open: (String) -> Unit, + viewModel: TaskViewModel, + drawerActions: DrawerActions, + navigationBarActions: NavigationBarActions, +) { + TaskScreen( + drawerActions = drawerActions, + navigationBarActions = navigationBarActions, + addSubject = { viewModel.addSubject() }, + ) { viewModel.getSubjects() } +} + +@Composable +fun TaskScreen( + drawerActions: DrawerActions, + navigationBarActions: NavigationBarActions, + addSubject: () -> Unit, + getSubjects: () -> Flow>, +) { + PrimaryScreenTemplate( + title = resources().getString(R.string.tasks), + drawerActions = drawerActions, + navigationBarActions = navigationBarActions, + barAction = {}, + ) { + val subjects = getSubjects().collectAsState(initial = emptyList()) + Column { + LazyColumn { + items(subjects.value) { + SubjectEntry(subject = it) + } + } + AddSubjectButton(onClick = addSubject) + } + } +} + +@Composable +fun AddSubjectButton( + onClick: () -> Unit, +) { + Button(onClick = onClick) { + Text(text = "Test Button") + } +} + +@Preview +@Composable +fun TaskScreenPreview() { + TaskScreen( + drawerActions = DrawerActions({}, {}, {}, {}, {}), + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), + {}, + ) { flowOf() } +} \ 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 new file mode 100644 index 0000000..da489a5 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt @@ -0,0 +1,30 @@ +package be.ugent.sel.studeez.screens.tasks + +import be.ugent.sel.studeez.data.local.models.task.Subject +import be.ugent.sel.studeez.domain.LogService +import be.ugent.sel.studeez.domain.SubjectDAO +import be.ugent.sel.studeez.screens.StudeezViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +@HiltViewModel +class TaskViewModel @Inject constructor( + private val subjectDAO: SubjectDAO, + logService: LogService, +) : StudeezViewModel(logService) { + fun addSubject() { + subjectDAO.saveSubject( + Subject( + name = "Test Subject", + tasks = listOf(), + time = 0, + color = 0, + ) + ) + } + + fun getSubjects(): Flow> { + return subjectDAO.getSubjects() + } +} \ No newline at end of file