Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Save messages for later #259

Merged
merged 63 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
00f6c1d
Use tum artemis server url as default for unrestricted build flavor
FelberMartin Dec 27, 2024
e09dfd0
Adapt ServerConfigurationService to use default implementations
FelberMartin Dec 27, 2024
785b68f
Adapt code to no longer rely on InstanceSelection
FelberMartin Dec 27, 2024
96c95c7
Implemented new service
FelberMartin Dec 28, 2024
fbef9c2
Displaying saved message categories
FelberMartin Dec 28, 2024
d9b3436
Enabled navigation to saved posts
FelberMartin Dec 28, 2024
beef456
Extended service to call post status apis
FelberMartin Dec 28, 2024
69d3f3a
Pass onSavePost down in UI to ViewModel
FelberMartin Dec 30, 2024
19df8fd
Update data objects to include isSaved
FelberMartin Dec 30, 2024
097ce4d
Minor fixes
FelberMartin Dec 30, 2024
1edb2a7
Adapted tests; added PostActionBarUITest for savePost
FelberMartin Dec 30, 2024
7343037
Added UI tests
FelberMartin Dec 30, 2024
1d89bd6
Fixed test
FelberMartin Dec 30, 2024
67f8965
Moving SavedPostService to conversation sub module
FelberMartin Dec 30, 2024
a4fc896
WIP Add tests; noticed deserialization issue
FelberMartin Dec 30, 2024
f8f748f
Created new dataClass SavedPost to deal with different serialization …
FelberMartin Dec 31, 2024
dd62735
Fixing tests; WIP 3rd test still failing
FelberMartin Dec 31, 2024
ab28f66
Fix changeSavePostStatus call
FelberMartin Jan 2, 2025
e975715
Created drafts for screens and SavedPostItem
FelberMartin Jan 2, 2025
1e06dab
Navigation to SavedPostsScreen
FelberMartin Jan 2, 2025
bdbd509
Added bottomSheet to change SavedPostStatus
FelberMartin Jan 2, 2025
bd885cb
Fix reload stuttering
FelberMartin Jan 2, 2025
399a082
Show failure dialog
FelberMartin Jan 2, 2025
911529b
Add button in IN_PROGRESS
FelberMartin Jan 2, 2025
83197f0
Fix key to work with standalone and answer posts
FelberMartin Jan 2, 2025
4bd47c0
Added animations
FelberMartin Jan 2, 2025
4e43dd6
Update TS2
FelberMartin Jan 3, 2025
5841616
Navigate to thread after savedPost click
FelberMartin Jan 3, 2025
d4aa22c
Fix flickering when re-entering savedPosts
FelberMartin Jan 3, 2025
ffe9c06
Added tests for the SavedPostsScreenUi
FelberMartin Jan 4, 2025
43058f4
Merge branch 'develop' into feature/communication/save-messages-for-l…
FelberMartin Jan 4, 2025
7f8510f
Fix module tests
FelberMartin Jan 4, 2025
5673ca1
Fix test compilation
FelberMartin Jan 4, 2025
de80192
Merge remote-tracking branch 'origin/develop' into feature/communicat…
FelberMartin Jan 4, 2025
d2f4a78
Adapt to ConversationOverview redesign
FelberMartin Jan 4, 2025
6a1220e
Fix E2e test
FelberMartin Jan 4, 2025
ca5faf6
Merge branch 'develop' into feature/communication/save-messages-for-l…
FelberMartin Jan 10, 2025
cec0dfa
Fix merge issue
FelberMartin Jan 10, 2025
e79f6c0
Refactor PostItem to be re-used
FelberMartin Jan 10, 2025
0ea6617
Use PostMainContent in SavedPostItem
FelberMartin Jan 10, 2025
d3e8188
Introduce InfoMessageCard
FelberMartin Jan 10, 2025
3f401ae
Add isSaved indicators
FelberMartin Jan 10, 2025
04ea798
Fix bug with markdown rendering
FelberMartin Jan 10, 2025
6d9b866
Fix warnings
FelberMartin Jan 10, 2025
59762ce
Merge branch 'develop' into feature/communication/save-messages-for-l…
FelberMartin Jan 10, 2025
91fe82a
Use spacings
FelberMartin Jan 11, 2025
5194307
Fixed paddings
FelberMartin Jan 16, 2025
8630711
Merge branch 'develop' into feature/communication/save-messages-for-l…
FelberMartin Jan 16, 2025
720835f
Fix spamming save button bug
FelberMartin Jan 16, 2025
f4a4d9d
Fix display of non-distinct post items
FelberMartin Jan 17, 2025
94697dc
Increase db version
FelberMartin Jan 22, 2025
4935749
Fix crash when saving answer post
FelberMartin Jan 22, 2025
b09308e
Move completeButton into card
FelberMartin Jan 22, 2025
8f382a3
Merge remote-tracking branch 'origin/develop' into feature/communicat…
FelberMartin Jan 22, 2025
6dcfddb
Fix CompleteButton padding
FelberMartin Jan 22, 2025
535c7f0
Fix display of duplicated savedPosts created by bug
FelberMartin Jan 22, 2025
cd23dd1
Fix navigation
FelberMartin Jan 22, 2025
cc79f22
Fix test after merge
FelberMartin Jan 22, 2025
db59e84
Display images in savedPosts
FelberMartin Jan 22, 2025
269a99f
Merge branch 'develop' into feature/communication/save-messages-for-l…
FelberMartin Jan 23, 2025
9e1225b
Fix merge issues
FelberMartin Jan 23, 2025
d9b65dc
Fix spacings
FelberMartin Jan 23, 2025
99e7d5c
Ignore flaky test
FelberMartin Jan 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import de.tum.informatics.www1.artemis.native_app.feature.push.communication_not
CommunicationMessageEntity::class
],
exportSchema = true,
version = 12,
version = 13,
)
@TypeConverters(RoomTypeConverters::class)
abstract class AppDatabase : RoomDatabase() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package de.tum.informatics.www1.artemis.native_app.core.data.service

import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

// Copied from https://stackoverflow.com/a/75644603/13366254
open class EnumAsIntSerializer<T:Enum<*>>(
serialName: String,
val serialize: (v: T) -> Int,
val deserialize: (v: Int) -> T
) : KSerializer<T> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(serialName, PrimitiveKind.INT)

override fun serialize(encoder: Encoder, value: T) {
encoder.encodeInt(serialize(value))
}

override fun deserialize(decoder: Decoder): T {
val v = decoder.decodeInt()
return deserialize(v)
}
}

open class EnumOrdinalSerializer<T:Enum<*>>(
serialName: String,
val values: Array<T>
) : EnumAsIntSerializer<T>(
serialName,
{ it.ordinal },
{ values[it] }
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import androidx.compose.ui.unit.dp

object Spacings {
val ScreenHorizontalSpacing = 16.dp
val ScreenHorizontalInnerSpacing = 8.dp

val EndOfScrollablePageSpacing = ScreenHorizontalSpacing

object Post {
Expand All @@ -29,6 +27,12 @@ object Spacings {
fun calculateEndOfPagePaddingValues() = PaddingValues(
bottom = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() + EndOfScrollablePageSpacing
)

val BottomSheetContentPadding = PaddingValues(
bottom = 40.dp,
start = ScreenHorizontalSpacing,
end = ScreenHorizontalSpacing
)
}

fun Modifier.endOfPagePadding() = padding(bottom = Spacings.EndOfScrollablePageSpacing).navigationBarsPadding()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package de.tum.informatics.www1.artemis.native_app.core.ui.common

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp

@Composable
fun EmptyListHint(
modifier: Modifier,
hint: String,
icon: ImageVector,
) {
Column(
modifier = modifier.fillMaxWidth(0.8f),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Icon(
modifier = Modifier.size(64.dp),
imageVector = icon,
tint = MaterialTheme.colorScheme.onSurfaceVariant,
contentDescription = null
)

Spacer(modifier = Modifier.size(8.dp))

Text(
text = hint,
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package de.tum.informatics.www1.artemis.native_app.core.ui.common

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import de.tum.informatics.www1.artemis.native_app.core.ui.material.colors.InfoMessageCardColors

@Composable
fun InfoMessageCard(
modifier: Modifier = Modifier,
infoText: String,
) {
Box(
modifier = modifier
.border(
width = 1.dp,
color = InfoMessageCardColors.border,
shape = MaterialTheme.shapes.extraSmall
)
.background(InfoMessageCardColors.background)
.padding(8.dp)
.fillMaxWidth()
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
imageVector = Icons.Outlined.Info,
contentDescription = null,
modifier = Modifier.padding(end = 8.dp),
tint = InfoMessageCardColors.text
)
Text(
text = infoText,
fontSize = 16.sp,
color = InfoMessageCardColors.text
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
package de.tum.informatics.www1.artemis.native_app.core.ui.exercise

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.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.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import de.tum.informatics.www1.artemis.native_app.core.model.exercise.Exercise
import de.tum.informatics.www1.artemis.native_app.core.model.exercise.ProgrammingExercise
import de.tum.informatics.www1.artemis.native_app.core.model.exercise.QuizExercise
Expand All @@ -28,8 +18,8 @@ import de.tum.informatics.www1.artemis.native_app.core.model.exercise.isStartExe
import de.tum.informatics.www1.artemis.native_app.core.model.exercise.latestParticipation
import de.tum.informatics.www1.artemis.native_app.core.model.exercise.participation.Participation
import de.tum.informatics.www1.artemis.native_app.core.ui.R
import de.tum.informatics.www1.artemis.native_app.core.ui.common.InfoMessageCard
import de.tum.informatics.www1.artemis.native_app.core.ui.date.hasPassed
import de.tum.informatics.www1.artemis.native_app.core.ui.material.colors.ParticipationNotPossibleInfoMessageCardColors

/**
* This composable composes up to two buttons. The modifier parameter is applied to every button
Expand Down Expand Up @@ -139,7 +129,9 @@ fun ExerciseActionButtons(
//}
else -> {
Row(modifier=Modifier.padding(top=2.dp, bottom = 2.dp)) {
ParticipationNotPossibleInfoMessageCard()
InfoMessageCard(
infoText = stringResource(id = R.string.exercise_participation_not_possible),
)
}
}
}
Expand Down Expand Up @@ -214,33 +206,3 @@ class BoundExerciseActions(
onClickViewQuizResults = { onClickViewQuizResults(exerciseId) }
)
}


@Composable
fun ParticipationNotPossibleInfoMessageCard() {
Box(
modifier = Modifier
.border(
width = 1.dp,
color = ParticipationNotPossibleInfoMessageCardColors.border,
shape = MaterialTheme.shapes.extraSmall
)
.background(ParticipationNotPossibleInfoMessageCardColors.background)
.padding(8.dp)
.fillMaxWidth()
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
imageVector = Icons.Outlined.Info,
contentDescription = null,
modifier = Modifier.padding(end = 8.dp),
tint = ParticipationNotPossibleInfoMessageCardColors.text
)
Text(
text = stringResource(id = R.string.exercise_participation_not_possible),
fontSize = 16.sp,
color = ParticipationNotPossibleInfoMessageCardColors.text
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package de.tum.informatics.www1.artemis.native_app.core.ui.markdown

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import de.tum.informatics.www1.artemis.native_app.core.common.markdown.PostArtemisMarkdownTransformer

@Composable
fun rememberPostArtemisMarkdownTransformer(
serverUrl: String,
courseId: Long
): PostArtemisMarkdownTransformer {
return remember(serverUrl, courseId) {
val strippedServerUrl =
if (serverUrl.endsWith("/")) serverUrl.substring(
0,
serverUrl.length - 1
) else serverUrl

PostArtemisMarkdownTransformer(serverUrl = strippedServerUrl, courseId = courseId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color

object ParticipationNotPossibleInfoMessageCardColors {
object InfoMessageCardColors {
val background: Color
@Composable get() = if(isSystemInDarkTheme()) Color(0xFF062A30) else Color(0xFFD1ECF1)
val border: Color
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ object PostColors {
@Composable get() = Color(0xFF28A745).copy(alpha = 0.2f)
val pinned: Color
@Composable get() = Color(0xFFFFA500).copy(alpha = 0.25f)
val saved: Color
@Composable get() = Color(0xFF007BFF).copy(alpha = 0.2f)
}

object EmojiChipColors {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import de.tum.informatics.www1.artemis.native_app.android.appModule
import de.tum.informatics.www1.artemis.native_app.core.common.CurrentActivityListener
import de.tum.informatics.www1.artemis.native_app.core.common.test.UnitTest
import de.tum.informatics.www1.artemis.native_app.feature.metis.shared.content.StandalonePostId
import de.tum.informatics.www1.artemis.native_app.feature.metis.shared.content.dto.SavedPostStatus
import de.tum.informatics.www1.artemis.native_app.feature.quiz.QuizType
import org.junit.Test
import org.junit.experimental.categories.Category
Expand Down Expand Up @@ -39,6 +40,7 @@ class AppModuleTest {
WorkerParameters::class,
QuizType.WorkableQuizType::class,
QuizType.ViewableQuizType::class,
SavedPostStatus::class,
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ fun `Metis - Conversation Overview`() {
examsExpanded = true,
exercisesExpanded = true,
lecturesExpanded = true,
savedPostsExpanded = false
)
)

Expand Down Expand Up @@ -139,6 +140,7 @@ fun `Metis - Conversation Overview`() {
modifier = Modifier.fillMaxSize(),
viewModel = viewModel,
onNavigateToConversation = {},
onNavigateToSavedPosts = {},
onRequestCreatePersonalConversation = {},
onRequestAddChannel = {},
onRequestBrowseChannel = {},
Expand Down Expand Up @@ -252,6 +254,7 @@ fun `Metis - Conversation Channel`() {
onEditPost = { _, _ -> CompletableDeferred() },
onDeletePost = { CompletableDeferred() },
onPinPost = { CompletableDeferred() },
onSavePost = { CompletableDeferred() },
onRequestReactWithEmoji = { _, _, _ -> CompletableDeferred() },
bottomItem = null,
onClickViewPost = {},
Expand Down Expand Up @@ -289,6 +292,7 @@ private fun generateMessage(
creationDate = time,
updatedDate = null,
resolved = false,
isSaved = false,
courseWideContext = null,
tags = emptyList(),
answers = emptyList(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,19 +255,23 @@ internal fun CourseUiScreen(
val initialConfiguration = remember(conversationId, postId) {
when {
conversationId != DEFAULT_CONVERSATION_ID && postId != DEFAULT_POST_ID -> OpenedConversation(
conversationId,
OpenedThread(
conversationId,
_prevConfiguration = NothingOpened,
conversationId = conversationId,
openedThread = OpenedThread(
StandalonePostId.ServerSideId(postId)
)
)

conversationId != DEFAULT_CONVERSATION_ID -> OpenedConversation(
conversationId,
null
_prevConfiguration = NothingOpened,
conversationId = conversationId,
openedThread = null
)

username.isNotBlank() -> NavigateToUserConversation(username)
username.isNotBlank() -> NavigateToUserConversation(
_prevConfiguration = NothingOpened,
username = username
)

else -> NothingOpened
}
Expand Down
Loading
Loading