QOL improvements & friendsSessionsDAOstuff

This commit is contained in:
Tibo De Peuter 2023-05-15 22:40:36 +02:00
parent 10c86c9bf0
commit a814bd74d7
9 changed files with 154 additions and 46 deletions

View file

@ -0,0 +1,44 @@
package be.ugent.sel.studeez.common.composable
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person
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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import be.ugent.sel.studeez.R
import be.ugent.sel.studeez.ui.theme.StudeezTheme
@Composable
fun ProfilePicture() {
Box(
modifier = Modifier
.size(40.dp)
.background(MaterialTheme.colors.primary, CircleShape)
) {
Icon(
imageVector = Icons.Default.Person,
contentDescription = stringResource(id = R.string.username),
modifier = Modifier
.size(30.dp)
.align(Alignment.Center),
tint = MaterialTheme.colors.onPrimary
)
}
}
@Preview
@Composable
fun ProfilePicturePreview() {
StudeezTheme {
ProfilePicture()
}
}

View file

@ -0,0 +1,6 @@
package be.ugent.sel.studeez.data.remote
object FirebaseSessionReport {
const val STUDYTIME: String = "studyTime"
const val ENDTIME: String = "endTime"
}

View file

@ -1,12 +1,19 @@
package be.ugent.sel.studeez.domain
import be.ugent.sel.studeez.data.local.models.SessionReport
import be.ugent.sel.studeez.data.local.models.User
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
import kotlinx.coroutines.flow.Flow
interface SessionDAO {
fun getSessions(): Flow<List<SessionReport>>
suspend fun getSessionsOfUser(userId: String): List<SessionReport>
/**
* Return a list of pairs, containing the username and all the studysessions of that user.
*/
fun getFriendsSessions(): Flow<List<Pair<String,List<SessionReport>>>>
fun saveSession(newSessionReport: SessionReport)

View file

@ -27,6 +27,10 @@ interface UserDAO {
userId: String
): Flow<User>
suspend fun getUsername(
userId: String
): String
/**
* @return information on the currently logged in user.
*/

View file

@ -1,19 +1,33 @@
package be.ugent.sel.studeez.domain.implementation
import be.ugent.sel.studeez.data.local.models.SessionReport
import be.ugent.sel.studeez.data.local.models.User
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
import be.ugent.sel.studeez.data.remote.FirebaseSessionReport
import be.ugent.sel.studeez.data.remote.FirebaseSessionReport.ENDTIME
import be.ugent.sel.studeez.data.remote.FirebaseSessionReport.STUDYTIME
import be.ugent.sel.studeez.domain.AccountDAO
import be.ugent.sel.studeez.domain.FriendshipDAO
import be.ugent.sel.studeez.domain.SessionDAO
import be.ugent.sel.studeez.domain.UserDAO
import be.ugent.sel.studeez.domain.implementation.FirebaseCollections.SESSION_COLLECTION
import be.ugent.sel.studeez.domain.implementation.FirebaseCollections.USER_COLLECTION
import com.google.firebase.Timestamp
import com.google.firebase.firestore.CollectionReference
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.getField
import com.google.firebase.firestore.ktx.snapshots
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.tasks.await
import javax.inject.Inject
class FirebaseSessionDAO @Inject constructor(
private val firestore: FirebaseFirestore,
private val auth: AccountDAO
private val auth: AccountDAO,
private val userDAO: UserDAO,
private val friendshipDAO: FriendshipDAO
) : SessionDAO {
override fun getSessions(): Flow<List<SessionReport>> {
@ -22,6 +36,34 @@ class FirebaseSessionDAO @Inject constructor(
.map { it.toObjects(SessionReport::class.java) }
}
override suspend fun getSessionsOfUser(userId: String): List<SessionReport> {
val collection = firestore.collection(USER_COLLECTION)
.document(userId)
.collection(SESSION_COLLECTION)
.get().await()
val list: MutableList<SessionReport> = mutableListOf()
for (document in collection) {
val id = document.id
val studyTime: Int = document.getField<Int>(STUDYTIME)!!
val endTime: Timestamp = document.getField<Timestamp>(ENDTIME)!!
list.add(SessionReport(id, studyTime, endTime))
}
return list
}
override fun getFriendsSessions(): Flow<List<Pair<String, List<SessionReport>>>> {
return friendshipDAO.getAllFriendships(auth.currentUserId)
.map { friendships ->
friendships.map { friendship ->
val userId: String = friendship.friendId
val username = userDAO.getUsername(userId)
val userSessions = getSessionsOfUser(userId)
Pair(username, userSessions)
}
}
}
override fun saveSession(newSessionReport: SessionReport) {
currentUserSessionsCollection().add(newSessionReport)
}
@ -31,7 +73,7 @@ class FirebaseSessionDAO @Inject constructor(
}
private fun currentUserSessionsCollection(): CollectionReference =
firestore.collection(FirebaseCollections.USER_COLLECTION)
firestore.collection(USER_COLLECTION)
.document(auth.currentUserId)
.collection(FirebaseCollections.SESSION_COLLECTION)
.collection(SESSION_COLLECTION)
}

View file

@ -61,6 +61,13 @@ class FirebaseUserDAO @Inject constructor(
}
}
override suspend fun getUsername(userId: String): String {
val user = firestore.collection(USER_COLLECTION)
.document(userId)
.get().await()
return user.getString(USERNAME)!!
}
override suspend fun getLoggedInUser(): User {
val userDocument = currentUserDocument().get().await()
return User(

View file

@ -14,7 +14,6 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextOverflow
@ -23,6 +22,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import be.ugent.sel.studeez.R
import be.ugent.sel.studeez.common.composable.BasicButton
import be.ugent.sel.studeez.common.composable.ProfilePicture
import be.ugent.sel.studeez.common.composable.SearchField
import be.ugent.sel.studeez.common.composable.drawer.DrawerEntry
import be.ugent.sel.studeez.common.ext.basicButton
@ -162,29 +162,21 @@ fun FriendsEntry(
viewProfile: (String) -> Unit,
removeFriend: (Friendship) -> Unit
) {
// TODO Styling
Row (
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 15.dp, vertical = 7.dp),
) {
Box(
modifier = Modifier
.fillMaxWidth(0.15f)
.background(MaterialTheme.colors.primary, CircleShape)
.padding(vertical = 4.dp)
) {
Icon(
painter = painterResource(id = R.drawable.ic_visibility_on),
contentDescription = null,
modifier = Modifier
.fillMaxHeight()
.align(Alignment.Center),
tint = MaterialTheme.colors.onPrimary
)
ProfilePicture()
}
Box (
modifier = Modifier
.fillMaxWidth(0.65f)
.fillMaxWidth()
) {
Column (
modifier = Modifier
@ -203,10 +195,10 @@ fun FriendsEntry(
overflow = TextOverflow.Ellipsis
)
}
}
Box(
modifier = Modifier.fillMaxWidth(0.15f)
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.CenterEnd
) {
FriendsOverviewDropDown(
friendship = friendship,
@ -216,6 +208,7 @@ fun FriendsEntry(
}
}
}
}
@Preview
@Composable

View file

@ -13,7 +13,6 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextOverflow
@ -21,12 +20,14 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import be.ugent.sel.studeez.R
import be.ugent.sel.studeez.common.composable.ProfilePicture
import be.ugent.sel.studeez.common.composable.SearchField
import be.ugent.sel.studeez.common.composable.drawer.DrawerEntry
import be.ugent.sel.studeez.data.local.models.User
import be.ugent.sel.studeez.resources
import be.ugent.sel.studeez.ui.theme.StudeezTheme
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import be.ugent.sel.studeez.R.string as AppText
data class SearchFriendsActions(
@ -153,25 +154,19 @@ fun UserEntry(
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 15.dp, vertical = 7.dp),
horizontalArrangement = Arrangement.spacedBy(15.dp)
) {
Box(
modifier = Modifier
.fillMaxWidth(0.15f)
.background(MaterialTheme.colors.primary, CircleShape)
.padding(vertical = 4.dp)
) {
Icon(
painter = painterResource(id = R.drawable.ic_visibility_on),
contentDescription = null,
modifier = Modifier
.fillMaxHeight()
.align(Alignment.Center),
tint = MaterialTheme.colors.onPrimary
)
ProfilePicture()
}
Box (
modifier = Modifier
.fillMaxWidth(0.65f)
.fillMaxWidth()
) {
Column (
modifier = Modifier
@ -190,10 +185,10 @@ fun UserEntry(
overflow = TextOverflow.Ellipsis
)
}
}
Box(
modifier = Modifier.fillMaxWidth(0.15f)
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.CenterEnd
) {
SearchFriendsDropDown(
user = user,
@ -202,6 +197,7 @@ fun UserEntry(
}
}
}
}
@Preview
@Composable

View file

@ -10,6 +10,7 @@ import be.ugent.sel.studeez.screens.StudeezViewModel
import be.ugent.sel.studeez.screens.profile.public_profile.SelectedProfileState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import javax.inject.Inject
@HiltViewModel
@ -43,8 +44,16 @@ class SearchFriendsViewModel @Inject constructor(
)
}
/**
* Get all users, except for the current user.
*/
fun getAllUsers(): Flow<List<User>> {
return userDAO.getAllUsers()
.filter { users ->
users.any { user ->
user.id != userDAO.getCurrentUserId()
}
}
}
fun goToProfile(