diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 175cf43509..75fc1408f2 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -10,6 +10,8 @@ permissions: {} jobs: pr-checks: + # Upstream-only: this fork does not use the PR- label convention. + if: github.repository == 'element-hq/element-x-android' name: PR Checks runs-on: ubuntu-latest timeout-minutes: 5 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d2628ffb9e..1cbdc9aa57 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -152,7 +152,7 @@ jobs: if: env.CODECOV_TOKEN != '' env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 + uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 with: fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} diff --git a/HEALTHCHAT_CHANGES.md b/HEALTHCHAT_CHANGES.md index 0b91bdb0f2..0c81078431 100644 --- a/HEALTHCHAT_CHANGES.md +++ b/HEALTHCHAT_CHANGES.md @@ -6,6 +6,18 @@ top section matching the released version — the heading must have the exact form `## Changes in ()` and the whole section must stay under 500 characters. See `.claude/skills/releasing-healthchat/SKILL.md`. +## Changes in 26.10.0 (2026-10-19) + +🎉 Neue Funktionen + +- Nachrichtensuche: Chats durchsuchen, auch in verschlüsselten Räumen. +- Umfragen mit Mehrfachauswahl. + +🙌 Verbesserungen + +- Basis aktualisiert auf Element X 26.10.0 mit zahlreichen Fehlerbehebungen. +- Einstellungen neu gegliedert in Konto- und App-Einstellungen. + ## Changes in 26.08.0 (2026-08-06) 🎉 Neue Funktionen diff --git a/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryEvents.kt b/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryEvent.kt similarity index 76% rename from features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryEvents.kt rename to features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryEvent.kt index 0025442928..cb879fc7cf 100644 --- a/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryEvents.kt +++ b/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryEvent.kt @@ -10,17 +10,17 @@ package io.element.android.features.healthchat.api.directory import io.element.android.libraries.matrix.api.user.MatrixUser -sealed interface MemberDirectoryEvents { +sealed interface MemberDirectoryEvent { /** * Fired by the view on first composition. The tab presenter runs from app start (it is * composed by the Home presenter), so the first fetch is deferred until the tab is shown. */ - data object LoadIfNeeded : MemberDirectoryEvents + data object LoadIfNeeded : MemberDirectoryEvent /** Header refresh and "try again" — one load path. */ - data object Refresh : MemberDirectoryEvents + data object Refresh : MemberDirectoryEvent - data class StartDm(val matrixUser: MatrixUser) : MemberDirectoryEvents + data class StartDm(val matrixUser: MatrixUser) : MemberDirectoryEvent - data object ClearStartDmState : MemberDirectoryEvents + data object ClearStartDmState : MemberDirectoryEvent } diff --git a/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryState.kt b/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryState.kt index 0cfa553669..c0930eb4e4 100644 --- a/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryState.kt +++ b/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryState.kt @@ -18,7 +18,7 @@ data class MemberDirectoryState( val searchQuery: TextFieldState, val directory: AsyncData, val startDmActionState: AsyncAction, - val eventSink: (MemberDirectoryEvents) -> Unit, + val eventSink: (MemberDirectoryEvent) -> Unit, ) { /** Unknown-while-loading counts as approved so no banner flashes during the first load. */ val isApproved: Boolean diff --git a/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryStateFixtures.kt b/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryStateFixtures.kt index c826f0a8f5..c3abec6020 100644 --- a/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryStateFixtures.kt +++ b/features/healthchat/api/src/main/kotlin/io/element/android/features/healthchat/api/directory/MemberDirectoryStateFixtures.kt @@ -25,7 +25,7 @@ fun aMemberDirectoryState( searchQuery: TextFieldState = TextFieldState(), directory: AsyncData = AsyncData.Success(aMemberDirectory()), startDmActionState: AsyncAction = AsyncAction.Uninitialized, - eventSink: (MemberDirectoryEvents) -> Unit = {}, + eventSink: (MemberDirectoryEvent) -> Unit = {}, ) = MemberDirectoryState( searchQuery = searchQuery, directory = directory, diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryPresenter.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryPresenter.kt index 031aea6c21..84dc32c035 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryPresenter.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryPresenter.kt @@ -21,7 +21,7 @@ import androidx.compose.runtime.setValue import dev.zacsweers.metro.Inject import io.element.android.features.healthchat.api.HealthChatDirectoryService import io.element.android.features.healthchat.api.HealthChatMemberDirectory -import io.element.android.features.healthchat.api.directory.MemberDirectoryEvents +import io.element.android.features.healthchat.api.directory.MemberDirectoryEvent import io.element.android.features.healthchat.api.directory.MemberDirectoryState import io.element.android.features.startchat.api.StartDMAction import io.element.android.libraries.architecture.AsyncAction @@ -62,22 +62,22 @@ class MemberDirectoryPresenter( ) } - fun handleEvents(event: MemberDirectoryEvents) { + fun handleEvents(event: MemberDirectoryEvent) { when (event) { - MemberDirectoryEvents.LoadIfNeeded -> { + MemberDirectoryEvent.LoadIfNeeded -> { hasBeenRequested = true } - MemberDirectoryEvents.Refresh -> { + MemberDirectoryEvent.Refresh -> { loadTrigger++ } - is MemberDirectoryEvents.StartDm -> coroutineScope.launch { + is MemberDirectoryEvent.StartDm -> coroutineScope.launch { startDMAction.execute( matrixUser = event.matrixUser, createIfDmDoesNotExist = startDmActionState.value is AsyncAction.Confirming, actionState = startDmActionState, ) } - MemberDirectoryEvents.ClearStartDmState -> { + MemberDirectoryEvent.ClearStartDmState -> { startDmActionState.value = AsyncAction.Uninitialized } } diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryStateProvider.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryStatePreviewParam.kt similarity index 94% rename from features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryStateProvider.kt rename to features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryStatePreviewParam.kt index f59e175d2d..309f2e86fe 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryStateProvider.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryStatePreviewParam.kt @@ -15,7 +15,7 @@ import io.element.android.features.healthchat.api.directory.aMemberDirectory import io.element.android.features.healthchat.api.directory.aMemberDirectoryState import io.element.android.libraries.architecture.AsyncData -open class MemberDirectoryStateProvider : PreviewParameterProvider { +open class MemberDirectoryStatePreviewParam : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aMemberDirectoryState(), diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryView.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryView.kt index 4af5dc9b99..b9f47083b2 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryView.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryView.kt @@ -27,7 +27,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.features.healthchat.api.HealthChatStrings -import io.element.android.features.healthchat.api.directory.MemberDirectoryEvents +import io.element.android.features.healthchat.api.directory.MemberDirectoryEvent import io.element.android.features.healthchat.api.directory.MemberDirectoryState import io.element.android.features.healthchat.api.toMatrixUser import io.element.android.features.healthchat.impl.directory.components.MemberCard @@ -63,7 +63,7 @@ fun MemberDirectoryView( modifier: Modifier = Modifier, ) { LaunchedEffect(Unit) { - state.eventSink(MemberDirectoryEvents.LoadIfNeeded) + state.eventSink(MemberDirectoryEvent.LoadIfNeeded) } Box(modifier = modifier.fillMaxSize()) { when (val directory = state.directory) { @@ -84,7 +84,7 @@ fun MemberDirectoryView( } is AsyncData.Failure -> MemberDirectoryErrorContent( message = directory.error.healthChatUserMessage(), - onRetry = { state.eventSink(MemberDirectoryEvents.Refresh) }, + onRetry = { state.eventSink(MemberDirectoryEvent.Refresh) }, ) is AsyncData.Success -> MemberDirectoryContent( state = state, @@ -107,17 +107,17 @@ fun MemberDirectoryView( onSuccess = onOpenDm, errorMessage = { stringResource(HealthChatStrings.healthchat_screen_member_directory_error_starting_chat) }, onRetry = null, - onErrorDismiss = { state.eventSink(MemberDirectoryEvents.ClearStartDmState) }, + onErrorDismiss = { state.eventSink(MemberDirectoryEvent.ClearStartDmState) }, confirmationDialog = { data -> if (data is ConfirmingStartDmWithMatrixUser) { CreateDmConfirmationBottomSheet( matrixUser = data.matrixUser, isUserIdentityUnknown = data.isUserIdentityUnknown, onSendInvite = { - state.eventSink(MemberDirectoryEvents.StartDm(data.matrixUser)) + state.eventSink(MemberDirectoryEvent.StartDm(data.matrixUser)) }, onDismiss = { - state.eventSink(MemberDirectoryEvents.ClearStartDmState) + state.eventSink(MemberDirectoryEvent.ClearStartDmState) }, ) } @@ -154,7 +154,7 @@ private fun MemberDirectoryContent( onMyProfileClick = onMyProfileClick, onEditProfileClick = onEditProfileClick, onInviteClick = if (state.isApproved) onInviteClick else null, - onRefreshClick = { state.eventSink(MemberDirectoryEvents.Refresh) }, + onRefreshClick = { state.eventSink(MemberDirectoryEvent.Refresh) }, ) } if (!state.isApproved) { @@ -196,7 +196,7 @@ private fun MemberDirectoryContent( MemberCard( member = member, onClick = onMemberClick?.let { callback -> { callback(member.userId) } }, - onStartChatClick = { state.eventSink(MemberDirectoryEvents.StartDm(member.toMatrixUser())) }, + onStartChatClick = { state.eventSink(MemberDirectoryEvent.StartDm(member.toMatrixUser())) }, modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp), ) } @@ -219,7 +219,7 @@ private fun FullScreenLoading( @PreviewsDayNight @Composable internal fun MemberDirectoryViewPreview( - @PreviewParameter(MemberDirectoryStateProvider::class) state: MemberDirectoryState + @PreviewParameter(MemberDirectoryStatePreviewParam::class) state: MemberDirectoryState ) = ElementPreview { MemberDirectoryView( state = state, diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/invite/HealthChatInviteStateProvider.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/invite/HealthChatInviteStatePreviewParam.kt similarity index 95% rename from features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/invite/HealthChatInviteStateProvider.kt rename to features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/invite/HealthChatInviteStatePreviewParam.kt index 530054892f..6bcd51509f 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/invite/HealthChatInviteStateProvider.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/invite/HealthChatInviteStatePreviewParam.kt @@ -12,7 +12,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.healthchat.api.HealthChatStrings import io.element.android.libraries.architecture.AsyncAction -open class HealthChatInviteStateProvider : PreviewParameterProvider { +open class HealthChatInviteStatePreviewParam : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aHealthChatInviteState(), diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/invite/HealthChatInviteView.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/invite/HealthChatInviteView.kt index b07893e13d..c1326dfbd9 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/invite/HealthChatInviteView.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/invite/HealthChatInviteView.kt @@ -136,7 +136,7 @@ private fun HealthChatFieldError.text(): String { @PreviewsDayNight @Composable internal fun HealthChatInviteViewPreview( - @PreviewParameter(HealthChatInviteStateProvider::class) state: HealthChatInviteState + @PreviewParameter(HealthChatInviteStatePreviewParam::class) state: HealthChatInviteState ) = ElementPreview { HealthChatInviteView( state = state, diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/edit/EditHealthChatProfileStateProvider.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/edit/EditHealthChatProfileStatePreviewParam.kt similarity index 97% rename from features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/edit/EditHealthChatProfileStateProvider.kt rename to features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/edit/EditHealthChatProfileStatePreviewParam.kt index ebbeac1992..56a3256ee7 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/edit/EditHealthChatProfileStateProvider.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/edit/EditHealthChatProfileStatePreviewParam.kt @@ -24,7 +24,7 @@ import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.toImmutableMap -open class EditHealthChatProfileStateProvider : PreviewParameterProvider { +open class EditHealthChatProfileStatePreviewParam : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( anEditHealthChatProfileState(), diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/edit/EditHealthChatProfileView.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/edit/EditHealthChatProfileView.kt index df851bdd04..ab9e283492 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/edit/EditHealthChatProfileView.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/edit/EditHealthChatProfileView.kt @@ -284,7 +284,7 @@ private fun ProfileFormField( @PreviewsDayNight @Composable internal fun EditHealthChatProfileViewPreview( - @PreviewParameter(EditHealthChatProfileStateProvider::class) state: EditHealthChatProfileState + @PreviewParameter(EditHealthChatProfileStatePreviewParam::class) state: EditHealthChatProfileState ) = ElementPreview { EditHealthChatProfileView( state = state, diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionEvents.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionEvent.kt similarity index 74% rename from features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionEvents.kt rename to features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionEvent.kt index 62cad15402..7cd5a922ec 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionEvents.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionEvent.kt @@ -8,6 +8,6 @@ package io.element.android.features.healthchat.impl.profile.section -sealed interface HealthChatProfileSectionEvents { - data object Retry : HealthChatProfileSectionEvents +sealed interface HealthChatProfileSectionEvent { + data object Retry : HealthChatProfileSectionEvent } diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionPresenter.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionPresenter.kt index dc6413dedd..a8155e7d5e 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionPresenter.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionPresenter.kt @@ -63,9 +63,9 @@ class HealthChatProfileSectionPresenter( memberProfile } - fun handleEvents(event: HealthChatProfileSectionEvents) { + fun handleEvents(event: HealthChatProfileSectionEvent) { when (event) { - HealthChatProfileSectionEvents.Retry -> retryTrigger++ + HealthChatProfileSectionEvent.Retry -> retryTrigger++ } } diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionState.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionState.kt index 1459a0100c..abf49932c5 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionState.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionState.kt @@ -13,5 +13,5 @@ import io.element.android.libraries.architecture.AsyncData data class HealthChatProfileSectionState( val profile: AsyncData, - val eventSink: (HealthChatProfileSectionEvents) -> Unit, + val eventSink: (HealthChatProfileSectionEvent) -> Unit, ) diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionStateProvider.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionStatePreviewParam.kt similarity index 94% rename from features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionStateProvider.kt rename to features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionStatePreviewParam.kt index ebfa4e92af..1aba9184a4 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionStateProvider.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionStatePreviewParam.kt @@ -14,7 +14,7 @@ import io.element.android.features.healthchat.api.HealthChatMember import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.core.UserId -open class HealthChatProfileSectionStateProvider : PreviewParameterProvider { +open class HealthChatProfileSectionStatePreviewParam : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aHealthChatProfileSectionState(profile = AsyncData.Success(aProfileSectionMember())), @@ -45,7 +45,7 @@ open class HealthChatProfileSectionStateProvider : PreviewParameterProvider = AsyncData.Uninitialized, - eventSink: (HealthChatProfileSectionEvents) -> Unit = {}, + eventSink: (HealthChatProfileSectionEvent) -> Unit = {}, ) = HealthChatProfileSectionState( profile = profile, eventSink = eventSink, diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionView.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionView.kt index 2b85e502c9..4e21163b3c 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionView.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionView.kt @@ -56,7 +56,7 @@ fun HealthChatProfileSectionView( is HealthChatApiException.NotFound -> Unit is HealthChatApiException.NotApproved -> NotApprovedHint(modifier = modifier) else -> LoadingErrorRow( - onRetry = { state.eventSink(HealthChatProfileSectionEvents.Retry) }, + onRetry = { state.eventSink(HealthChatProfileSectionEvent.Retry) }, modifier = modifier, ) } @@ -147,7 +147,7 @@ private fun ProfileFieldRow( onClick: (() -> Unit)? = null, ) { ListItem( - headlineContent = { Text(value) }, + content = { Text(value) }, supportingContent = { Text(stringResource(labelRes)) }, leadingContent = ListItemContent.Icon(IconSource.Vector(icon)), onClick = onClick, @@ -175,7 +175,7 @@ private fun LoadingErrorRow( modifier: Modifier = Modifier, ) { ListItem( - headlineContent = { Text(stringResource(HealthChatStrings.healthchat_profile_error_loading)) }, + content = { Text(stringResource(HealthChatStrings.healthchat_profile_error_loading)) }, leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Error())), trailingContent = ListItemContent.Custom { TextButton( @@ -206,7 +206,7 @@ private fun String.withHttpScheme(): String { @PreviewsDayNight @Composable internal fun HealthChatProfileSectionViewPreview( - @PreviewParameter(HealthChatProfileSectionStateProvider::class) state: HealthChatProfileSectionState + @PreviewParameter(HealthChatProfileSectionStatePreviewParam::class) state: HealthChatProfileSectionState ) = ElementPreview { HealthChatProfileSectionView(state = state) } diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/status/HealthChatAccountStatusStateProvider.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/status/HealthChatAccountStatusStatePreviewParam.kt similarity index 89% rename from features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/status/HealthChatAccountStatusStateProvider.kt rename to features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/status/HealthChatAccountStatusStatePreviewParam.kt index c98f5bd767..8599cefc7a 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/status/HealthChatAccountStatusStateProvider.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/status/HealthChatAccountStatusStatePreviewParam.kt @@ -11,7 +11,7 @@ package io.element.android.features.healthchat.impl.status import androidx.compose.ui.tooling.preview.PreviewParameterProvider import kotlinx.collections.immutable.persistentListOf -open class HealthChatAccountStatusStateProvider : PreviewParameterProvider { +open class HealthChatAccountStatusStatePreviewParam : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( HealthChatAccountStatusState(status = HealthChatAccountStatus.PendingApproval(serverMessage = null)), diff --git a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/status/HealthChatAccountStatusView.kt b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/status/HealthChatAccountStatusView.kt index 7723f645af..859b18a0e6 100644 --- a/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/status/HealthChatAccountStatusView.kt +++ b/features/healthchat/impl/src/main/kotlin/io/element/android/features/healthchat/impl/status/HealthChatAccountStatusView.kt @@ -74,7 +74,7 @@ fun HealthChatAccountStatusView( @PreviewsDayNight @Composable internal fun HealthChatAccountStatusViewPreview( - @PreviewParameter(HealthChatAccountStatusStateProvider::class) state: HealthChatAccountStatusState + @PreviewParameter(HealthChatAccountStatusStatePreviewParam::class) state: HealthChatAccountStatusState ) = ElementPreview { HealthChatAccountStatusView( state = state, diff --git a/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryPresenterTest.kt b/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryPresenterTest.kt index aae6fa932c..ecc25cd56f 100644 --- a/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryPresenterTest.kt +++ b/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryPresenterTest.kt @@ -15,11 +15,11 @@ import io.element.android.features.healthchat.api.HealthChatApiException import io.element.android.features.healthchat.api.HealthChatDirectoryService import io.element.android.features.healthchat.api.HealthChatMember import io.element.android.features.healthchat.api.HealthChatMemberDirectory -import io.element.android.features.healthchat.api.directory.MemberDirectoryEvents +import io.element.android.features.healthchat.api.directory.MemberDirectoryEvent import io.element.android.features.healthchat.test.FakeHealthChatDirectoryService import io.element.android.features.healthchat.test.aHealthChatMember -import io.element.android.features.invitepeople.test.FakeStartDMAction import io.element.android.features.startchat.api.StartDMAction +import io.element.android.features.startchat.test.FakeStartDMAction import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.core.RoomId @@ -52,7 +52,7 @@ class MemberDirectoryPresenterTest { val initialState = awaitItem() assertThat(initialState.directory).isEqualTo(AsyncData.Uninitialized) searchLambda.assertions().isNeverCalled() - initialState.eventSink(MemberDirectoryEvents.LoadIfNeeded) + initialState.eventSink(MemberDirectoryEvent.LoadIfNeeded) val loadedState = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last() assertThat(loadedState.directory.dataOrNull()).isEqualTo(aDirectory()) searchLambda.assertions().isCalledOnce() @@ -72,7 +72,7 @@ class MemberDirectoryPresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(MemberDirectoryEvents.LoadIfNeeded) + initialState.eventSink(MemberDirectoryEvent.LoadIfNeeded) val loadedState = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last() // Typing restarts the effect: intermediate values must be debounced away. loadedState.searchQuery.setTextAndPlaceCursorAtEnd("M") @@ -100,11 +100,11 @@ class MemberDirectoryPresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(MemberDirectoryEvents.LoadIfNeeded) + initialState.eventSink(MemberDirectoryEvent.LoadIfNeeded) val failedState = consumeItemsUntilPredicate { it.directory is AsyncData.Failure }.last() // No stale fallback. assertThat((failedState.directory as AsyncData.Failure).prevData).isNull() - failedState.eventSink(MemberDirectoryEvents.Refresh) + failedState.eventSink(MemberDirectoryEvent.Refresh) val loadedState = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last() assertThat(loadedState.directory.dataOrNull()).isEqualTo(aDirectory()) } @@ -127,7 +127,7 @@ class MemberDirectoryPresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(MemberDirectoryEvents.LoadIfNeeded) + initialState.eventSink(MemberDirectoryEvent.LoadIfNeeded) val state = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last() assertThat(state.isApproved).isFalse() assertThat(state.pendingMessage).isEqualTo("Ihr Konto wird derzeit geprüft.") @@ -149,11 +149,11 @@ class MemberDirectoryPresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(MemberDirectoryEvents.StartDm(MatrixUser(A_USER_ID))) + initialState.eventSink(MemberDirectoryEvent.StartDm(MatrixUser(A_USER_ID))) val state = consumeItemsUntilPredicate { it.startDmActionState is AsyncAction.Success }.last() assertThat((state.startDmActionState as AsyncAction.Success).data).isEqualTo(A_ROOM_ID) executeLambda.assertions().isCalledOnce() - state.eventSink(MemberDirectoryEvents.ClearStartDmState) + state.eventSink(MemberDirectoryEvent.ClearStartDmState) val clearedState = consumeItemsUntilPredicate { it.startDmActionState is AsyncAction.Uninitialized }.last() assertThat(clearedState.startDmActionState).isEqualTo(AsyncAction.Uninitialized) } diff --git a/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryViewTest.kt b/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryViewTest.kt index 89d88c57d3..3af04e850f 100644 --- a/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryViewTest.kt +++ b/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/directory/MemberDirectoryViewTest.kt @@ -18,7 +18,7 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.v2.runAndroidComposeUiTest import io.element.android.features.healthchat.api.HealthChatApiException -import io.element.android.features.healthchat.api.directory.MemberDirectoryEvents +import io.element.android.features.healthchat.api.directory.MemberDirectoryEvent import io.element.android.features.healthchat.api.directory.MemberDirectoryState import io.element.android.features.healthchat.api.directory.aDirectoryMember import io.element.android.features.healthchat.api.directory.aMemberDirectory @@ -37,19 +37,19 @@ import org.junit.Test class MemberDirectoryViewTest : RobolectricTest() { @Test fun `on composition LoadIfNeeded is emitted`() = runAndroidComposeUiTest { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() setMemberDirectoryView( state = aMemberDirectoryState( directory = AsyncData.Uninitialized, eventSink = eventsRecorder, ), ) - eventsRecorder.assertSingle(MemberDirectoryEvents.LoadIfNeeded) + eventsRecorder.assertSingle(MemberDirectoryEvent.LoadIfNeeded) } @Test fun `clicking retry on the error state emits Refresh`() = runAndroidComposeUiTest { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() setMemberDirectoryView( state = aMemberDirectoryState( directory = AsyncData.Failure(HealthChatApiException.Http(500, "Fehler beim Laden der Benutzer")), @@ -61,8 +61,8 @@ class MemberDirectoryViewTest : RobolectricTest() { clickOn(CommonStrings.action_retry) eventsRecorder.assertList( listOf( - MemberDirectoryEvents.LoadIfNeeded, - MemberDirectoryEvents.Refresh, + MemberDirectoryEvent.LoadIfNeeded, + MemberDirectoryEvent.Refresh, ) ) } @@ -70,7 +70,7 @@ class MemberDirectoryViewTest : RobolectricTest() { @Test fun `clicking start chat emits StartDm with the member as MatrixUser`() = runAndroidComposeUiTest { val member = aDirectoryMember() - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() setMemberDirectoryView( state = aMemberDirectoryState( directory = AsyncData.Success(aMemberDirectory(members = listOf(member))), @@ -82,8 +82,8 @@ class MemberDirectoryViewTest : RobolectricTest() { .performClick() eventsRecorder.assertList( listOf( - MemberDirectoryEvents.LoadIfNeeded, - MemberDirectoryEvents.StartDm(member.toMatrixUser()), + MemberDirectoryEvent.LoadIfNeeded, + MemberDirectoryEvent.StartDm(member.toMatrixUser()), ) ) } @@ -91,7 +91,7 @@ class MemberDirectoryViewTest : RobolectricTest() { @Test fun `clicking a member card opens the profile`() = runAndroidComposeUiTest { val member = aDirectoryMember() - val eventsRecorder = EventsRecorder(expectEvents = true) + val eventsRecorder = EventsRecorder(expectEvents = true) ensureCalledOnceWithParam(member.userId) { callback -> setMemberDirectoryView( state = aMemberDirectoryState( @@ -106,7 +106,7 @@ class MemberDirectoryViewTest : RobolectricTest() { @Test fun `an unapproved account shows the pending banner and no search field`() = runAndroidComposeUiTest { - val eventsRecorder = EventsRecorder(expectEvents = true) + val eventsRecorder = EventsRecorder(expectEvents = true) setMemberDirectoryView( state = aMemberDirectoryState( directory = AsyncData.Success( @@ -127,7 +127,7 @@ class MemberDirectoryViewTest : RobolectricTest() { @Test fun `hidden affordances are not rendered when their callbacks are null`() = runAndroidComposeUiTest { - val eventsRecorder = EventsRecorder(expectEvents = true) + val eventsRecorder = EventsRecorder(expectEvents = true) setMemberDirectoryView( state = aMemberDirectoryState(eventSink = eventsRecorder), onMyProfileClick = null, diff --git a/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionPresenterTest.kt b/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionPresenterTest.kt index 18106eae29..5a30eda1a9 100644 --- a/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionPresenterTest.kt +++ b/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionPresenterTest.kt @@ -106,7 +106,7 @@ class HealthChatProfileSectionPresenterTest { val presenter = createPresenter(isCurrentUser = false, directoryService = directoryService) presenter.test { val failedState = consumeItemsUntilPredicate { it.profile is AsyncData.Failure }.last() - failedState.eventSink(HealthChatProfileSectionEvents.Retry) + failedState.eventSink(HealthChatProfileSectionEvent.Retry) val state = consumeItemsUntilPredicate { it.profile is AsyncData.Success }.last() assertThat(state.profile).isEqualTo(AsyncData.Success(member)) assertThat(callCount).isEqualTo(2) diff --git a/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionViewTest.kt b/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionViewTest.kt index 68aece4b41..0cfe167de0 100644 --- a/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionViewTest.kt +++ b/features/healthchat/impl/src/test/kotlin/io/element/android/features/healthchat/impl/profile/section/HealthChatProfileSectionViewTest.kt @@ -30,7 +30,7 @@ import org.robolectric.Shadows.shadowOf class HealthChatProfileSectionViewTest : RobolectricTest() { @Test fun `a loaded profile renders its fields with values`() = runAndroidComposeUiTest { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) setContent { HealthChatProfileSectionView( state = aHealthChatProfileSectionState( @@ -50,7 +50,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() { @Test fun `empty fields are omitted`() = runAndroidComposeUiTest { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) setContent { HealthChatProfileSectionView( state = aHealthChatProfileSectionState( @@ -77,7 +77,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() { @Test fun `clicking the email row opens a mailto intent`() = runAndroidComposeUiTest { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) setContent { HealthChatProfileSectionView( state = aHealthChatProfileSectionState( @@ -94,7 +94,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() { @Test fun `clicking the phone row opens a tel intent`() = runAndroidComposeUiTest { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) setContent { HealthChatProfileSectionView( state = aHealthChatProfileSectionState( @@ -110,7 +110,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() { @Test fun `a loading state renders nothing`() = runAndroidComposeUiTest { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) setContent { HealthChatProfileSectionView( state = aHealthChatProfileSectionState( @@ -124,7 +124,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() { @Test fun `a NotFound failure renders nothing`() = runAndroidComposeUiTest { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) val activity = requireNotNull(activity) setContent { HealthChatProfileSectionView( @@ -139,7 +139,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() { @Test fun `an error state shows a retry row which emits Retry`() = runAndroidComposeUiTest { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() setContent { HealthChatProfileSectionView( state = aHealthChatProfileSectionState( @@ -149,6 +149,6 @@ class HealthChatProfileSectionViewTest : RobolectricTest() { ) } clickOn(CommonStrings.action_retry) - eventsRecorder.assertSingle(HealthChatProfileSectionEvents.Retry) + eventsRecorder.assertSingle(HealthChatProfileSectionEvent.Retry) } } diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomeViewBackHandlingTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomeViewBackHandlingTest.kt index f4f45856f0..7ea3d54065 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomeViewBackHandlingTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomeViewBackHandlingTest.kt @@ -28,8 +28,10 @@ class HomeViewBackHandlingTest : RobolectricTest() { currentHomeNavigationBarItem = HomeNavigationBarItem.Members, eventSink = eventsRecorder, ), - onRoomClick = {}, + onRoomClick = { _, _ -> }, onSettingsClick = {}, + onAddAccountClick = {}, + onSwitchToAccount = {}, onSetUpRecoveryClick = {}, onConfirmRecoveryKeyClick = {}, onStartChatClick = {}, @@ -58,8 +60,10 @@ class HomeViewBackHandlingTest : RobolectricTest() { currentHomeNavigationBarItem = HomeNavigationBarItem.Members, eventSink = eventsRecorder, ), - onRoomClick = {}, + onRoomClick = { _, _ -> }, onSettingsClick = {}, + onAddAccountClick = {}, + onSwitchToAccount = {}, onSetUpRecoveryClick = {}, onConfirmRecoveryKeyClick = {}, onStartChatClick = {},