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: Send message via user dialog #285

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -109,13 +109,17 @@ class MainActivity : AppCompatActivity(),
val visibleMetisContextManager = object :
VisibleMetisContextManager {
override fun registerMetisContext(metisContext: VisibleMetisContext) {
visibleMetisContexts.value = visibleMetisContexts.value + metisContext
visibleMetisContexts.value += metisContext

cancelCommunicationNotifications(metisContext)
}

override fun unregisterMetisContext(metisContext: VisibleMetisContext) {
visibleMetisContexts.value = visibleMetisContexts.value - metisContext
visibleMetisContexts.value -= metisContext
}

override fun getRegisteredMetisContexts(): List<VisibleMetisContext> {
return visibleMetisContexts.value
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.tum.informatics.www1.artemis.native_app.core.data
package de.tum.informatics.www1.artemis.native_app.core.data.test

import de.tum.informatics.www1.artemis.native_app.core.data.NetworkResponse
import de.tum.informatics.www1.artemis.native_app.core.data.service.network.AccountDataService
import de.tum.informatics.www1.artemis.native_app.core.model.account.Account

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.UserIdentifier
import de.tum.informatics.www1.artemis.native_app.feature.quiz.QuizType
import org.junit.Test
import org.junit.experimental.categories.Category
Expand All @@ -32,6 +33,7 @@ class AppModuleTest {
SavedStateHandle::class,
Boolean::class,
Long::class,
UserIdentifier::class,
StandalonePostId::class,
Application::class,
CurrentActivityListener::class,
Expand Down
2 changes: 2 additions & 0 deletions feature/course-view/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ dependencies {
implementation(libs.kotlinx.datetime)
implementation(libs.placeholder.material)
implementation(project(":core:device-test"))
debugImplementation(project(":core:data-test"))

testImplementation(project(":feature:login"))
testImplementation(project(":feature:login-test"))
testImplementation(project(":feature:metis-test"))

kover(project(":core:data"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.CourseVi
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.course_overview.CourseUiScreen
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.course_overview.DEFAULT_CONVERSATION_ID
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.course_overview.DEFAULT_POST_ID
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.course_overview.DEFAULT_USERNAME
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.course_overview.DEFAULT_USER_ID
import org.koin.core.context.startKoin
import org.koin.dsl.module

Expand Down Expand Up @@ -54,8 +56,9 @@ fun `Course View - Exercise List`() {
CourseUiScreen(
modifier = Modifier.fillMaxSize(),
viewModel = courseViewModel,
username = "",
courseId = 0L,
username = DEFAULT_USERNAME,
userId = DEFAULT_USER_ID,
conversationId = DEFAULT_CONVERSATION_ID,
postId = DEFAULT_POST_ID,
onNavigateToExercise = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.TextFieldValue
import de.tum.informatics.www1.artemis.native_app.core.data.AccountDataServiceStub
import de.tum.informatics.www1.artemis.native_app.core.data.DataState
import de.tum.informatics.www1.artemis.native_app.core.data.test.AccountDataServiceStub
import de.tum.informatics.www1.artemis.native_app.core.datastore.AccountServiceStub
import de.tum.informatics.www1.artemis.native_app.core.datastore.ServerConfigurationServiceStub
import de.tum.informatics.www1.artemis.native_app.core.device.NetworkStatusProviderStub
Expand Down Expand Up @@ -190,11 +190,9 @@ fun `Metis - Conversation Channel`() {
).reversed()

val visibleMetisContextManagerStub = object : VisibleMetisContextManager {
override fun registerMetisContext(metisContext: VisibleMetisContext) =
Unit

override fun unregisterMetisContext(metisContext: VisibleMetisContext) =
Unit
override fun registerMetisContext(metisContext: VisibleMetisContext) = Unit
override fun unregisterMetisContext(metisContext: VisibleMetisContext) = Unit
override fun getRegisteredMetisContexts(): List<VisibleMetisContext> = emptyList()
}

// TODO: Provide artemis image provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,16 @@ import de.tum.informatics.www1.artemis.native_app.feature.courseview.R
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.CourseViewModel
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.LectureListUi
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.exercise_list.ExerciseListUi
import de.tum.informatics.www1.artemis.native_app.feature.metis.IgnoreCustomBackHandling
import de.tum.informatics.www1.artemis.native_app.feature.metis.NavigateToUserConversation
import de.tum.informatics.www1.artemis.native_app.feature.metis.NothingOpened
import de.tum.informatics.www1.artemis.native_app.feature.metis.OpenedConversation
import de.tum.informatics.www1.artemis.native_app.feature.metis.OpenedThread
import de.tum.informatics.www1.artemis.native_app.feature.metis.shared.content.MetisContext
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.UserIdentifier
import de.tum.informatics.www1.artemis.native_app.feature.metis.shared.visiblemetiscontextreporter.ReportVisibleMetisContext
import de.tum.informatics.www1.artemis.native_app.feature.metis.shared.visiblemetiscontextreporter.VisibleCourse
import de.tum.informatics.www1.artemis.native_app.feature.metis.ui.ConversationFacadeUi
import kotlinx.serialization.Serializable
import org.koin.androidx.compose.koinViewModel
Expand All @@ -61,13 +66,16 @@ internal const val TAB_COMMUNICATION = 2

internal const val DEFAULT_CONVERSATION_ID = -1L
internal const val DEFAULT_POST_ID = -1L
internal const val DEFAULT_USERNAME = ""
internal const val DEFAULT_USER_ID = -1L

@Serializable
private data class CourseUiScreen(
val courseId: Long,
val conversationId: Long = DEFAULT_CONVERSATION_ID,
val postId: Long = DEFAULT_POST_ID,
val username: String = ""
val username: String = DEFAULT_USERNAME,
val userId: Long = DEFAULT_USER_ID
)

fun NavController.navigateToCourse(courseId: Long, builder: NavOptionsBuilder.() -> Unit) {
Expand All @@ -91,7 +99,8 @@ fun NavGraphBuilder.course(
generateLinks("courses/{courseId}") +
generateLinks("courses/{courseId}/exercises") +
generateLinks("courses/{courseId}/messages?conversationId={conversationId}") +
generateLinks("courses/{courseId}/messages?username={username}")
generateLinks("courses/{courseId}/messages?username={username}") +
generateLinks("courses/{courseId}/messages?userId={userId}")
animatedComposable<CourseUiScreen>(
deepLinks = deepLinks
) { backStackEntry ->
Expand All @@ -101,6 +110,7 @@ fun NavGraphBuilder.course(
val conversationId = route.conversationId
val postId = route.postId
val username = route.username
val userId = route.userId

CourseUiScreen(
modifier = Modifier.fillMaxSize(),
Expand All @@ -109,6 +119,7 @@ fun NavGraphBuilder.course(
conversationId = conversationId,
postId = postId,
username = username,
userId = userId,
onNavigateToExercise = onNavigateToExercise,
onNavigateToTextExerciseParticipation = onNavigateToTextExerciseParticipation,
onNavigateToExerciseResultView = onNavigateToExerciseResultView,
Expand All @@ -134,6 +145,7 @@ fun CourseUiScreen(
conversationId: Long,
postId: Long,
username: String,
userId: Long,
onNavigateToExercise: (exerciseId: Long) -> Unit,
onNavigateToTextExerciseParticipation: (exerciseId: Long, participationId: Long) -> Unit,
onNavigateToExerciseResultView: (exerciseId: Long) -> Unit,
Expand All @@ -151,6 +163,7 @@ fun CourseUiScreen(
conversationId = conversationId,
courseDataState = courseDataState,
username = username,
userId = userId,
onNavigateBack = onNavigateBack,
weeklyExercisesDataState = weeklyExercisesDataState,
onNavigateToExercise = onNavigateToExercise,
Expand Down Expand Up @@ -181,6 +194,7 @@ internal fun CourseUiScreen(
conversationId: Long,
postId: Long,
username: String,
userId: Long,
courseDataState: DataState<Course>,
weeklyExercisesDataState: DataState<List<GroupedByWeek<Exercise>>>,
weeklyLecturesDataState: DataState<List<GroupedByWeek<Lecture>>>,
Expand All @@ -196,13 +210,17 @@ internal fun CourseUiScreen(
) {
var selectedTabIndex by rememberSaveable(conversationId) {
val initialTab = when {
conversationId != DEFAULT_CONVERSATION_ID || username.isNotBlank() -> TAB_COMMUNICATION
conversationId != DEFAULT_CONVERSATION_ID -> TAB_COMMUNICATION
username != DEFAULT_USERNAME -> TAB_COMMUNICATION
userId != DEFAULT_USER_ID -> TAB_COMMUNICATION
else -> TAB_EXERCISES
}

mutableIntStateOf(initialTab)
}

ReportVisibleMetisContext(VisibleCourse(MetisContext.Course(courseId)))

CourseUiScreen(
modifier = modifier,
courseDataState = courseDataState,
Expand Down Expand Up @@ -255,19 +273,28 @@ internal fun CourseUiScreen(
val initialConfiguration = remember(conversationId, postId) {
when {
conversationId != DEFAULT_CONVERSATION_ID && postId != DEFAULT_POST_ID -> OpenedConversation(
conversationId,
OpenedThread(
conversationId,
_prevConfiguration = IgnoreCustomBackHandling,
conversationId = conversationId,
openedThread = OpenedThread(
StandalonePostId.ServerSideId(postId)
)
)

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

username != DEFAULT_USERNAME -> NavigateToUserConversation(
_prevConfiguration = IgnoreCustomBackHandling,
userIdentifier = UserIdentifier.Username(username)
)

username.isNotBlank() -> NavigateToUserConversation(username)
userId != DEFAULT_USER_ID -> NavigateToUserConversation(
_prevConfiguration = IgnoreCustomBackHandling,
userIdentifier = UserIdentifier.UserId(userId)
)

else -> NothingOpened
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.tum.informatics.www1.artemis.native_app.feature.courseview

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.test.platform.app.InstrumentationRegistry
import de.tum.informatics.www1.artemis.native_app.core.model.Course
Expand All @@ -12,10 +13,14 @@ import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.CourseVi
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.course_overview.CourseUiScreen
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.course_overview.DEFAULT_CONVERSATION_ID
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.course_overview.DEFAULT_POST_ID
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.course_overview.DEFAULT_USERNAME
import de.tum.informatics.www1.artemis.native_app.feature.courseview.ui.course_overview.DEFAULT_USER_ID
import de.tum.informatics.www1.artemis.native_app.feature.login.loginModule
import de.tum.informatics.www1.artemis.native_app.feature.login.test.getAdminAccessToken
import de.tum.informatics.www1.artemis.native_app.feature.login.test.performTestLogin
import de.tum.informatics.www1.artemis.native_app.feature.login.test.testLoginModule
import de.tum.informatics.www1.artemis.native_app.feature.metis.shared.visiblemetiscontextreporter.LocalVisibleMetisContextManager
import de.tum.informatics.www1.artemis.native_app.feature.metistest.VisibleMetisContextManagerMock
import org.junit.Before
import org.junit.Rule
import org.koin.android.ext.koin.androidContext
Expand Down Expand Up @@ -55,21 +60,26 @@ abstract class BaseCourseTest : BaseComposeTest() {
)

composeTestRule.setContent {
CourseUiScreen(
modifier = Modifier.fillMaxSize(),
viewModel = viewModel,
courseId = course.id!!,
conversationId = DEFAULT_CONVERSATION_ID,
postId = DEFAULT_POST_ID,
username = "",
onNavigateToExercise = {},
onNavigateToExerciseResultView = {},
onNavigateToTextExerciseParticipation = { _, _ -> },
onParticipateInQuiz = { _, _ -> },
onClickViewQuizResults = { _, _ -> },
onNavigateToLecture = {},
onNavigateBack = {}
)
CompositionLocalProvider(
LocalVisibleMetisContextManager provides VisibleMetisContextManagerMock
) {
CourseUiScreen(
modifier = Modifier.fillMaxSize(),
viewModel = viewModel,
courseId = course.id!!,
conversationId = DEFAULT_CONVERSATION_ID,
postId = DEFAULT_POST_ID,
username = DEFAULT_USERNAME,
userId = DEFAULT_USER_ID,
onNavigateToExercise = {},
onNavigateToExerciseResultView = {},
onNavigateToTextExerciseParticipation = { _, _ -> },
onParticipateInQuiz = { _, _ -> },
onClickViewQuizResults = { _, _ -> },
onNavigateToLecture = {},
onNavigateBack = {}
)
}
}

return viewModel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
package de.tum.informatics.www1.artemis.native_app.feature.metis.conversation
package de.tum.informatics.www1.artemis.native_app.feature.metistest

import de.tum.informatics.www1.artemis.native_app.feature.metis.shared.visiblemetiscontextreporter.VisibleMetisContext
import de.tum.informatics.www1.artemis.native_app.feature.metis.shared.visiblemetiscontextreporter.VisibleMetisContextManager

object EmptyVisibleMetisContextManager : VisibleMetisContextManager {
override fun registerMetisContext(metisContext: VisibleMetisContext) = Unit
object VisibleMetisContextManagerMock : VisibleMetisContextManager {
private val registeredMetisContexts = mutableListOf<VisibleMetisContext>()

override fun unregisterMetisContext(metisContext: VisibleMetisContext) = Unit
override fun registerMetisContext(metisContext: VisibleMetisContext) {
registeredMetisContexts.add(metisContext)
}

override fun unregisterMetisContext(metisContext: VisibleMetisContext) {
registeredMetisContexts.remove(metisContext)
}

override fun getRegisteredMetisContexts(): List<VisibleMetisContext> = registeredMetisContexts
}
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,6 @@ fun MetisChatList(
title: String,
onFileSelected: (Uri) -> Unit
) {
val context = LocalContext.current

// TODO: https://github.com/ls1intum/artemis-android/issues/213
// val navigateToChat = { userId: Long ->
// val chatLink = "artemis://courses/$courseId/messages?userId=$userId"
// val intent = Intent(Intent.ACTION_VIEW, Uri.parse(chatLink))
// context.startActivity(intent)
// }

MetisReplyHandler(
initialReplyTextProvider = initialReplyTextProvider,
onCreatePost = onCreatePost,
Expand Down
Loading
Loading