diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index b9d8be16c9..a9cc829697 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -63,44 +63,6 @@ jobs:
path: |
app/build/outputs/bundle/gplayRelease/app-gplay-release.aab
- enterprise:
- name: Create App Bundle Enterprise
- runs-on: ubuntu-latest
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }}
- concurrency:
- group: ${{ format('build-release-main-enterprise-{0}', github.sha) }}
- cancel-in-progress: true
- steps:
- - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- with:
- persist-credentials: false
- - name: Add SSH private keys for submodule repositories
- uses: webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }}
- with:
- ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}
- - name: Clone submodules
- run: git submodule update --init --recursive
- - name: Use JDK 21
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
- with:
- distribution: 'temurin' # See 'Supported distributions' for available options
- java-version: '21'
- - name: Configure gradle
- uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0
- - name: Create Enterprise app bundle
- env:
- ELEMENT_ANDROID_MAPTILER_API_KEY: ${{ secrets.MAPTILER_KEY }}
- ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
- ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }}
- run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES
- - name: Upload bundle as artifact
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
- with:
- name: elementx-enterprise-app-gplay-bundle-unsigned
- path: |
- app/build/outputs/bundle/gplayRelease/app-gplay-release.aab
-
fdroid:
name: Create APKs (FDroid)
runs-on: ubuntu-latest
diff --git a/AGENTS.md b/AGENTS.md
index 917285ab30..a4a73ca965 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -50,9 +50,10 @@ PRs must meet these rules.
- Title = changelog entry — descriptive, no "Fixes #…".
- Leave description template for the developer. Redirect them to the [contributing etiquette](CONTRIBUTING.md#etiquette).
- Screenshots/videos for visual changes.
-- 500 additions max — split large changes.
+- 500 additions max into production code. Test code can be larger — split large changes.
- Commits need a title and description; no tiny or massive commits.
- No history rewrites.
+- When creating a pull request and if changes contain new or update(s) of the Composable Previews, add the label "Record-Screenshots" to the PR so that the CI will record the screenshots.
---
diff --git a/CHANGES.md b/CHANGES.md
index db18e59251..5f4be5d6eb 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,87 @@
+Changes in Element X v26.08.4
+=============================
+
+
+
+## What's Changed
+### 🧱 Build
+* Add releaseV2.sh, a release script automating the GitHub release by @bmarty in https://github.com/element-hq/element-x-android/pull/7579
+* Update submodule ref. by @bmarty in https://github.com/element-hq/element-x-android/pull/7582
+### Others
+* Keep the formatting of a caption that is being edited by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7572
+* Say when the server cannot be reached instead of showing nothing by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7567
+* Keep saving files to Downloads once 32 files share the same name by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7344
+* Fix removed messages hiding its thread on deletion by @bxdxnn in https://github.com/element-hq/element-x-android/pull/7480
+* Drop the sender's name from the room list preview of two-person rooms by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7562
+* Document how the Element Call base URL developer option is used by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7546
+
+
+**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v26.08.3...v26.08.4
+
+Changes in Element X v26.08.3
+=============================
+
+
+
+## What's Changed
+### ✨ Features
+* Let users enter their full Matrix user ID on the account provider screen by @jennaharris7 in https://github.com/element-hq/element-x-android/pull/7500
+* Enable user status feature and hide status text in the timeline by @bmarty in https://github.com/element-hq/element-x-android/pull/7517
+### 🐛 Bugfixes
+* Fix cold start with a mobile deep link by @bmarty in https://github.com/element-hq/element-x-android/pull/7488
+* Make the account provider screen scrollable so its description is not clipped by the keyboard by @jennaharris7 in https://github.com/element-hq/element-x-android/pull/7521
+### 🧱 Build
+* Update Gradle Wrapper from 9.7.0 to 9.7.1 by @ElementBot in https://github.com/element-hq/element-x-android/pull/7485
+* Fix flaky test in `DefaultVoiceMessageComposerPresenterTest` by @jmartinesp in https://github.com/element-hq/element-x-android/pull/7487
+* Fix warning about deprecated Gradle `keepRules.file` API by @jmartinesp in https://github.com/element-hq/element-x-android/pull/7498
+* Update Enterprise Copyright in idea settings, so that new files get an expected header. by @bmarty in https://github.com/element-hq/element-x-android/pull/7501
+* Remove workaround for Renovate. by @bmarty in https://github.com/element-hq/element-x-android/pull/7502
+### 🚧 In development 🚧
+* Make PIP react to camera orientation changes in the other participant's device by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6951
+* Feature: global search by @jmartinesp in https://github.com/element-hq/element-x-android/pull/7410
+### Dependency upgrades
+* Update dependency org.maplibre.gl:android-sdk to v13.5.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/7486
+* Update dependency androidx.webkit:webkit to v1.17.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/7484
+* Update dependency io.sentry:sentry-android to v8.53.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/7481
+* Update dependency io.element.android:element-call-embedded to v0.24.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/7474
+* Update roborazzi to v1.72.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/7489
+* Update metro to v1.4.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/7493
+* Update dependency com.squareup.okhttp3:okhttp-bom to v5.5.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/7512
+* Update dependency com.google.guava:guava to v33.7.0-android by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/7516
+* Update sdk to version 26.08.25 by @bmarty in https://github.com/element-hq/element-x-android/pull/7550
+### 💼 Element Pro
+* Add `ClientEnterpriseHook` and `ClientBuilderEnterpriseHook` by @jmartinesp in https://github.com/element-hq/element-x-android/pull/7495
+* Remove dependency on enterprise module. by @bmarty in https://github.com/element-hq/element-x-android/pull/7505
+### Others
+* Show the right image when opening one that has not finished sending by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7359
+* Move strings to the login module by @bmarty in https://github.com/element-hq/element-x-android/pull/7494
+* Allow empty problem description if the GitHub issue number is present for rageshakes by @bxdxnn in https://github.com/element-hq/element-x-android/pull/7497
+* Apply the system theme when switching back to it from a forced light or dark theme by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7453
+* Show dialog with reason when user clicks on a message with a failure by @bmarty in https://github.com/element-hq/element-x-android/pull/7490
+* Keep a focused timeline focused until the event has been rendered by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7463
+* Do not render in-chat key verification requests in the timeline by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7443
+* Share a file whose mime type is not one of the supported ones by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7435
+* Show reactions in the pinned messages list by @bxdxnn in https://github.com/element-hq/element-x-android/pull/6676
+* Send a concrete mime type for media shared with a wildcard one by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7449
+* Rename module and ensure that naming convention is followed by @bmarty in https://github.com/element-hq/element-x-android/pull/7514
+* Fix lint issue, ensure that PiP methods are not called on old devices not supporting them. by @bmarty in https://github.com/element-hq/element-x-android/pull/7515
+* Rename PreviewParameterProvider subclasses to the PreviewParam suffix by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7468
+* Update Ref. by @bmarty in https://github.com/element-hq/element-x-android/pull/7518
+* Remove the reference to the decommissioned OIDC playground by @sandhose in https://github.com/element-hq/element-x-android/pull/7519
+* Hide the encryption badge when key storage is set up on the server by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7447
+* Rename remaining events sealed interface by @bmarty in https://github.com/element-hq/element-x-android/pull/7533
+* Stop waiting on a verification request the other session never accepts by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7457
+* Point the proxy debugging doc at the method that builds the clients by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7543
+* Show the build date in the screenshot gallery footer by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7544
+* Run the database migrations again when a database is upgraded by @hayaksi1 in https://github.com/element-hq/element-x-android/pull/7570
+* Update fonts on the headings by @bmarty in https://github.com/element-hq/element-x-android/pull/7520
+* Add a "Push rules" entry in the developer options by @bmarty in https://github.com/element-hq/element-x-android/pull/7577
+
+## New Contributors
+* @sandhose made their first contribution in https://github.com/element-hq/element-x-android/pull/7519
+
+**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v26.08.2...v26.08.3
+
Changes in Element X v26.08.2
=============================
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f6a3225cb8..d5f08e0795 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -139,6 +139,12 @@
+
+
diff --git a/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt b/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt
index 38952b144f..a3712ebbf6 100644
--- a/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt
+++ b/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt
@@ -13,10 +13,14 @@ import androidx.compose.material3.ComposeMaterial3Flags.isAnchoredDraggableCompo
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.startup.AppInitializer
import androidx.work.Configuration
+import dev.zacsweers.metro.Inject
import dev.zacsweers.metro.createGraphFactory
+import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.di.DependencyInjectionGraphOwner
+import io.element.android.libraries.matrix.api.SdkMetadata
import io.element.android.libraries.workmanager.api.di.MetroWorkerFactory
import io.element.android.x.di.AppGraph
+import io.element.android.x.di.ApplicationBindings
import io.element.android.x.info.logApplicationInfo
import io.element.android.x.initializer.CacheCleanerInitializer
import io.element.android.x.initializer.CrashInitializer
@@ -29,6 +33,8 @@ class ElementXApplication : Application(), DependencyInjectionGraphOwner, Config
.setWorkerFactory(MetroWorkerFactory(graph.workerProviders))
.build()
+ @Inject lateinit var sdkMetadata: SdkMetadata
+
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate() {
super.onCreate()
@@ -38,7 +44,8 @@ class ElementXApplication : Application(), DependencyInjectionGraphOwner, Config
initializeComponent(CacheCleanerInitializer::class.java)
}
- logApplicationInfo(this)
+ bindings().inject(this)
+ logApplicationInfo(this, sdkMetadata.sdkGitSha)
// Disable the strict offset check for anchored draggable components, as it can cause issues with bottom sheets.
// Remove once https://issuetracker.google.com/issues/477038695 is fixed.
diff --git a/app/src/main/kotlin/io/element/android/x/MainActivity.kt b/app/src/main/kotlin/io/element/android/x/MainActivity.kt
index a882dd8769..c5551f11aa 100644
--- a/app/src/main/kotlin/io/element/android/x/MainActivity.kt
+++ b/app/src/main/kotlin/io/element/android/x/MainActivity.kt
@@ -61,6 +61,13 @@ class MainActivity : NodeActivity() {
setContent {
MainContent(appBindings)
}
+
+ val activity = this
+ appBindings.appStartupHooks().forEach {
+ lifecycleScope.launch {
+ it.onAppStartup(activity)
+ }
+ }
}
@Composable
diff --git a/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt b/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt
index 6768d0d8db..638ba0e38c 100644
--- a/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt
+++ b/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt
@@ -10,7 +10,9 @@ package io.element.android.x.di
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesTo
+import dev.zacsweers.metro.Multibinds
import io.element.android.features.api.MigrationEntryPoint
+import io.element.android.features.enterprise.api.AppStartupHook
import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.features.lockscreen.api.LockScreenEntryPoint
import io.element.android.features.lockscreen.api.LockScreenService
@@ -51,4 +53,7 @@ interface AppBindings {
fun buildMeta(): BuildMeta
fun sentrySdkDsn(): SentrySdkDsn?
+
+ @Multibinds(allowEmpty = true)
+ fun appStartupHooks(): Set
}
diff --git a/app/src/main/kotlin/io/element/android/x/di/ApplicationBindings.kt b/app/src/main/kotlin/io/element/android/x/di/ApplicationBindings.kt
new file mode 100644
index 0000000000..3bc2445f58
--- /dev/null
+++ b/app/src/main/kotlin/io/element/android/x/di/ApplicationBindings.kt
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2026 Element Creations Ltd.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
+ * Please see LICENSE files in the repository root for full details.
+ */
+
+package io.element.android.x.di
+
+import dev.zacsweers.metro.AppScope
+import dev.zacsweers.metro.ContributesTo
+import io.element.android.x.ElementXApplication
+
+@ContributesTo(AppScope::class)
+interface ApplicationBindings {
+ fun inject(application: ElementXApplication)
+}
diff --git a/app/src/main/kotlin/io/element/android/x/info/Logs.kt b/app/src/main/kotlin/io/element/android/x/info/Logs.kt
index 2b66fef55e..a9c6f6cee6 100644
--- a/app/src/main/kotlin/io/element/android/x/info/Logs.kt
+++ b/app/src/main/kotlin/io/element/android/x/info/Logs.kt
@@ -10,32 +10,22 @@ package io.element.android.x.info
import android.content.Context
import io.element.android.libraries.androidutils.system.getVersionCodeFromManifest
+import io.element.android.libraries.core.log.logger.wrapInBox
import io.element.android.x.BuildConfig
import timber.log.Timber
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
-fun logApplicationInfo(context: Context) {
- val appVersion = buildString {
- append(BuildConfig.VERSION_NAME)
- append(" (")
- append(context.getVersionCodeFromManifest())
- append(") - ")
- append(BuildConfig.BUILD_TYPE)
- append(" / ")
- append(BuildConfig.FLAVOR)
- }
- // TODO Get SDK version somehow
- val sdkVersion = "SDK VERSION (TODO)"
+fun logApplicationInfo(context: Context, sdkGitSha: String) {
+ val appVersion = "${BuildConfig.VERSION_NAME} (${context.getVersionCodeFromManifest()}) - ${BuildConfig.BUILD_TYPE} / ${BuildConfig.FLAVOR}"
val date = SimpleDateFormat("MM-dd HH:mm:ss.SSSZ", Locale.US).format(Date())
-
- Timber.d("----------------------------------------------------------------")
- Timber.d("----------------------------------------------------------------")
- Timber.d(" Application version: $appVersion")
- Timber.d(" Git SHA: ${BuildConfig.GIT_REVISION}")
- Timber.d(" SDK version: $sdkVersion")
- Timber.d(" Local time: $date")
- Timber.d("----------------------------------------------------------------")
- Timber.d("----------------------------------------------------------------\n\n\n\n")
+ listOf(
+ " Application version: $appVersion",
+ " Element X: https://github.com/element-hq/element-x-android/commit/${BuildConfig.GIT_REVISION}",
+ " SDK : https://github.com/matrix-org/matrix-rust-sdk/commit/$sdkGitSha",
+ " Local time: $date",
+ )
+ .wrapInBox(minBoxInsideWidth = 80)
+ .forEach { Timber.d(it) }
}
diff --git a/app/src/main/res/xml/shortcuts.xml b/app/src/main/res/xml/shortcuts.xml
new file mode 100644
index 0000000000..d4995157d8
--- /dev/null
+++ b/app/src/main/res/xml/shortcuts.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInEvents.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInEvent.kt
similarity index 90%
rename from appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInEvents.kt
rename to appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInEvent.kt
index 66fffce9e8..34ba2e6460 100644
--- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInEvents.kt
+++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInEvent.kt
@@ -8,11 +8,11 @@
package io.element.android.appnav.loggedin
-sealed interface LoggedInEvents {
- data class CloseErrorDialog(val doNotShowAgain: Boolean) : LoggedInEvents
- data object CheckSlidingSyncProxyAvailability : LoggedInEvents
- data object LogoutAndMigrateToNativeSlidingSync : LoggedInEvents
- data object DismissLocalNetworkPermissionPrompt : LoggedInEvents
+sealed interface LoggedInEvent {
+ data class CloseErrorDialog(val doNotShowAgain: Boolean) : LoggedInEvent
+ data object CheckSlidingSyncProxyAvailability : LoggedInEvent
+ data object LogoutAndMigrateToNativeSlidingSync : LoggedInEvent
+ data object DismissLocalNetworkPermissionPrompt : LoggedInEvent
- data object RequestLocationNetworkPermission : LoggedInEvents
+ data object RequestLocationNetworkPermission : LoggedInEvent
}
diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt
index 5cd3efa801..f2f6e1312f 100644
--- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt
+++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt
@@ -105,9 +105,18 @@ class LoggedInPresenter(
}
val syncIndicator by matrixClient.roomListService.syncIndicator.collectAsState()
val isOnline by syncService.isOnline.collectAsState()
- val showSyncSpinner by remember {
+ val hasNetwork by networkMonitor.connectivity.collectAsState()
+ val syncIndicatorState by remember {
derivedStateOf {
- isOnline && syncIndicator == RoomListService.SyncIndicator.Show
+ when {
+ isOnline -> if (syncIndicator == RoomListService.SyncIndicator.Show) {
+ SyncIndicatorState.Syncing
+ } else {
+ SyncIndicatorState.Hidden
+ }
+ hasNetwork == NetworkStatus.Connected -> SyncIndicatorState.ServerUnreachable
+ else -> SyncIndicatorState.Hidden
+ }
}
}
var forceNativeSlidingSyncMigration by remember { mutableStateOf(false) }
@@ -149,9 +158,9 @@ class LoggedInPresenter(
else -> LocalNetworkPermissionDialog.Settings
}
- fun handleEvent(event: LoggedInEvents) {
+ fun handleEvent(event: LoggedInEvent) {
when (event) {
- is LoggedInEvents.CloseErrorDialog -> {
+ is LoggedInEvent.CloseErrorDialog -> {
pusherRegistrationState.value = AsyncData.Uninitialized
if (event.doNotShowAgain) {
coroutineScope.launch {
@@ -159,17 +168,17 @@ class LoggedInPresenter(
}
}
}
- LoggedInEvents.CheckSlidingSyncProxyAvailability -> coroutineScope.launch {
+ LoggedInEvent.CheckSlidingSyncProxyAvailability -> coroutineScope.launch {
forceNativeSlidingSyncMigration = matrixClient.needsForcedNativeSlidingSyncMigration().getOrDefault(false)
}
- LoggedInEvents.LogoutAndMigrateToNativeSlidingSync -> coroutineScope.launch {
+ LoggedInEvent.LogoutAndMigrateToNativeSlidingSync -> coroutineScope.launch {
// Force the logout since Native Sliding Sync is already enforced by the SDK
matrixClient.logout(userInitiated = true, ignoreSdkError = true)
}
- LoggedInEvents.DismissLocalNetworkPermissionPrompt -> {
+ LoggedInEvent.DismissLocalNetworkPermissionPrompt -> {
localNetworkPromptDismissedThisSession = true
}
- LoggedInEvents.RequestLocationNetworkPermission -> {
+ LoggedInEvent.RequestLocationNetworkPermission -> {
if (localNetworkPermissionDialog == LocalNetworkPermissionDialog.Settings) {
localNetworkPermissionState.eventSink(PermissionsEvent.OpenSystemSettingAndCloseDialog)
} else {
@@ -181,7 +190,7 @@ class LoggedInPresenter(
}
return LoggedInState(
- showSyncSpinner = showSyncSpinner,
+ syncIndicatorState = syncIndicatorState,
pusherRegistrationState = pusherRegistrationState.value,
ignoreRegistrationError = ignoreRegistrationError,
forceNativeSlidingSyncMigration = forceNativeSlidingSyncMigration,
diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInState.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInState.kt
index edc12383bf..8ac675a146 100644
--- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInState.kt
+++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInState.kt
@@ -11,12 +11,18 @@ package io.element.android.appnav.loggedin
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.permissions.api.localnetwork.LocalNetworkPermissionDialog
+enum class SyncIndicatorState {
+ Hidden,
+ Syncing,
+ ServerUnreachable,
+}
+
data class LoggedInState(
- val showSyncSpinner: Boolean,
+ val syncIndicatorState: SyncIndicatorState,
val pusherRegistrationState: AsyncData,
val ignoreRegistrationError: Boolean,
val forceNativeSlidingSyncMigration: Boolean,
val appName: String,
val localNetworkPermissionDialog: LocalNetworkPermissionDialog,
- val eventSink: (LoggedInEvents) -> Unit,
+ val eventSink: (LoggedInEvent) -> Unit,
)
diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInStatePreviewParam.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInStatePreviewParam.kt
index b479e00279..705f6fbe61 100644
--- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInStatePreviewParam.kt
+++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInStatePreviewParam.kt
@@ -17,7 +17,8 @@ open class LoggedInStatePreviewParam : PreviewParameterProvider {
override val values: Sequence
get() = sequenceOf(
aLoggedInState(),
- aLoggedInState(showSyncSpinner = true),
+ aLoggedInState(syncIndicatorState = SyncIndicatorState.Syncing),
+ aLoggedInState(syncIndicatorState = SyncIndicatorState.ServerUnreachable),
aLoggedInState(pusherRegistrationState = AsyncData.Failure(PusherRegistrationFailure.NoDistributorsAvailable())),
aLoggedInState(forceNativeSlidingSyncMigration = true),
aLoggedInState(localNetworkPermissionDialog = LocalNetworkPermissionDialog.Rationale),
@@ -26,13 +27,13 @@ open class LoggedInStatePreviewParam : PreviewParameterProvider {
}
fun aLoggedInState(
- showSyncSpinner: Boolean = false,
+ syncIndicatorState: SyncIndicatorState = SyncIndicatorState.Hidden,
pusherRegistrationState: AsyncData = AsyncData.Uninitialized,
forceNativeSlidingSyncMigration: Boolean = false,
appName: String = "Element X",
localNetworkPermissionDialog: LocalNetworkPermissionDialog = LocalNetworkPermissionDialog.None,
) = LoggedInState(
- showSyncSpinner = showSyncSpinner,
+ syncIndicatorState = syncIndicatorState,
pusherRegistrationState = pusherRegistrationState,
ignoreRegistrationError = false,
forceNativeSlidingSyncMigration = forceNativeSlidingSyncMigration,
diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt
index 7e607e7d92..1d3a355663 100644
--- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt
+++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt
@@ -37,7 +37,7 @@ fun LoggedInView(
) {
OnLifecycleEvent { _, event ->
if (event == Lifecycle.Event.ON_RESUME) {
- state.eventSink(LoggedInEvents.CheckSlidingSyncProxyAvailability)
+ state.eventSink(LoggedInEvent.CheckSlidingSyncProxyAvailability)
}
}
Box(
@@ -47,7 +47,7 @@ fun LoggedInView(
) {
SyncStateView(
modifier = Modifier.align(Alignment.TopCenter),
- isVisible = state.showSyncSpinner,
+ state = state.syncIndicatorState,
)
}
when (state.pusherRegistrationState) {
@@ -63,10 +63,10 @@ fun LoggedInView(
content = stringResource(id = CommonStrings.common_error_registering_pusher_android, reason),
cancelText = stringResource(id = CommonStrings.common_settings),
onDismiss = {
- state.eventSink(LoggedInEvents.CloseErrorDialog(it))
+ state.eventSink(LoggedInEvent.CloseErrorDialog(it))
},
onCancel = {
- state.eventSink(LoggedInEvents.CloseErrorDialog(false))
+ state.eventSink(LoggedInEvent.CloseErrorDialog(false))
navigateToNotificationTroubleshoot()
}
)
@@ -79,15 +79,15 @@ fun LoggedInView(
ForceNativeSlidingSyncMigrationDialog(
appName = state.appName,
onSubmit = {
- state.eventSink(LoggedInEvents.LogoutAndMigrateToNativeSlidingSync)
+ state.eventSink(LoggedInEvent.LogoutAndMigrateToNativeSlidingSync)
}
)
}
LocalNetworkPermissionDialogView(
dialog = state.localNetworkPermissionDialog,
- onSubmit = { state.eventSink(LoggedInEvents.RequestLocationNetworkPermission) },
- onDismiss = { state.eventSink(LoggedInEvents.DismissLocalNetworkPermissionPrompt) },
+ onSubmit = { state.eventSink(LoggedInEvent.RequestLocationNetworkPermission) },
+ onDismiss = { state.eventSink(LoggedInEvent.DismissLocalNetworkPermissionPrompt) },
)
}
diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SyncStateView.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SyncStateView.kt
index 7c5f196a4c..db39658ad4 100644
--- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SyncStateView.kt
+++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SyncStateView.kt
@@ -25,18 +25,23 @@ import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun SyncStateView(
- isVisible: Boolean,
+ state: SyncIndicatorState,
modifier: Modifier = Modifier
) {
AnimatedVisibility(
- visible = isVisible,
+ visible = state != SyncIndicatorState.Hidden,
modifier = modifier,
enter = fadeIn(spring(stiffness = 500F)),
exit = fadeOut(spring(stiffness = 500F)),
) {
- AsyncIndicator.Loading(
- text = stringResource(id = CommonStrings.common_syncing),
- )
+ when (state) {
+ SyncIndicatorState.ServerUnreachable -> AsyncIndicator.Failure(
+ text = stringResource(id = CommonStrings.common_server_unreachable),
+ )
+ else -> AsyncIndicator.Loading(
+ text = stringResource(id = CommonStrings.common_syncing),
+ )
+ }
}
}
@@ -46,7 +51,18 @@ internal fun SyncStateViewPreview() = ElementPreview {
// Add a box to see the shadow
Box(modifier = Modifier.padding(24.dp)) {
SyncStateView(
- isVisible = true
+ state = SyncIndicatorState.Syncing
+ )
+ }
+}
+
+@PreviewsDayNight
+@Composable
+internal fun SyncStateViewServerUnreachablePreview() = ElementPreview {
+ // Add a box to see the shadow
+ Box(modifier = Modifier.padding(24.dp)) {
+ SyncStateView(
+ state = SyncIndicatorState.ServerUnreachable
)
}
}
diff --git a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt
index 0e2d459d1e..474253c8df 100644
--- a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt
+++ b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt
@@ -67,7 +67,7 @@ class LoggedInPresenterTest {
fun `present - initial state`() = runTest {
createLoggedInPresenter().test {
val initialState = awaitItem()
- assertThat(initialState.showSyncSpinner).isFalse()
+ assertThat(initialState.syncIndicatorState).isEqualTo(SyncIndicatorState.Hidden)
assertThat(initialState.pusherRegistrationState.isUninitialized()).isTrue()
assertThat(initialState.ignoreRegistrationError).isFalse()
}
@@ -97,11 +97,33 @@ class LoggedInPresenterTest {
matrixClient = FakeMatrixClient(roomListService = roomListService),
).test {
val initialState = awaitItem()
- assertThat(initialState.showSyncSpinner).isFalse()
+ assertThat(initialState.syncIndicatorState).isEqualTo(SyncIndicatorState.Hidden)
roomListService.postSyncIndicator(RoomListService.SyncIndicator.Show)
- consumeItemsUntilPredicate { it.showSyncSpinner }
+ consumeItemsUntilPredicate { it.syncIndicatorState == SyncIndicatorState.Syncing }
roomListService.postSyncIndicator(RoomListService.SyncIndicator.Hide)
- consumeItemsUntilPredicate { !it.showSyncSpinner }
+ consumeItemsUntilPredicate { it.syncIndicatorState != SyncIndicatorState.Syncing }
+ }
+ }
+
+ @Test
+ fun `present - say the server is unreachable when the device has network but the sync is offline`() = runTest {
+ createLoggedInPresenter(
+ syncState = SyncState.Offline,
+ networkMonitor = FakeNetworkMonitor(initialStatus = NetworkStatus.Connected),
+ ).test {
+ consumeItemsUntilPredicate { it.syncIndicatorState == SyncIndicatorState.ServerUnreachable }
+ cancelAndConsumeRemainingEvents()
+ }
+ }
+
+ @Test
+ fun `present - say nothing when the device itself has no network`() = runTest {
+ createLoggedInPresenter(
+ syncState = SyncState.Offline,
+ networkMonitor = FakeNetworkMonitor(initialStatus = NetworkStatus.Disconnected),
+ ).test {
+ consumeItemsUntilPredicate { it.syncIndicatorState == SyncIndicatorState.Hidden }
+ cancelAndConsumeRemainingEvents()
}
}
@@ -210,7 +232,7 @@ class LoggedInPresenterTest {
lambda.assertions()
.isCalledOnce()
// Reset the error and do not show again
- finalState.eventSink(LoggedInEvents.CloseErrorDialog(doNotShowAgain = false))
+ finalState.eventSink(LoggedInEvent.CloseErrorDialog(doNotShowAgain = false))
val lastState = awaitItem()
assertThat(lastState.pusherRegistrationState.isUninitialized()).isTrue()
assertThat(lastState.ignoreRegistrationError).isFalse()
@@ -240,7 +262,7 @@ class LoggedInPresenterTest {
lambda.assertions()
.isCalledOnce()
// Reset the error and do not show again
- finalState.eventSink(LoggedInEvents.CloseErrorDialog(doNotShowAgain = true))
+ finalState.eventSink(LoggedInEvent.CloseErrorDialog(doNotShowAgain = true))
skipItems(1)
setIgnoreRegistrationErrorLambda.assertions()
.isCalledOnce()
@@ -296,7 +318,7 @@ class LoggedInPresenterTest {
).test {
val initialState = awaitItem()
assertThat(initialState.forceNativeSlidingSyncMigration).isFalse()
- initialState.eventSink(LoggedInEvents.CheckSlidingSyncProxyAvailability)
+ initialState.eventSink(LoggedInEvent.CheckSlidingSyncProxyAvailability)
assertThat(awaitItem().forceNativeSlidingSyncMigration).isTrue()
}
}
@@ -318,7 +340,7 @@ class LoggedInPresenterTest {
).test {
val initialState = awaitItem()
- initialState.eventSink(LoggedInEvents.LogoutAndMigrateToNativeSlidingSync)
+ initialState.eventSink(LoggedInEvent.LogoutAndMigrateToNativeSlidingSync)
advanceUntilIdle()
diff --git a/docs/_developer_onboarding.md b/docs/_developer_onboarding.md
index e7515eb466..01ad915126 100644
--- a/docs/_developer_onboarding.md
+++ b/docs/_developer_onboarding.md
@@ -322,7 +322,7 @@ Example for a new feature called RoomDetails:
4. Verify that the structure looks ok and click on Finish
5. The modules api/impl should be created under `features/roomdetails` directory.
6. Sync project with Gradle so the modules are recognized (no need to add them to settings.gradle).
-7. You can now add more Presentation classes (Events, State, StatePreviewParam, View, Presenter) in the impl module with the `Template Presentation Classes`.
+7. You can now add more Presentation classes (Event, State, StatePreviewParam, View, Presenter) in the impl module with the `Template Presentation Classes`.
To use it, just right click on the package where you want to generate classes, and click on `New` / `Template Presentation Classes`.
Fill the text field with the base name of the classes: the generated files are `Event.kt`, `State.kt`,
`StatePreviewParam.kt`, `Presenter.kt`, `Node.kt` and `View.kt`. For instance
diff --git a/docs/debug_proxying.md b/docs/debug_proxying.md
index a28163c959..f76c24eecb 100644
--- a/docs/debug_proxying.md
+++ b/docs/debug_proxying.md
@@ -9,13 +9,18 @@
1) Set `127.0.0.1` as "Host name" and `8080` as "Port number".
1) Click "Apply" and verify that "Proxy status" is "Success" and close the settings window.
+ 1) Alternatively, set the proxy on the device itself, which the app honours through `DefaultProxyProvider`, and which also works on a physical device:
+ ```
+ adb shell settings put global http_proxy 10.0.2.2:8080
+ ```
+ Use `adb shell settings delete global http_proxy` to remove it afterwards. On a physical device, replace `10.0.2.2` with the address of the machine running mitmproxy.
1) Install the mitmproxy CA cert (this is needed to see traffic from java/kotlin code, it's not needed for traffic coming from native code e.g. the matrix-rust-sdk).
1) Open the emulator Chrome browser app
1) Go to the url `mitm.it`
1) Follow the instructions to install the CA cert on Android devices.
1) Slightly modify the Element X app source code.
- 1) Go to the `RustMatrixClientFactory.create()` method.
+ 1) Go to the `RustMatrixClientFactory.getBaseClientBuilder()` method, which builds every client the app creates, whether it is logging in or restoring a session.
1) Add `.disableSslVerification()` in the `ClientBuilder` method chain.
1) Build and run the Element X app.
1) Enjoy, you will see all the traffic in mitmproxy's web interface.
diff --git a/docs/element_call.md b/docs/element_call.md
new file mode 100644
index 0000000000..e4bd46e2cb
--- /dev/null
+++ b/docs/element_call.md
@@ -0,0 +1,53 @@
+# Element Call
+
+
+
+* [Overview](#overview)
+* [Setting a custom base URL](#setting-a-custom-base-url)
+* [Why the application does not add the room path itself](#why-the-application-does-not-add-the-room-path-itself)
+* [Where the value is read](#where-the-value-is-read)
+
+
+
+## Overview
+
+Element X embeds a copy of [Element Call](https://github.com/element-hq/element-call) in the
+application assets and loads it from
+`https://appassets.androidplatform.net/element-call/index.html`. Calls therefore work out of the box
+with no extra deployment, and the embedded copy is the one every user gets.
+
+Developers can point the application at another Element Call deployment instead — a local
+development server, a staging deployment, or a self-hosted one — with the **Element Call base URL**
+developer option.
+
+## Setting a custom base URL
+
+The option lives in *Settings* → *Developer options* → *Element Call*, under "Element Call base
+URL". On a release build the *Developer options* entry is hidden until the version number at the
+bottom of *Settings* is tapped seven times. Leaving the field empty restores the embedded copy.
+
+The value is used verbatim as the widget base URL, so it must be the URL of the page that joins a
+room, not the URL of the deployment root. For the public deployments that means:
+
+| Deployment | Value to enter |
+|---|---|
+| `call.element.io` | `https://call.element.io/room` |
+| `call.element.dev` | `https://call.element.dev/room` |
+
+Entering `https://call.element.io` without the `/room` suffix loads the Element Call lobby rather
+than the room, so the call is never joined.
+
+## Why the application does not add the room path itself
+
+The path that joins a room is a property of the deployment, not of Element Call. Unpacking the
+Element Call release tarball behind a reverse proxy can put it at any path — `https://call.foo.tld`,
+`https://call.foo.tld/some/path/somewhere` — and a proxy that already maps a subdomain onto
+`https://1.2.3.4/room` would end up with the suffix twice. The application passes the value through
+unchanged so that every one of those deployments can be reached.
+
+## Where the value is read
+
+`AppDeveloperSettingsView` renders the field and sends
+`AppDeveloperSettingsEvent.SetCustomElementCallBaseUrl`, which `DefaultAppPreferencesStore` persists.
+`DefaultCallWidgetProvider.getWidget` reads it back and falls back to the embedded copy when it is
+unset.
diff --git a/docs/install_from_github_release.md b/docs/install_from_github_release.md
index 5ac27ff812..1fd963e953 100644
--- a/docs/install_from_github_release.md
+++ b/docs/install_from_github_release.md
@@ -64,16 +64,16 @@ brew install bundletool
### Steps
1. Open the GitHub release that you want to install from https://github.com/element-hq/element-x-android/releases
-2. Download the asset `app-release-signed.aab`
+2. Download the asset `app-gplay-release-signed.aab`
3. Navigate to the folder where you cloned the project and run the following command:
```bash
-bundletool build-apks --bundle= --output=./tmp/elementx.apks \
+bundletool build-apks --bundle= --output=./tmp/elementx.apks \
--ks=./app/signature/debug.keystore --ks-pass=pass:android --ks-key-alias=androiddebugkey --key-pass=pass:android \
--overwrite
```
For instance:
```bash
-bundletool build-apks --bundle=./tmp/Element/0.1.5/app-release-signed.aab --output=./tmp/elementx.apks \
+bundletool build-apks --bundle=./tmp/Element/26.08.3/app-gplay-release-signed.aab --output=./tmp/elementx.apks \
--ks=./app/signature/debug.keystore --ks-pass=pass:android --ks-key-alias=androiddebugkey --key-pass=pass:android \
--overwrite
```
diff --git a/enterprise b/enterprise
index e633a343b1..53750903f2 160000
--- a/enterprise
+++ b/enterprise
@@ -1 +1 @@
-Subproject commit e633a343b12088b1fe3fd6b27ec319c1f7f2931c
+Subproject commit 53750903f229a410ec4dded2bb6357431a55662e
diff --git a/fastlane/metadata/android/en-US/changelogs/202608030.txt b/fastlane/metadata/android/en-US/changelogs/202608030.txt
new file mode 100644
index 0000000000..a4b397f1bb
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/202608030.txt
@@ -0,0 +1,2 @@
+Main changes in this version: bug fixes and improvements.
+Full changelog: https://github.com/element-hq/element-x-android/releases
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/202608040.txt b/fastlane/metadata/android/en-US/changelogs/202608040.txt
new file mode 100644
index 0000000000..a4b397f1bb
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/202608040.txt
@@ -0,0 +1,2 @@
+Main changes in this version: bug fixes and improvements.
+Full changelog: https://github.com/element-hq/element-x-android/releases
\ No newline at end of file
diff --git a/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/AnalyticsOptInEvents.kt b/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/AnalyticsOptInEvent.kt
similarity index 86%
rename from features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/AnalyticsOptInEvents.kt
rename to features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/AnalyticsOptInEvent.kt
index 4181f52ba8..6095bc67da 100644
--- a/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/AnalyticsOptInEvents.kt
+++ b/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/AnalyticsOptInEvent.kt
@@ -8,6 +8,6 @@
package io.element.android.features.analytics.api
-sealed interface AnalyticsOptInEvents {
- data class EnableAnalytics(val isEnabled: Boolean) : AnalyticsOptInEvents
+sealed interface AnalyticsOptInEvent {
+ data class EnableAnalytics(val isEnabled: Boolean) : AnalyticsOptInEvent
}
diff --git a/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesState.kt b/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesState.kt
index 20a180446c..b5f049460d 100644
--- a/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesState.kt
+++ b/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesState.kt
@@ -8,11 +8,11 @@
package io.element.android.features.analytics.api.preferences
-import io.element.android.features.analytics.api.AnalyticsOptInEvents
+import io.element.android.features.analytics.api.AnalyticsOptInEvent
data class AnalyticsPreferencesState(
val applicationName: String,
val isEnabled: Boolean,
val policyUrl: String,
- val eventSink: (AnalyticsOptInEvents) -> Unit,
+ val eventSink: (AnalyticsOptInEvent) -> Unit,
)
diff --git a/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesView.kt b/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesView.kt
index 0d141e5ed2..31891a0162 100644
--- a/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesView.kt
+++ b/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesView.kt
@@ -13,7 +13,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
-import io.element.android.features.analytics.api.AnalyticsOptInEvents
+import io.element.android.features.analytics.api.AnalyticsOptInEvent
import io.element.android.features.analytics.api.R
import io.element.android.libraries.designsystem.components.LINK_TAG
import io.element.android.libraries.designsystem.components.list.ListItemContent
@@ -30,7 +30,7 @@ fun AnalyticsPreferencesView(
modifier: Modifier = Modifier,
) {
fun onEnabledChanged(isEnabled: Boolean) {
- state.eventSink(AnalyticsOptInEvents.EnableAnalytics(isEnabled = isEnabled))
+ state.eventSink(AnalyticsOptInEvent.EnableAnalytics(isEnabled = isEnabled))
}
val supportingText = stringResource(
diff --git a/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenter.kt b/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenter.kt
index d7bdb85e35..05d2c2fefd 100644
--- a/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenter.kt
+++ b/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenter.kt
@@ -12,7 +12,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import dev.zacsweers.metro.Inject
import io.element.android.appconfig.AnalyticsConfig
-import io.element.android.features.analytics.api.AnalyticsOptInEvents
+import io.element.android.features.analytics.api.AnalyticsOptInEvent
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.services.analytics.api.AnalyticsService
@@ -28,9 +28,9 @@ class AnalyticsOptInPresenter(
override fun present(): AnalyticsOptInState {
val localCoroutineScope = rememberCoroutineScope()
- fun handleEvent(event: AnalyticsOptInEvents) {
+ fun handleEvent(event: AnalyticsOptInEvent) {
when (event) {
- is AnalyticsOptInEvents.EnableAnalytics -> localCoroutineScope.setIsEnabled(event.isEnabled)
+ is AnalyticsOptInEvent.EnableAnalytics -> localCoroutineScope.setIsEnabled(event.isEnabled)
}
localCoroutineScope.launch {
analyticsService.setDidAskUserConsent()
diff --git a/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInState.kt b/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInState.kt
index b2ebd37e20..063ed316c8 100644
--- a/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInState.kt
+++ b/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInState.kt
@@ -8,10 +8,10 @@
package io.element.android.features.analytics.impl
-import io.element.android.features.analytics.api.AnalyticsOptInEvents
+import io.element.android.features.analytics.api.AnalyticsOptInEvent
data class AnalyticsOptInState(
val applicationName: String,
val hasPolicyLink: Boolean,
- val eventSink: (AnalyticsOptInEvents) -> Unit
+ val eventSink: (AnalyticsOptInEvent) -> Unit
)
diff --git a/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInView.kt b/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInView.kt
index 678d28c5c9..3ead26ea48 100644
--- a/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInView.kt
+++ b/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInView.kt
@@ -28,7 +28,7 @@ import androidx.compose.ui.unit.dp
import io.element.android.appconfig.AnalyticsConfig
import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons
-import io.element.android.features.analytics.api.AnalyticsOptInEvents
+import io.element.android.features.analytics.api.AnalyticsOptInEvent
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
@@ -55,11 +55,11 @@ fun AnalyticsOptInView(
val eventSink = state.eventSink
fun onAcceptTerms() {
- eventSink(AnalyticsOptInEvents.EnableAnalytics(true))
+ eventSink(AnalyticsOptInEvent.EnableAnalytics(true))
}
fun onDeclineTerms() {
- eventSink(AnalyticsOptInEvents.EnableAnalytics(false))
+ eventSink(AnalyticsOptInEvent.EnableAnalytics(false))
}
BackHandler(onBack = ::onDeclineTerms)
diff --git a/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenter.kt b/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenter.kt
index 110cb98d41..ca3388ee3c 100644
--- a/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenter.kt
+++ b/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenter.kt
@@ -13,7 +13,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.rememberCoroutineScope
import dev.zacsweers.metro.Inject
import io.element.android.appconfig.AnalyticsConfig
-import io.element.android.features.analytics.api.AnalyticsOptInEvents
+import io.element.android.features.analytics.api.AnalyticsOptInEvent
import io.element.android.features.analytics.api.preferences.AnalyticsPreferencesState
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta
@@ -31,9 +31,9 @@ class AnalyticsPreferencesPresenter(
val localCoroutineScope = rememberCoroutineScope()
val isEnabled = analyticsService.userConsentFlow.collectAsState(initial = false)
- fun handleEvent(event: AnalyticsOptInEvents) {
+ fun handleEvent(event: AnalyticsOptInEvent) {
when (event) {
- is AnalyticsOptInEvents.EnableAnalytics -> localCoroutineScope.setIsEnabled(event.isEnabled)
+ is AnalyticsOptInEvent.EnableAnalytics -> localCoroutineScope.setIsEnabled(event.isEnabled)
}
}
diff --git a/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenterTest.kt b/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenterTest.kt
index 6521c7f597..f2093dfa72 100644
--- a/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenterTest.kt
+++ b/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInPresenterTest.kt
@@ -12,7 +12,7 @@ import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
-import io.element.android.features.analytics.api.AnalyticsOptInEvents
+import io.element.android.features.analytics.api.AnalyticsOptInEvent
import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.WarmUpRule
@@ -37,7 +37,7 @@ class AnalyticsOptInPresenterTest {
}.test {
val initialState = awaitItem()
assertThat(analyticsService.didAskUserConsentFlow.first()).isFalse()
- initialState.eventSink.invoke(AnalyticsOptInEvents.EnableAnalytics(true))
+ initialState.eventSink.invoke(AnalyticsOptInEvent.EnableAnalytics(true))
assertThat(analyticsService.didAskUserConsentFlow.first()).isTrue()
assertThat(analyticsService.userConsentFlow.first()).isTrue()
}
@@ -55,7 +55,7 @@ class AnalyticsOptInPresenterTest {
}.test {
val initialState = awaitItem()
assertThat(analyticsService.didAskUserConsentFlow.first()).isFalse()
- initialState.eventSink.invoke(AnalyticsOptInEvents.EnableAnalytics(false))
+ initialState.eventSink.invoke(AnalyticsOptInEvent.EnableAnalytics(false))
assertThat(analyticsService.didAskUserConsentFlow.first()).isTrue()
assertThat(analyticsService.userConsentFlow.first()).isFalse()
}
diff --git a/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenterTest.kt b/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenterTest.kt
index 174935a1ad..29f7d9af03 100644
--- a/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenterTest.kt
+++ b/features/analytics/impl/src/test/kotlin/io/element/android/features/analytics/impl/preferences/AnalyticsPreferencesPresenterTest.kt
@@ -13,7 +13,7 @@ import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.appconfig.AnalyticsConfig
-import io.element.android.features.analytics.api.AnalyticsOptInEvents
+import io.element.android.features.analytics.api.AnalyticsOptInEvent
import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.WarmUpRule
@@ -67,9 +67,9 @@ class AnalyticsPreferencesPresenterTest {
skipItems(1)
val initialState = awaitItem()
assertThat(initialState.isEnabled).isTrue()
- initialState.eventSink.invoke(AnalyticsOptInEvents.EnableAnalytics(false))
+ initialState.eventSink.invoke(AnalyticsOptInEvent.EnableAnalytics(false))
assertThat(awaitItem().isEnabled).isFalse()
- initialState.eventSink.invoke(AnalyticsOptInEvents.EnableAnalytics(true))
+ initialState.eventSink.invoke(AnalyticsOptInEvent.EnableAnalytics(true))
assertThat(awaitItem().isEnabled).isTrue()
}
}
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt
index f9075691aa..b23226b9c0 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt
@@ -21,7 +21,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.features.createroom.impl.R
-import io.element.android.features.invitepeople.api.InvitePeopleEvents
+import io.element.android.features.invitepeople.api.InvitePeopleEvent
import io.element.android.features.invitepeople.api.InvitePeopleState
import io.element.android.features.invitepeople.api.InvitePeopleStatePreviewParam
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
@@ -56,7 +56,7 @@ fun AddPeopleView(
Button(
text = stringResource(CommonStrings.action_finish),
onClick = {
- state.eventSink(InvitePeopleEvents.SendInvites)
+ state.eventSink(InvitePeopleEvent.SendInvites)
},
enabled = state.canInvite,
modifier = Modifier
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvent.kt
similarity index 78%
rename from features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt
rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvent.kt
index 5de99e519d..e22e08a5b0 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvent.kt
@@ -11,13 +11,13 @@ package io.element.android.features.createroom.impl.configureroom
import io.element.android.libraries.matrix.api.spaces.SpaceRoom
import io.element.android.libraries.matrix.ui.media.AvatarAction
-sealed interface ConfigureRoomEvents {
- data class RoomNameChanged(val name: String) : ConfigureRoomEvents
- data class TopicChanged(val topic: String) : ConfigureRoomEvents
- data class JoinRuleChanged(val joinRuleItem: JoinRuleItem) : ConfigureRoomEvents
- data class RoomAddressChanged(val roomAddress: String) : ConfigureRoomEvents
- data object CreateRoom : ConfigureRoomEvents
- data class HandleAvatarAction(val action: AvatarAction) : ConfigureRoomEvents
- data class SetParentSpace(val space: SpaceRoom?) : ConfigureRoomEvents
- data object CancelCreateRoom : ConfigureRoomEvents
+sealed interface ConfigureRoomEvent {
+ data class RoomNameChanged(val name: String) : ConfigureRoomEvent
+ data class TopicChanged(val topic: String) : ConfigureRoomEvent
+ data class JoinRuleChanged(val joinRuleItem: JoinRuleItem) : ConfigureRoomEvent
+ data class RoomAddressChanged(val roomAddress: String) : ConfigureRoomEvent
+ data object CreateRoom : ConfigureRoomEvent
+ data class HandleAvatarAction(val action: AvatarAction) : ConfigureRoomEvent
+ data class SetParentSpace(val space: SpaceRoom?) : ConfigureRoomEvent
+ data object CancelCreateRoom : ConfigureRoomEvent
}
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt
index abedc2bd49..849647a9d3 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt
@@ -188,14 +188,14 @@ class ConfigureRoomPresenter(
localCoroutineScope.createRoom(config, createRoomAction)
}
- fun handleEvent(event: ConfigureRoomEvents) {
+ fun handleEvent(event: ConfigureRoomEvent) {
when (event) {
- is ConfigureRoomEvents.RoomNameChanged -> dataStore.setRoomName(event.name)
- is ConfigureRoomEvents.TopicChanged -> dataStore.setTopic(event.topic)
- is ConfigureRoomEvents.JoinRuleChanged -> dataStore.setJoinRule(event.joinRuleItem)
- is ConfigureRoomEvents.RoomAddressChanged -> dataStore.setRoomAddress(event.roomAddress)
- is ConfigureRoomEvents.CreateRoom -> createRoom(createRoomConfig)
- is ConfigureRoomEvents.HandleAvatarAction -> {
+ is ConfigureRoomEvent.RoomNameChanged -> dataStore.setRoomName(event.name)
+ is ConfigureRoomEvent.TopicChanged -> dataStore.setTopic(event.topic)
+ is ConfigureRoomEvent.JoinRuleChanged -> dataStore.setJoinRule(event.joinRuleItem)
+ is ConfigureRoomEvent.RoomAddressChanged -> dataStore.setRoomAddress(event.roomAddress)
+ is ConfigureRoomEvent.CreateRoom -> createRoom(createRoomConfig)
+ is ConfigureRoomEvent.HandleAvatarAction -> {
when (event.action) {
AvatarAction.ChoosePhoto -> galleryImagePicker.launch()
AvatarAction.TakePhoto -> if (cameraPermissionState.permissionGranted) {
@@ -207,10 +207,10 @@ class ConfigureRoomPresenter(
AvatarAction.Remove -> dataStore.setAvatarUri(uri = null)
}
}
- is ConfigureRoomEvents.SetParentSpace -> {
+ is ConfigureRoomEvent.SetParentSpace -> {
dataStore.setParentSpace(event.space, false)
}
- ConfigureRoomEvents.CancelCreateRoom -> {
+ ConfigureRoomEvent.CancelCreateRoom -> {
createRoomAction.value = AsyncAction.Uninitialized
}
}
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt
index 0da931fa51..15f549d28f 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt
@@ -26,7 +26,7 @@ data class ConfigureRoomState(
val homeserverName: String,
val availableJoinRules: ImmutableList,
val spaces: ImmutableList,
- val eventSink: (ConfigureRoomEvents) -> Unit
+ val eventSink: (ConfigureRoomEvent) -> Unit
) {
val isValid: Boolean = config.roomName?.isNotEmpty() == true &&
(config.visibilityState is RoomVisibilityState.Private || roomAddressValidity == RoomAddressValidity.Valid) &&
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStatePreviewParam.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStatePreviewParam.kt
index 151c7d13d0..725cfc2309 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStatePreviewParam.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStatePreviewParam.kt
@@ -143,7 +143,7 @@ fun aConfigureRoomState(
)
},
spaces: List = emptyList(),
- eventSink: (ConfigureRoomEvents) -> Unit = { },
+ eventSink: (ConfigureRoomEvent) -> Unit = { },
) = ConfigureRoomState(
config = config,
isSpace = isSpace,
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt
index e39df69f97..fec820ffbb 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt
@@ -96,7 +96,7 @@ fun ConfigureRoomView(
onBackClick = onBackClick,
onNextClick = {
focusManager.clearFocus()
- state.eventSink(ConfigureRoomEvents.CreateRoom)
+ state.eventSink(ConfigureRoomEvent.CreateRoom)
},
)
}
@@ -114,20 +114,20 @@ fun ConfigureRoomView(
avatarUri = state.config.avatarUri,
roomName = state.config.roomName.orEmpty(),
onAvatarClick = ::onAvatarClick,
- onChangeRoomName = { state.eventSink(ConfigureRoomEvents.RoomNameChanged(it)) },
+ onChangeRoomName = { state.eventSink(ConfigureRoomEvent.RoomNameChanged(it)) },
)
Spacer(modifier = Modifier.height(16.dp))
RoomTopic(
modifier = Modifier.padding(horizontal = 16.dp),
topic = state.config.topic.orEmpty(),
- onTopicChange = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) },
+ onTopicChange = { state.eventSink(ConfigureRoomEvent.TopicChanged(it)) },
)
Spacer(modifier = Modifier.height(16.dp))
if (!state.isSpace && state.spaces.isNotEmpty()) {
SelectParentSpaceOptions(
spaces = state.spaces,
selectedSpace = state.config.parentSpace,
- onSelectSpace = { state.eventSink(ConfigureRoomEvents.SetParentSpace(it)) },
+ onSelectSpace = { state.eventSink(ConfigureRoomEvent.SetParentSpace(it)) },
)
}
RoomJoinRuleOptions(
@@ -136,7 +136,7 @@ fun ConfigureRoomView(
parentSpace = state.config.parentSpace,
onOptionClick = {
focusManager.clearFocus()
- state.eventSink(ConfigureRoomEvents.JoinRuleChanged(it))
+ state.eventSink(ConfigureRoomEvent.JoinRuleChanged(it))
},
)
if (state.config.visibilityState !is RoomVisibilityState.Private) {
@@ -146,7 +146,7 @@ fun ConfigureRoomView(
address = state.config.visibilityState.roomAddress().getOrNull().orEmpty(),
homeserverName = state.homeserverName,
addressValidity = state.roomAddressValidity,
- onAddressChange = { state.eventSink(ConfigureRoomEvents.RoomAddressChanged(it)) },
+ onAddressChange = { state.eventSink(ConfigureRoomEvent.RoomAddressChanged(it)) },
label = null,
supportingText = stringResource(R.string.screen_create_room_room_address_section_footer),
)
@@ -158,7 +158,7 @@ fun ConfigureRoomView(
actions = state.avatarActions,
isVisible = isAvatarActionsSheetVisible.value,
onDismiss = { isAvatarActionsSheetVisible.value = false },
- onSelectAction = { state.eventSink(ConfigureRoomEvents.HandleAvatarAction(it)) }
+ onSelectAction = { state.eventSink(ConfigureRoomEvent.HandleAvatarAction(it)) }
)
AsyncActionView(
@@ -170,8 +170,8 @@ fun ConfigureRoomView(
},
onSuccess = { onCreateRoomSuccess(it) },
errorMessage = { stringResource(if (isSpace) R.string.screen_create_room_error_creating_space else R.string.screen_create_room_error_creating_room) },
- onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom) },
- onErrorDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) },
+ onRetry = { state.eventSink(ConfigureRoomEvent.CreateRoom) },
+ onErrorDismiss = { state.eventSink(ConfigureRoomEvent.CancelCreateRoom) },
)
PermissionsView(
diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/ConfigureRoomPresenterTest.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/ConfigureRoomPresenterTest.kt
index 046d00a5c6..09afd38f90 100644
--- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/ConfigureRoomPresenterTest.kt
+++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/ConfigureRoomPresenterTest.kt
@@ -12,7 +12,7 @@ import androidx.core.net.toUri
import app.cash.turbine.TurbineTestContext
import com.google.common.truth.Truth.assertThat
import im.vector.app.features.analytics.plan.CreatedRoom
-import io.element.android.features.createroom.impl.configureroom.ConfigureRoomEvents
+import io.element.android.features.createroom.impl.configureroom.ConfigureRoomEvent
import io.element.android.features.createroom.impl.configureroom.ConfigureRoomPresenter
import io.element.android.features.createroom.impl.configureroom.ConfigureRoomState
import io.element.android.features.createroom.impl.configureroom.CreateRoomConfig
@@ -106,14 +106,14 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
assertThat(initialState.isValid).isFalse()
// Room name not empty
- initialState.eventSink(ConfigureRoomEvents.RoomNameChanged(A_ROOM_NAME))
+ initialState.eventSink(ConfigureRoomEvent.RoomNameChanged(A_ROOM_NAME))
var newState: ConfigureRoomState = awaitItem()
config = config.copy(roomName = A_ROOM_NAME)
assertThat(newState.config).isEqualTo(config)
assertThat(newState.isValid).isTrue()
// Clear room name
- newState.eventSink(ConfigureRoomEvents.RoomNameChanged(""))
+ newState.eventSink(ConfigureRoomEvent.RoomNameChanged(""))
newState = awaitItem()
config = config.copy(roomName = null)
assertThat(newState.config).isEqualTo(config)
@@ -136,13 +136,13 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
var expectedConfig = CreateRoomConfig()
assertThat(initialState.config).isEqualTo(expectedConfig)
// Room name
- initialState.eventSink(ConfigureRoomEvents.RoomNameChanged(A_ROOM_NAME))
+ initialState.eventSink(ConfigureRoomEvent.RoomNameChanged(A_ROOM_NAME))
var newState = awaitItem()
expectedConfig = expectedConfig.copy(roomName = A_ROOM_NAME)
assertThat(newState.config).isEqualTo(expectedConfig)
// Room topic
- newState.eventSink(ConfigureRoomEvents.TopicChanged(A_MESSAGE))
+ newState.eventSink(ConfigureRoomEvent.TopicChanged(A_MESSAGE))
newState = awaitItem()
expectedConfig = expectedConfig.copy(topic = A_MESSAGE)
assertThat(newState.config).isEqualTo(expectedConfig)
@@ -153,7 +153,7 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
// From gallery
val uriFromGallery = AN_URI_FROM_GALLERY
pickerProvider.givenResult(uriFromGallery.toUri())
- newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
+ newState.eventSink(ConfigureRoomEvent.HandleAvatarAction(AvatarAction.ChoosePhoto))
newState = awaitItem()
expectedConfig = expectedConfig.copy(avatarUri = uriFromGallery)
assertThat(newState.config).isEqualTo(expectedConfig)
@@ -161,7 +161,7 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
val uriFromCamera = AN_URI_FROM_CAMERA
pickerProvider.givenResult(uriFromCamera.toUri())
assertThat(newState.cameraPermissionState.permissionGranted).isFalse()
- newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto))
+ newState.eventSink(ConfigureRoomEvent.HandleAvatarAction(AvatarAction.TakePhoto))
newState = awaitItem()
assertThat(newState.cameraPermissionState.showDialog).isTrue()
permissionsPresenter.setPermissionGranted()
@@ -173,18 +173,18 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
// Do it again, no permission is requested
val uriFromCamera2 = AN_URI_FROM_CAMERA_2
pickerProvider.givenResult(uriFromCamera2.toUri())
- newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto))
+ newState.eventSink(ConfigureRoomEvent.HandleAvatarAction(AvatarAction.TakePhoto))
newState = awaitItem()
expectedConfig = expectedConfig.copy(avatarUri = uriFromCamera2)
assertThat(newState.config).isEqualTo(expectedConfig)
// Remove
- newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.Remove))
+ newState.eventSink(ConfigureRoomEvent.HandleAvatarAction(AvatarAction.Remove))
newState = awaitItem()
expectedConfig = expectedConfig.copy(avatarUri = null)
assertThat(newState.config).isEqualTo(expectedConfig)
// Room privacy
- newState.eventSink(ConfigureRoomEvents.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
+ newState.eventSink(ConfigureRoomEvent.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
newState = awaitItem()
expectedConfig = expectedConfig.copy(
visibilityState = RoomVisibilityState.Public(
@@ -208,7 +208,7 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
matrixClient.givenCreateRoomResult(createRoomResult)
- initialState.eventSink(ConfigureRoomEvents.CreateRoom)
+ initialState.eventSink(ConfigureRoomEvent.CreateRoom)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
val stateAfterCreateRoom = awaitItem()
assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Success::class.java)
@@ -239,13 +239,13 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
// Use a public parent space so AskToJoin is a valid option
val parentSpace = aSpaceRoom(joinRule = JoinRule.Public)
- initialState.eventSink(ConfigureRoomEvents.SetParentSpace(parentSpace))
+ initialState.eventSink(ConfigureRoomEvent.SetParentSpace(parentSpace))
assertThat(awaitItem().config.parentSpace).isEqualTo(parentSpace)
- initialState.eventSink(ConfigureRoomEvents.JoinRuleChanged(JoinRuleItem.PublicVisibility.AskToJoin))
+ initialState.eventSink(ConfigureRoomEvent.JoinRuleChanged(JoinRuleItem.PublicVisibility.AskToJoin))
assertThat(awaitItem().config.visibilityState.joinRuleItem).isEqualTo(JoinRuleItem.PublicVisibility.AskToJoin)
- initialState.eventSink(ConfigureRoomEvents.CreateRoom)
+ initialState.eventSink(ConfigureRoomEvent.CreateRoom)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
val stateAfterCreateRoom = awaitItem()
@@ -282,13 +282,13 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
// Use a public parent space so AskToJoin is a valid option
val parentSpace = aSpaceRoom(joinRule = JoinRule.Public)
- initialState.eventSink(ConfigureRoomEvents.SetParentSpace(parentSpace))
+ initialState.eventSink(ConfigureRoomEvent.SetParentSpace(parentSpace))
assertThat(awaitItem().config.parentSpace).isEqualTo(parentSpace)
- initialState.eventSink(ConfigureRoomEvents.JoinRuleChanged(JoinRuleItem.PublicVisibility.AskToJoin))
+ initialState.eventSink(ConfigureRoomEvent.JoinRuleChanged(JoinRuleItem.PublicVisibility.AskToJoin))
assertThat(awaitItem().config.visibilityState.joinRuleItem).isEqualTo(JoinRuleItem.PublicVisibility.AskToJoin)
- initialState.eventSink(ConfigureRoomEvents.CreateRoom)
+ initialState.eventSink(ConfigureRoomEvent.CreateRoom)
// We immediately receive the room power levels info needed for adding the child to a space
val powerLevels = RoomPowerLevels(
@@ -339,7 +339,7 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
matrixClient.givenCreateRoomResult(createRoomResult)
- initialState.eventSink(ConfigureRoomEvents.CreateRoom)
+ initialState.eventSink(ConfigureRoomEvent.CreateRoom)
skipItems(2)
val analyticsEvent = analyticsService.capturedEvents.filterIsInstance().firstOrNull()
@@ -369,14 +369,14 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
mediaPreProcessor.givenResult(Result.success(MediaUploadInfo.Image(file, mockk(), mockk())))
matrixClient.givenUploadMediaResult(Result.failure(AN_EXCEPTION))
- initialState.eventSink(ConfigureRoomEvents.CreateRoom)
+ initialState.eventSink(ConfigureRoomEvent.CreateRoom)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
val stateAfterCreateRoom = awaitItem()
assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java)
assertThat(analyticsService.capturedEvents.filterIsInstance()).isEmpty()
matrixClient.givenUploadMediaResult(Result.success(AN_AVATAR_URL))
- stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom)
+ stateAfterCreateRoom.eventSink(ConfigureRoomEvent.CreateRoom)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Success::class.java)
@@ -399,14 +399,14 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
fakeMatrixClient.givenCreateRoomResult(createRoomResult)
// Create
- initialState.eventSink(ConfigureRoomEvents.CreateRoom)
+ initialState.eventSink(ConfigureRoomEvent.CreateRoom)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
val stateAfterCreateRoom = awaitItem()
assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java)
assertThat((stateAfterCreateRoom.createRoomAction as? AsyncAction.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull())
// Retry
- stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom)
+ stateAfterCreateRoom.eventSink(ConfigureRoomEvent.CreateRoom)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
val stateAfterRetry = awaitItem()
@@ -414,7 +414,7 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
assertThat((stateAfterRetry.createRoomAction as? AsyncAction.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull())
// Cancel
- stateAfterRetry.eventSink(ConfigureRoomEvents.CancelCreateRoom)
+ stateAfterRetry.eventSink(ConfigureRoomEvent.CancelCreateRoom)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
}
}
@@ -430,9 +430,9 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
)
presenter.test {
val initialState = initialState()
- initialState.eventSink(ConfigureRoomEvents.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
+ initialState.eventSink(ConfigureRoomEvent.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
skipItems(1)
- initialState.eventSink(ConfigureRoomEvents.RoomAddressChanged("invalid address"))
+ initialState.eventSink(ConfigureRoomEvent.RoomAddressChanged("invalid address"))
skipItems(1)
advanceUntilIdle()
awaitItem().also { state ->
@@ -450,9 +450,9 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
)
presenter.test {
val initialState = initialState()
- initialState.eventSink(ConfigureRoomEvents.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
+ initialState.eventSink(ConfigureRoomEvent.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
skipItems(1)
- initialState.eventSink(ConfigureRoomEvents.RoomAddressChanged("address"))
+ initialState.eventSink(ConfigureRoomEvent.RoomAddressChanged("address"))
skipItems(1)
advanceUntilIdle()
awaitItem().also { state ->
@@ -470,9 +470,9 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
)
presenter.test {
val initialState = initialState()
- initialState.eventSink(ConfigureRoomEvents.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
+ initialState.eventSink(ConfigureRoomEvent.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
skipItems(1)
- initialState.eventSink(ConfigureRoomEvents.RoomAddressChanged("address"))
+ initialState.eventSink(ConfigureRoomEvent.RoomAddressChanged("address"))
skipItems(1)
advanceUntilIdle()
awaitItem().also { state ->
@@ -488,22 +488,22 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
val initialState = initialState()
// First change the join rule to public
- initialState.eventSink(ConfigureRoomEvents.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
+ initialState.eventSink(ConfigureRoomEvent.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
assertThat(awaitItem().config.visibilityState).isInstanceOf(RoomVisibilityState.Public::class.java)
// Then check changing the parent space resets it to private
// (via LaunchedEffect fallback since Public is not in availableJoinRules for non-public parent)
- initialState.eventSink(ConfigureRoomEvents.SetParentSpace(aSpaceRoom()))
+ initialState.eventSink(ConfigureRoomEvent.SetParentSpace(aSpaceRoom()))
skipItems(1) // Skip intermediate state
assertThat(awaitItem().config.visibilityState).isEqualTo(RoomVisibilityState.Private(JoinRuleItem.PrivateVisibility.Private))
// If we change the join rule back to public
- initialState.eventSink(ConfigureRoomEvents.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
+ initialState.eventSink(ConfigureRoomEvent.JoinRuleChanged(JoinRuleItem.PublicVisibility.Public))
skipItems(1) // Skip intermediate state (Public is still invalid)
assertThat(awaitItem().config.visibilityState).isEqualTo(RoomVisibilityState.Private(JoinRuleItem.PrivateVisibility.Private))
// Then remove the parent space, the join rule stays private
- initialState.eventSink(ConfigureRoomEvents.SetParentSpace(null))
+ initialState.eventSink(ConfigureRoomEvent.SetParentSpace(null))
assertThat(awaitItem().config.visibilityState).isEqualTo(RoomVisibilityState.Private(JoinRuleItem.PrivateVisibility.Private))
}
}
@@ -514,7 +514,7 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
presenter.test {
val initialState = initialState()
- initialState.eventSink(ConfigureRoomEvents.SetParentSpace(aSpaceRoom()))
+ initialState.eventSink(ConfigureRoomEvent.SetParentSpace(aSpaceRoom()))
assertThat(awaitError())
}
@@ -534,8 +534,8 @@ class ConfigureRoomPresenterTest : RobolectricTest() {
presenter.test {
val initialState = initialState()
- initialState.eventSink(ConfigureRoomEvents.JoinRuleChanged(JoinRuleItem.PrivateVisibility.Private))
- initialState.eventSink(ConfigureRoomEvents.CreateRoom)
+ initialState.eventSink(ConfigureRoomEvent.JoinRuleChanged(JoinRuleItem.PrivateVisibility.Private))
+ initialState.eventSink(ConfigureRoomEvent.CreateRoom)
assertThat(awaitItem().createRoomAction.isLoading()).isTrue()
assertThat(awaitItem().createRoomAction.isSuccess()).isTrue()
diff --git a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationEvents.kt b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationEvent.kt
similarity index 76%
rename from features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationEvents.kt
rename to features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationEvent.kt
index 5ceb97b232..cc1f5093fd 100644
--- a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationEvents.kt
+++ b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationEvent.kt
@@ -8,9 +8,9 @@
package io.element.android.features.logout.impl
-sealed interface AccountDeactivationEvents {
- data class SetEraseData(val eraseData: Boolean) : AccountDeactivationEvents
- data class SetPassword(val password: String) : AccountDeactivationEvents
- data class DeactivateAccount(val isRetry: Boolean) : AccountDeactivationEvents
- data object CloseDialogs : AccountDeactivationEvents
+sealed interface AccountDeactivationEvent {
+ data class SetEraseData(val eraseData: Boolean) : AccountDeactivationEvent
+ data class SetPassword(val password: String) : AccountDeactivationEvent
+ data class DeactivateAccount(val isRetry: Boolean) : AccountDeactivationEvent
+ data object CloseDialogs : AccountDeactivationEvent
}
diff --git a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationPresenter.kt b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationPresenter.kt
index eaeacd022c..11e658aa7f 100644
--- a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationPresenter.kt
+++ b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationPresenter.kt
@@ -34,19 +34,19 @@ class AccountDeactivationPresenter(
val formState = remember { mutableStateOf(DeactivateFormState.Default) }
- fun handleEvent(event: AccountDeactivationEvents) {
+ fun handleEvent(event: AccountDeactivationEvent) {
when (event) {
- is AccountDeactivationEvents.SetEraseData -> {
+ is AccountDeactivationEvent.SetEraseData -> {
updateFormState(formState) {
copy(eraseData = event.eraseData)
}
}
- is AccountDeactivationEvents.SetPassword -> {
+ is AccountDeactivationEvent.SetPassword -> {
updateFormState(formState) {
copy(password = event.password)
}
}
- is AccountDeactivationEvents.DeactivateAccount ->
+ is AccountDeactivationEvent.DeactivateAccount ->
if (action.value.isConfirming() || event.isRetry) {
localCoroutineScope.deactivateAccount(
formState = formState.value,
@@ -55,7 +55,7 @@ class AccountDeactivationPresenter(
} else {
action.value = AsyncAction.ConfirmingNoParams
}
- AccountDeactivationEvents.CloseDialogs -> {
+ AccountDeactivationEvent.CloseDialogs -> {
action.value = AsyncAction.Uninitialized
}
}
diff --git a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationState.kt b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationState.kt
index ca9751efcc..ebf9fec3c4 100644
--- a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationState.kt
+++ b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationState.kt
@@ -15,7 +15,7 @@ import kotlinx.parcelize.Parcelize
data class AccountDeactivationState(
val deactivateFormState: DeactivateFormState,
val accountDeactivationAction: AsyncAction,
- val eventSink: (AccountDeactivationEvents) -> Unit,
+ val eventSink: (AccountDeactivationEvent) -> Unit,
) {
val submitEnabled: Boolean
get() = accountDeactivationAction is AsyncAction.Uninitialized &&
diff --git a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationStatePreviewParam.kt b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationStatePreviewParam.kt
index bd86af9572..b5ab948b05 100644
--- a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationStatePreviewParam.kt
+++ b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationStatePreviewParam.kt
@@ -45,7 +45,7 @@ internal fun aDeactivateFormState(
internal fun anAccountDeactivationState(
deactivateFormState: DeactivateFormState = aDeactivateFormState(),
accountDeactivationAction: AsyncAction = AsyncAction.Uninitialized,
- eventSink: (AccountDeactivationEvents) -> Unit = {},
+ eventSink: (AccountDeactivationEvent) -> Unit = {},
) = AccountDeactivationState(
deactivateFormState = deactivateFormState,
accountDeactivationAction = accountDeactivationAction,
diff --git a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationView.kt b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationView.kt
index eb6b401667..d86eae41ff 100644
--- a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationView.kt
+++ b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationView.kt
@@ -102,14 +102,14 @@ fun AccountDeactivationView(
Content(
state = state,
onSubmitClick = {
- eventSink(AccountDeactivationEvents.DeactivateAccount(isRetry = false))
+ eventSink(AccountDeactivationEvent.DeactivateAccount(isRetry = false))
}
)
Spacer(modifier = Modifier.height(32.dp))
Buttons(
state = state,
onSubmitClick = {
- eventSink(AccountDeactivationEvents.DeactivateAccount(isRetry = false))
+ eventSink(AccountDeactivationEvent.DeactivateAccount(isRetry = false))
}
)
}
@@ -117,13 +117,13 @@ fun AccountDeactivationView(
AccountDeactivationActionDialog(
state.accountDeactivationAction,
onConfirmClick = {
- eventSink(AccountDeactivationEvents.DeactivateAccount(isRetry = false))
+ eventSink(AccountDeactivationEvent.DeactivateAccount(isRetry = false))
},
onRetryClick = {
- eventSink(AccountDeactivationEvents.DeactivateAccount(isRetry = true))
+ eventSink(AccountDeactivationEvent.DeactivateAccount(isRetry = true))
},
onDismissDialog = {
- eventSink(AccountDeactivationEvents.CloseDialogs)
+ eventSink(AccountDeactivationEvent.CloseDialogs)
},
)
}
@@ -239,7 +239,7 @@ private fun Content(
headline = stringResource(R.string.screen_deactivate_account_delete_all_messages),
value = eraseData,
onChange = {
- eventSink(AccountDeactivationEvents.SetEraseData(it))
+ eventSink(AccountDeactivationEvent.SetEraseData(it))
},
enabled = !isLoading,
)
@@ -275,7 +275,7 @@ private fun Content(
onValueChange = {
val sanitized = it.sanitize()
passwordFieldState = sanitized
- eventSink(AccountDeactivationEvents.SetPassword(sanitized))
+ eventSink(AccountDeactivationEvent.SetPassword(sanitized))
},
placeholder = stringResource(CommonStrings.common_password),
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
diff --git a/features/deactivation/impl/src/test/kotlin/io/element/android/features/logout/impl/AccountDeactivationPresenterTest.kt b/features/deactivation/impl/src/test/kotlin/io/element/android/features/logout/impl/AccountDeactivationPresenterTest.kt
index ee7f8e470d..d6402c2f59 100644
--- a/features/deactivation/impl/src/test/kotlin/io/element/android/features/logout/impl/AccountDeactivationPresenterTest.kt
+++ b/features/deactivation/impl/src/test/kotlin/io/element/android/features/logout/impl/AccountDeactivationPresenterTest.kt
@@ -47,11 +47,11 @@ class AccountDeactivationPresenterTest {
}.test {
val initialState = awaitItem()
assertThat(initialState.deactivateFormState).isEqualTo(DeactivateFormState.Default)
- initialState.eventSink(AccountDeactivationEvents.SetEraseData(true))
+ initialState.eventSink(AccountDeactivationEvent.SetEraseData(true))
val updatedState = awaitItem()
assertThat(updatedState.deactivateFormState).isEqualTo(DeactivateFormState.Default.copy(eraseData = true))
assertThat(updatedState.submitEnabled).isFalse()
- updatedState.eventSink(AccountDeactivationEvents.SetPassword("password"))
+ updatedState.eventSink(AccountDeactivationEvent.SetPassword("password"))
val updatedState2 = awaitItem()
assertThat(updatedState2.deactivateFormState).isEqualTo(DeactivateFormState(password = "password", eraseData = true))
assertThat(updatedState2.submitEnabled).isTrue()
@@ -71,12 +71,12 @@ class AccountDeactivationPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
- initialState.eventSink(AccountDeactivationEvents.SetPassword("password"))
+ initialState.eventSink(AccountDeactivationEvent.SetPassword("password"))
skipItems(1)
- initialState.eventSink(AccountDeactivationEvents.DeactivateAccount(isRetry = false))
+ initialState.eventSink(AccountDeactivationEvent.DeactivateAccount(isRetry = false))
val updatedState = awaitItem()
assertThat(updatedState.accountDeactivationAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- updatedState.eventSink(AccountDeactivationEvents.DeactivateAccount(isRetry = false))
+ updatedState.eventSink(AccountDeactivationEvent.DeactivateAccount(isRetry = false))
val updatedState2 = awaitItem()
assertThat(updatedState2.accountDeactivationAction).isEqualTo(AsyncAction.Loading)
val finalState = awaitItem()
@@ -98,20 +98,20 @@ class AccountDeactivationPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
- initialState.eventSink(AccountDeactivationEvents.SetPassword("password"))
- initialState.eventSink(AccountDeactivationEvents.SetEraseData(true))
+ initialState.eventSink(AccountDeactivationEvent.SetPassword("password"))
+ initialState.eventSink(AccountDeactivationEvent.SetEraseData(true))
skipItems(2)
- initialState.eventSink(AccountDeactivationEvents.DeactivateAccount(isRetry = false))
+ initialState.eventSink(AccountDeactivationEvent.DeactivateAccount(isRetry = false))
val updatedState = awaitItem()
assertThat(updatedState.accountDeactivationAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- updatedState.eventSink(AccountDeactivationEvents.DeactivateAccount(isRetry = false))
+ updatedState.eventSink(AccountDeactivationEvent.DeactivateAccount(isRetry = false))
val updatedState2 = awaitItem()
assertThat(updatedState2.accountDeactivationAction).isEqualTo(AsyncAction.Loading)
val finalState = awaitItem()
assertThat(finalState.accountDeactivationAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
recorder.assertions().isCalledOnce().with(value("password"), value(true))
// Retry
- finalState.eventSink(AccountDeactivationEvents.DeactivateAccount(isRetry = true))
+ finalState.eventSink(AccountDeactivationEvent.DeactivateAccount(isRetry = true))
val finalState2 = awaitItem()
assertThat(finalState2.accountDeactivationAction).isEqualTo(AsyncAction.Loading)
assertThat(awaitItem().accountDeactivationAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
@@ -131,20 +131,20 @@ class AccountDeactivationPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
- initialState.eventSink(AccountDeactivationEvents.SetPassword("password"))
- initialState.eventSink(AccountDeactivationEvents.SetEraseData(true))
+ initialState.eventSink(AccountDeactivationEvent.SetPassword("password"))
+ initialState.eventSink(AccountDeactivationEvent.SetEraseData(true))
skipItems(2)
- initialState.eventSink(AccountDeactivationEvents.DeactivateAccount(isRetry = false))
+ initialState.eventSink(AccountDeactivationEvent.DeactivateAccount(isRetry = false))
val updatedState = awaitItem()
assertThat(updatedState.accountDeactivationAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- updatedState.eventSink(AccountDeactivationEvents.DeactivateAccount(isRetry = false))
+ updatedState.eventSink(AccountDeactivationEvent.DeactivateAccount(isRetry = false))
val updatedState2 = awaitItem()
assertThat(updatedState2.accountDeactivationAction).isEqualTo(AsyncAction.Loading)
val finalState = awaitItem()
assertThat(finalState.accountDeactivationAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
recorder.assertions().isCalledOnce().with(value("password"), value(true))
// Cancel
- finalState.eventSink(AccountDeactivationEvents.CloseDialogs)
+ finalState.eventSink(AccountDeactivationEvent.CloseDialogs)
val finalState2 = awaitItem()
assertThat(finalState2.accountDeactivationAction).isEqualTo(AsyncAction.Uninitialized)
}
diff --git a/features/deactivation/impl/src/test/kotlin/io/element/android/features/logout/impl/AccountDeactivationViewTest.kt b/features/deactivation/impl/src/test/kotlin/io/element/android/features/logout/impl/AccountDeactivationViewTest.kt
index caf4c0384f..5c650fea9d 100644
--- a/features/deactivation/impl/src/test/kotlin/io/element/android/features/logout/impl/AccountDeactivationViewTest.kt
+++ b/features/deactivation/impl/src/test/kotlin/io/element/android/features/logout/impl/AccountDeactivationViewTest.kt
@@ -35,7 +35,7 @@ import org.robolectric.annotation.Config
class AccountDeactivationViewTest : RobolectricTest() {
@Test
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce {
setAccountDeactivationView(
state = anAccountDeactivationState(eventSink = eventsRecorder),
@@ -48,7 +48,7 @@ class AccountDeactivationViewTest : RobolectricTest() {
@Config(qualifiers = "h1024dp")
@Test
fun `clicking on Deactivate emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setAccountDeactivationView(
state = anAccountDeactivationState(
deactivateFormState = aDeactivateFormState(
@@ -58,12 +58,12 @@ class AccountDeactivationViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_delete)
- eventsRecorder.assertSingle(AccountDeactivationEvents.DeactivateAccount(false))
+ eventsRecorder.assertSingle(AccountDeactivationEvent.DeactivateAccount(false))
}
@Test
fun `clicking on Deactivate on the confirmation dialog emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setAccountDeactivationView(
state = anAccountDeactivationState(
deactivateFormState = aDeactivateFormState(
@@ -74,12 +74,12 @@ class AccountDeactivationViewTest : RobolectricTest() {
),
)
pressTag(TestTags.dialogPositive.value)
- eventsRecorder.assertSingle(AccountDeactivationEvents.DeactivateAccount(false))
+ eventsRecorder.assertSingle(AccountDeactivationEvent.DeactivateAccount(false))
}
@Test
fun `clicking on retry on the confirmation dialog emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setAccountDeactivationView(
state = anAccountDeactivationState(
deactivateFormState = aDeactivateFormState(
@@ -90,24 +90,24 @@ class AccountDeactivationViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_retry)
- eventsRecorder.assertSingle(AccountDeactivationEvents.DeactivateAccount(true))
+ eventsRecorder.assertSingle(AccountDeactivationEvent.DeactivateAccount(true))
}
@Test
fun `switching on the erase all switch emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setAccountDeactivationView(
state = anAccountDeactivationState(
eventSink = eventsRecorder,
),
)
clickOn(R.string.screen_deactivate_account_delete_all_messages)
- eventsRecorder.assertSingle(AccountDeactivationEvents.SetEraseData(true))
+ eventsRecorder.assertSingle(AccountDeactivationEvent.SetEraseData(true))
}
@Test
fun `switching off the erase all switch emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setAccountDeactivationView(
state = anAccountDeactivationState(
deactivateFormState = aDeactivateFormState(
@@ -117,13 +117,13 @@ class AccountDeactivationViewTest : RobolectricTest() {
),
)
clickOn(R.string.screen_deactivate_account_delete_all_messages)
- eventsRecorder.assertSingle(AccountDeactivationEvents.SetEraseData(false))
+ eventsRecorder.assertSingle(AccountDeactivationEvent.SetEraseData(false))
}
@Config(qualifiers = "h1024dp")
@Test
fun `typing text in the password field emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setAccountDeactivationView(
state = anAccountDeactivationState(
deactivateFormState = aDeactivateFormState(
@@ -133,7 +133,7 @@ class AccountDeactivationViewTest : RobolectricTest() {
),
)
onNodeWithTag(TestTags.loginPassword.value).performTextInput("A")
- eventsRecorder.assertSingle(AccountDeactivationEvents.SetPassword("A$A_PASSWORD"))
+ eventsRecorder.assertSingle(AccountDeactivationEvent.SetPassword("A$A_PASSWORD"))
}
}
diff --git a/features/enterprise/api/src/main/kotlin/io/element/android/features/enterprise/api/AppStartupHook.kt b/features/enterprise/api/src/main/kotlin/io/element/android/features/enterprise/api/AppStartupHook.kt
new file mode 100644
index 0000000000..15922291f7
--- /dev/null
+++ b/features/enterprise/api/src/main/kotlin/io/element/android/features/enterprise/api/AppStartupHook.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2026 Element Creations Ltd.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
+ * Please see LICENSE files in the repository root for full details.
+ */
+
+package io.element.android.features.enterprise.api
+
+import android.app.Activity
+
+/**
+ * A hook that is called during app startup, from the `MainActivity`.
+ *
+ * Note that the hook is run in the background: it will not block startup of the app.
+ */
+fun interface AppStartupHook {
+ /** @param activity The activity which is active while the app starts (i.e. the `MainActivity`). */
+ suspend fun onAppStartup(activity: Activity)
+}
diff --git a/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesEvents.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesEvent.kt
similarity index 76%
rename from features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesEvents.kt
rename to features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesEvent.kt
index 0161a5d657..9fab72424f 100644
--- a/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesEvents.kt
+++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesEvent.kt
@@ -8,6 +8,6 @@
package io.element.android.features.forward.impl
-sealed interface ForwardMessagesEvents {
- data object ClearError : ForwardMessagesEvents
+sealed interface ForwardMessagesEvent {
+ data object ClearError : ForwardMessagesEvent
}
diff --git a/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenter.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenter.kt
index 1145f294a3..6068866653 100644
--- a/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenter.kt
+++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenter.kt
@@ -48,9 +48,9 @@ class ForwardMessagesPresenter(
@Composable
override fun present(): ForwardMessagesState {
- fun handleEvent(event: ForwardMessagesEvents) {
+ fun handleEvent(event: ForwardMessagesEvent) {
when (event) {
- ForwardMessagesEvents.ClearError -> forwardingActionState.value = AsyncAction.Uninitialized
+ ForwardMessagesEvent.ClearError -> forwardingActionState.value = AsyncAction.Uninitialized
}
}
diff --git a/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesState.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesState.kt
index b1e46adb03..141c1bad38 100644
--- a/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesState.kt
+++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesState.kt
@@ -13,5 +13,5 @@ import io.element.android.libraries.matrix.api.core.RoomId
data class ForwardMessagesState(
val forwardAction: AsyncAction>,
- val eventSink: (ForwardMessagesEvents) -> Unit
+ val eventSink: (ForwardMessagesEvent) -> Unit
)
diff --git a/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesStatePreviewParam.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesStatePreviewParam.kt
index 8ff621c2a6..fc61925fcc 100644
--- a/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesStatePreviewParam.kt
+++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesStatePreviewParam.kt
@@ -32,7 +32,7 @@ open class ForwardMessagesStatePreviewParam : PreviewParameterProvider> = AsyncAction.Uninitialized,
- eventSink: (ForwardMessagesEvents) -> Unit = {}
+ eventSink: (ForwardMessagesEvent) -> Unit = {}
) = ForwardMessagesState(
forwardAction = forwardAction,
eventSink = eventSink
diff --git a/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesView.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesView.kt
index f350c5b516..8c622d8e29 100644
--- a/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesView.kt
+++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesView.kt
@@ -31,7 +31,7 @@ fun ForwardMessagesView(
stringResource(id = CommonStrings.error_unknown)
},
onErrorDismiss = {
- state.eventSink(ForwardMessagesEvents.ClearError)
+ state.eventSink(ForwardMessagesEvent.ClearError)
},
)
}
diff --git a/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenterTest.kt b/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenterTest.kt
index 5e2f74ccad..0ff3210f2e 100644
--- a/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenterTest.kt
+++ b/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenterTest.kt
@@ -86,7 +86,7 @@ class ForwardMessagesPresenterTest {
val failedForwardState = awaitItem()
assertThat(failedForwardState.forwardAction.isFailure()).isTrue()
// Then clear error
- failedForwardState.eventSink(ForwardMessagesEvents.ClearError)
+ failedForwardState.eventSink(ForwardMessagesEvent.ClearError)
assertThat(awaitItem().forwardAction.isUninitialized()).isTrue()
forwardEventLambda.assertions().isCalledOnce()
}
diff --git a/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesViewTest.kt b/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesViewTest.kt
index a73478479e..3302e3430f 100644
--- a/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesViewTest.kt
+++ b/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesViewTest.kt
@@ -29,7 +29,7 @@ import org.junit.Test
class ForwardMessagesViewTest : RobolectricTest() {
@Test
fun `cancel error emits the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setForwardMessagesView(
aForwardMessagesState(
forwardAction = AsyncAction.Failure(AN_EXCEPTION),
@@ -37,13 +37,13 @@ class ForwardMessagesViewTest : RobolectricTest() {
),
)
pressTag(TestTags.dialogPositive.value)
- eventsRecorder.assertSingle(ForwardMessagesEvents.ClearError)
+ eventsRecorder.assertSingle(ForwardMessagesEvent.ClearError)
}
@Test
fun `success invokes onForwardSuccess`() = runAndroidComposeUiTest {
val data = listOf(A_ROOM_ID)
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnceWithParam?>(data) { callback ->
setForwardMessagesView(
aForwardMessagesState(
diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInEvents.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInEvent.kt
similarity index 65%
rename from features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInEvents.kt
rename to features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInEvent.kt
index e0bd5acf43..3ce3b5b2cf 100644
--- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInEvents.kt
+++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInEvent.kt
@@ -8,7 +8,7 @@
package io.element.android.features.ftue.impl.notifications
-sealed interface NotificationsOptInEvents {
- data object ContinueClicked : NotificationsOptInEvents
- data object NotNowClicked : NotificationsOptInEvents
+sealed interface NotificationsOptInEvent {
+ data object ContinueClicked : NotificationsOptInEvent
+ data object NotNowClicked : NotificationsOptInEvent
}
diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt
index deb7fc59b9..45365670f7 100644
--- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt
+++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt
@@ -52,16 +52,16 @@ class NotificationsOptInPresenter(
override fun present(): NotificationsOptInState {
val notificationsPermissionsState = postNotificationPermissionsPresenter.present()
- fun handleEvent(event: NotificationsOptInEvents) {
+ fun handleEvent(event: NotificationsOptInEvent) {
when (event) {
- NotificationsOptInEvents.ContinueClicked -> {
+ NotificationsOptInEvent.ContinueClicked -> {
if (notificationsPermissionsState.permissionGranted) {
callback.onNotificationsOptInFinished()
} else {
notificationsPermissionsState.eventSink(PermissionsEvent.RequestPermissions)
}
}
- NotificationsOptInEvents.NotNowClicked -> {
+ NotificationsOptInEvent.NotNowClicked -> {
if (buildVersionSdkIntProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU)) {
appCoroutineScope.setPermissionDenied()
}
diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInState.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInState.kt
index d12cec0778..cff99ab6df 100644
--- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInState.kt
+++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInState.kt
@@ -12,5 +12,5 @@ import io.element.android.libraries.permissions.api.PermissionsState
data class NotificationsOptInState(
val notificationsPermissionState: PermissionsState,
- val eventSink: (NotificationsOptInEvents) -> Unit
+ val eventSink: (NotificationsOptInEvent) -> Unit
)
diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt
index e2eabe8f2b..e2db8ce4b7 100644
--- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt
+++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt
@@ -86,14 +86,14 @@ private fun NotificationsOptInFooter(state: NotificationsOptInState) {
modifier = Modifier.fillMaxWidth(),
text = stringResource(CommonStrings.action_ok),
onClick = {
- state.eventSink(NotificationsOptInEvents.ContinueClicked)
+ state.eventSink(NotificationsOptInEvent.ContinueClicked)
}
)
TextButton(
modifier = Modifier.fillMaxWidth(),
text = stringResource(CommonStrings.action_not_now),
onClick = {
- state.eventSink(NotificationsOptInEvents.NotNowClicked)
+ state.eventSink(NotificationsOptInEvent.NotNowClicked)
}
)
}
diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModePresenter.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModePresenter.kt
index 2e37cbe8a5..f19c323d52 100644
--- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModePresenter.kt
+++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModePresenter.kt
@@ -15,7 +15,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import dev.zacsweers.metro.Inject
-import io.element.android.features.logout.api.direct.DirectLogoutEvents
+import io.element.android.features.logout.api.direct.DirectLogoutEvent
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
@@ -67,7 +67,7 @@ class ChooseSelfVerificationModePresenter(
fun handleEvent(event: ChooseSelfVerificationModeEvent) {
when (event) {
- ChooseSelfVerificationModeEvent.SignOut -> directLogoutState.eventSink(DirectLogoutEvents.Logout(ignoreSdkError = false))
+ ChooseSelfVerificationModeEvent.SignOut -> directLogoutState.eventSink(DirectLogoutEvent.Logout(ignoreSdkError = false))
}
}
diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTest.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTest.kt
index 32d68dd1e1..a456d9f373 100644
--- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTest.kt
+++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenterTest.kt
@@ -55,7 +55,7 @@ class NotificationsOptInPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
- initialState.eventSink(NotificationsOptInEvents.ContinueClicked)
+ initialState.eventSink(NotificationsOptInEvent.ContinueClicked)
assertThat(awaitItem().notificationsPermissionState.showDialog).isTrue()
}
}
@@ -70,7 +70,7 @@ class NotificationsOptInPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
- initialState.eventSink(NotificationsOptInEvents.ContinueClicked)
+ initialState.eventSink(NotificationsOptInEvent.ContinueClicked)
assertThat(isFinished).isTrue()
}
}
@@ -86,7 +86,7 @@ class NotificationsOptInPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
- initialState.eventSink(NotificationsOptInEvents.NotNowClicked)
+ initialState.eventSink(NotificationsOptInEvent.NotNowClicked)
assertThat(isFinished).isTrue()
}
}
@@ -105,7 +105,7 @@ class NotificationsOptInPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
- initialState.eventSink(NotificationsOptInEvents.NotNowClicked)
+ initialState.eventSink(NotificationsOptInEvent.NotNowClicked)
// Allow background coroutines to run
runCurrent()
diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModePresenterTest.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModePresenterTest.kt
index 697c51f776..8ceb683993 100644
--- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModePresenterTest.kt
+++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSessionVerificationModePresenterTest.kt
@@ -9,7 +9,7 @@
package io.element.android.features.ftue.impl.sessionverification.choosemode
import com.google.common.truth.Truth.assertThat
-import io.element.android.features.logout.api.direct.DirectLogoutEvents
+import io.element.android.features.logout.api.direct.DirectLogoutEvent
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.features.logout.api.direct.aDirectLogoutState
import io.element.android.libraries.architecture.AsyncData
@@ -112,7 +112,7 @@ class ChooseSessionVerificationModePresenterTest {
@Test
fun `sing out action triggers a direct logout`() = runTest {
- val logoutEventRecorder = lambdaRecorder {}
+ val logoutEventRecorder = lambdaRecorder {}
val logoutPresenter = Presenter {
aDirectLogoutState(eventSink = logoutEventRecorder)
}
@@ -121,7 +121,7 @@ class ChooseSessionVerificationModePresenterTest {
val initial = awaitItem()
initial.eventSink(ChooseSelfVerificationModeEvent.SignOut)
logoutEventRecorder.assertions().isCalledOnce()
- .with(value(DirectLogoutEvents.Logout(ignoreSdkError = false)))
+ .with(value(DirectLogoutEvent.Logout(ignoreSdkError = false)))
}
}
diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/BatteryOptimizationBanner.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/BatteryOptimizationBanner.kt
index c6a9480bc9..95826665fe 100644
--- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/BatteryOptimizationBanner.kt
+++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/BatteryOptimizationBanner.kt
@@ -16,7 +16,7 @@ import io.element.android.libraries.designsystem.components.Announcement
import io.element.android.libraries.designsystem.components.AnnouncementType
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
-import io.element.android.libraries.push.api.battery.BatteryOptimizationEvents
+import io.element.android.libraries.push.api.battery.BatteryOptimizationEvent
import io.element.android.libraries.push.api.battery.BatteryOptimizationState
import io.element.android.libraries.push.api.battery.aBatteryOptimizationState
@@ -31,8 +31,8 @@ internal fun BatteryOptimizationBanner(
description = stringResource(R.string.banner_battery_optimization_content_android),
type = AnnouncementType.Actionable(
actionText = stringResource(R.string.banner_battery_optimization_submit_android),
- onActionClick = { state.eventSink(BatteryOptimizationEvents.RequestDisableOptimizations) },
- onDismissClick = { state.eventSink(BatteryOptimizationEvents.Dismiss) },
+ onActionClick = { state.eventSink(BatteryOptimizationEvent.RequestDisableOptimizations) },
+ onDismissClick = { state.eventSink(BatteryOptimizationEvent.Dismiss) },
),
)
}
diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/FullScreenIntentPermissionBanner.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/FullScreenIntentPermissionBanner.kt
index 92a5d8dbaa..f2826415d2 100644
--- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/FullScreenIntentPermissionBanner.kt
+++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/FullScreenIntentPermissionBanner.kt
@@ -16,7 +16,7 @@ import io.element.android.libraries.designsystem.components.Announcement
import io.element.android.libraries.designsystem.components.AnnouncementType
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
-import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsEvents
+import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsEvent
import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState
import io.element.android.libraries.fullscreenintent.api.aFullScreenIntentPermissionsState
import io.element.android.libraries.ui.strings.CommonStrings
@@ -31,8 +31,8 @@ fun FullScreenIntentPermissionBanner(
description = stringResource(R.string.full_screen_intent_banner_message),
type = AnnouncementType.Actionable(
actionText = stringResource(CommonStrings.action_continue),
- onDismissClick = { state.eventSink(FullScreenIntentPermissionsEvents.Dismiss) },
- onActionClick = { state.eventSink(FullScreenIntentPermissionsEvents.OpenSettings) },
+ onDismissClick = { state.eventSink(FullScreenIntentPermissionsEvent.Dismiss) },
+ onActionClick = { state.eventSink(FullScreenIntentPermissionsEvent.OpenSettings) },
),
modifier = modifier.roomListBannerPadding(),
)
diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt
index 63d28dca21..9f4a2403f7 100644
--- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt
+++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt
@@ -53,8 +53,6 @@ import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.semantics.heading
-import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
@@ -80,7 +78,7 @@ import io.element.android.libraries.designsystem.modifiers.backgroundVerticalGra
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.preview.USER_NAME_ALICE
-import io.element.android.libraries.designsystem.theme.aliasScreenTitle
+import io.element.android.libraries.designsystem.text.AdaptativeTitle
import io.element.android.libraries.designsystem.theme.components.DropdownMenu
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
import io.element.android.libraries.designsystem.theme.components.Icon
@@ -141,15 +139,21 @@ fun HomeTopBar(
else -> stringResource(selectedNavigationItem.labelRes)
}
}
- HomeNavigationBarItem.Spaces -> stringResource(selectedNavigationItem.labelRes)
+ HomeNavigationBarItem.Spaces -> null
+ }
+ displayTitle?.let {
+ val style = when (spaceFiltersState) {
+ // Space name
+ is SpaceFiltersState.Selected -> ElementTheme.typography.fontHeadingSmMedium
+ // "Chats"
+ else -> ElementTheme.typography.fontHeadingLgBold
+ }
+ AdaptativeTitle(
+ title = displayTitle,
+ style = style,
+ twoLinesStyle = ElementTheme.typography.fontHeadingSmMedium,
+ )
}
- Text(
- modifier = Modifier.semantics {
- heading()
- },
- style = ElementTheme.typography.aliasScreenTitle,
- text = displayTitle,
- )
},
navigationIcon = {
NavigationIcon(
@@ -179,7 +183,9 @@ fun HomeTopBar(
TopAppBarScrollBehaviorLayout(scrollBehavior = scrollBehavior) {
RoomListFiltersView(
state = filtersState,
- modifier = Modifier.padding(bottom = 16.dp).padding(contentPadding)
+ modifier = Modifier
+ .padding(bottom = 16.dp)
+ .padding(contentPadding)
)
}
}
@@ -348,45 +354,45 @@ private fun AccountIcon(
),
contentAlignment = Alignment.Center,
) {
- val avatarData by remember(matrixUser) {
- derivedStateOf {
- matrixUser.getAvatarData(size = AvatarSize.CurrentUserTopBar)
- }
+ val avatarData by remember(matrixUser) {
+ derivedStateOf {
+ matrixUser.getAvatarData(size = AvatarSize.CurrentUserTopBar)
}
- val statusEmoji = matrixUser.displayedStatus?.toEmojiText()
- val avatarModifier = if (statusEmoji != null) {
- Modifier.eraseStatusEmojiBackground(
- parentSize = AvatarSize.CurrentUserTopBar.dp,
- layoutDirection = LocalLayoutDirection.current,
- )
- } else {
- Modifier
- }
- Avatar(
- avatarData = avatarData,
- avatarType = AvatarType.User,
- modifier = avatarModifier,
- contentDescription = if (isCurrentAccount) {
- if (showAvatarIndicator) {
- stringResource(CommonStrings.a11y_settings_with_required_action)
- } else {
- stringResource(CommonStrings.common_settings)
- }
- } else {
- null
- },
+ }
+ val statusEmoji = matrixUser.displayedStatus?.toEmojiText()
+ val avatarModifier = if (statusEmoji != null) {
+ Modifier.eraseStatusEmojiBackground(
+ parentSize = AvatarSize.CurrentUserTopBar.dp,
+ layoutDirection = LocalLayoutDirection.current,
)
- if (statusEmoji != null) {
- StatusEmojiBadge(
- emoji = statusEmoji,
- modifier = Modifier.align(Alignment.BottomEnd),
- )
- }
- if (showAvatarIndicator) {
- RedIndicatorAtom(
- modifier = Modifier.align(Alignment.TopEnd)
- )
- }
+ } else {
+ Modifier
+ }
+ Avatar(
+ avatarData = avatarData,
+ avatarType = AvatarType.User,
+ modifier = avatarModifier,
+ contentDescription = if (isCurrentAccount) {
+ if (showAvatarIndicator) {
+ stringResource(CommonStrings.a11y_settings_with_required_action)
+ } else {
+ stringResource(CommonStrings.common_settings)
+ }
+ } else {
+ null
+ },
+ )
+ if (statusEmoji != null) {
+ StatusEmojiBadge(
+ emoji = statusEmoji,
+ modifier = Modifier.align(Alignment.BottomEnd),
+ )
+ }
+ if (showAvatarIndicator) {
+ RedIndicatorAtom(
+ modifier = Modifier.align(Alignment.TopEnd)
+ )
+ }
}
}
diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt
index 96e9f9344b..ba3e8592b6 100644
--- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt
+++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt
@@ -19,6 +19,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter
import io.element.android.libraries.matrix.api.room.CallIntentConsensus
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
+import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.roomlist.LatestEventValue
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.ui.model.dmUserStatus
@@ -47,7 +48,7 @@ class RoomListRoomSummaryFactory(
mode = DateFormatterMode.TimeOrDate,
useRelative = true,
),
- latestEvent = computeLatestEvent(roomSummary.latestEvent, roomInfo.isDm),
+ latestEvent = computeLatestEvent(roomSummary.latestEvent, roomInfo.hasOnlyTwoMembers()),
avatarData = avatarData,
userDefinedNotificationMode = roomInfo.userDefinedNotificationMode,
hasRoomCall = roomInfo.hasRoomCall,
@@ -81,6 +82,10 @@ class RoomListRoomSummaryFactory(
)
}
+ private fun RoomInfo.hasOnlyTwoMembers(): Boolean {
+ return isDm || activeMembersCount <= 2
+ }
+
private fun computeLatestEvent(latestEvent: LatestEventValue, dm: Boolean): LatestEvent {
return when (latestEvent) {
is LatestEventValue.None -> {
diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt
index 1c21177988..546092ede6 100644
--- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt
+++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt
@@ -37,8 +37,8 @@ import io.element.android.features.home.impl.spacefilters.SpaceFiltersState
import io.element.android.features.home.impl.spacefilters.into
import io.element.android.features.home.impl.spacefilters.selectedFilter
import io.element.android.features.invite.api.SeenInvitesStore
-import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents.AcceptInvite
-import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents.DeclineInvite
+import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvent.AcceptInvite
+import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvent.DeclineInvite
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.leaveroom.api.LeaveRoomEvent
import io.element.android.features.leaveroom.api.LeaveRoomState
diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/GlobalSearchEvent.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/GlobalSearchEvent.kt
index 76d9147e94..5f8093b1de 100644
--- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/GlobalSearchEvent.kt
+++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/GlobalSearchEvent.kt
@@ -7,9 +7,6 @@
package io.element.android.features.home.impl.search
-import androidx.compose.runtime.Immutable
-
-@Immutable
sealed interface GlobalSearchEvent {
object ClearQuery : GlobalSearchEvent
object ToggleSearchVisibility : GlobalSearchEvent
diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesEvents.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesEvent.kt
similarity index 89%
rename from features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesEvents.kt
rename to features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesEvent.kt
index 88290417dd..0a32da7c09 100644
--- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesEvents.kt
+++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesEvent.kt
@@ -8,4 +8,4 @@
package io.element.android.features.home.impl.spaces
-sealed interface HomeSpacesEvents
+sealed interface HomeSpacesEvent
diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt
index b758a1e593..2e2406be87 100644
--- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt
+++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt
@@ -39,7 +39,7 @@ class HomeSpacesPresenter(
seenInvitesStore.seenRoomIds().map { it.toImmutableSet() }
}.collectAsState(persistentSetOf())
- fun handleEvent(event: HomeSpacesEvents) {
+ fun handleEvent(event: HomeSpacesEvent) {
// when (event) { }
}
diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt
index e93f04291e..e1c8827087 100644
--- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt
+++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt
@@ -19,7 +19,7 @@ data class HomeSpacesState(
val seenSpaceInvites: ImmutableSet,
val hideInvitesAvatar: Boolean,
val canExploreSpaces: Boolean,
- val eventSink: (HomeSpacesEvents) -> Unit,
+ val eventSink: (HomeSpacesEvent) -> Unit,
)
sealed interface CurrentSpace {
diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStatePreviewParam.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStatePreviewParam.kt
index 57b219d302..8d4acae8b7 100644
--- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStatePreviewParam.kt
+++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStatePreviewParam.kt
@@ -43,7 +43,7 @@ internal fun aHomeSpacesState(
seenSpaceInvites: Set = emptySet(),
hideInvitesAvatar: Boolean = false,
canExploreSpaces: Boolean = true,
- eventSink: (HomeSpacesEvents) -> Unit = {},
+ eventSink: (HomeSpacesEvent) -> Unit = {},
) = HomeSpacesState(
space = space,
spaceRooms = spaceRooms.toImmutableList(),
diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt
index 914d08d7f6..f9cf38a1aa 100644
--- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt
+++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesView.kt
@@ -143,7 +143,7 @@ private fun EmptySpaceHomeView(
)
Text(
text = stringResource(CommonStrings.screen_space_list_empty_state_title),
- style = ElementTheme.typography.fontHeadingLgBold,
+ style = ElementTheme.typography.fontHeadingMdBold,
color = ElementTheme.colors.textPrimary,
textAlign = TextAlign.Center,
)
diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt
index 5f307918be..bfd92094a5 100644
--- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt
+++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt
@@ -8,10 +8,36 @@
package io.element.android.features.home.impl.datasource
+import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.dateformatter.api.DateFormatter
import io.element.android.libraries.dateformatter.test.FakeDateFormatter
import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter
import io.element.android.libraries.eventformatter.test.FakeRoomLatestEventFormatter
+import io.element.android.libraries.matrix.test.room.aRoomInfo
+import io.element.android.libraries.matrix.test.room.aRoomSummary
+import org.junit.Test
+
+class RoomListRoomSummaryFactoryTest {
+ @Test
+ fun `a room with two members does not prefix its preview with the sender`() {
+ val formatter = FakeRoomLatestEventFormatter()
+ val factory = aRoomListRoomSummaryFactory(roomLatestEventFormatter = formatter)
+
+ factory.create(aRoomSummary(info = aRoomInfo(isDm = false, activeMembersCount = 2)))
+
+ assertThat(formatter.lastIsDmRoom).isTrue()
+ }
+
+ @Test
+ fun `a room with more than two members prefixes its preview with the sender`() {
+ val formatter = FakeRoomLatestEventFormatter()
+ val factory = aRoomListRoomSummaryFactory(roomLatestEventFormatter = formatter)
+
+ factory.create(aRoomSummary(info = aRoomInfo(isDm = false, activeMembersCount = 3)))
+
+ assertThat(formatter.lastIsDmRoom).isFalse()
+ }
+}
fun aRoomListRoomSummaryFactory(
dateFormatter: DateFormatter = FakeDateFormatter { _, _, _ -> "Today" },
diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt
index d2e33c77c1..9bc8719a8b 100644
--- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt
+++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt
@@ -25,7 +25,7 @@ import io.element.android.features.home.impl.search.aRoomListSearchState
import io.element.android.features.home.impl.spacefilters.SpaceFiltersState
import io.element.android.features.home.impl.spacefilters.aDisabledSpaceFiltersState
import io.element.android.features.invite.api.SeenInvitesStore
-import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
+import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvent
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.invite.api.acceptdecline.anAcceptDeclineInviteState
import io.element.android.features.invite.test.InMemorySeenInvitesStore
@@ -474,7 +474,7 @@ class RoomListPresenterTest {
@Test
fun `present - when a room is invited then accept and decline events are sent to acceptDeclinePresenter`() = runTest {
- val eventSinkRecorder = lambdaRecorder { _: AcceptDeclineInviteEvents -> }
+ val eventSinkRecorder = lambdaRecorder { _: AcceptDeclineInviteEvent -> }
val acceptDeclinePresenter = Presenter {
anAcceptDeclineInviteState(eventSink = eventSinkRecorder)
}
@@ -513,8 +513,8 @@ class RoomListPresenterTest {
assert(eventSinkRecorder)
.isCalledExactly(2)
.withSequence(
- listOf(value(AcceptDeclineInviteEvents.AcceptInvite(inviteData))),
- listOf(value(AcceptDeclineInviteEvents.DeclineInvite(inviteData, blockUser = false, shouldConfirm = false))),
+ listOf(value(AcceptDeclineInviteEvent.AcceptInvite(inviteData))),
+ listOf(value(AcceptDeclineInviteEvent.DeclineInvite(inviteData, blockUser = false, shouldConfirm = false))),
)
}
}
diff --git a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteEvents.kt b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteEvent.kt
similarity index 91%
rename from features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteEvents.kt
rename to features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteEvent.kt
index 5691b19ef7..1bf1ffea8a 100644
--- a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteEvents.kt
+++ b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteEvent.kt
@@ -13,7 +13,7 @@ import io.element.android.features.invite.api.InviteData
/**
* Events sent to the accept/decline invite presenter, from whichever screen is showing the invitation.
*/
-interface AcceptDeclineInviteEvents {
- data class AcceptInvite(val invite: InviteData) : AcceptDeclineInviteEvents
- data class DeclineInvite(val invite: InviteData, val blockUser: Boolean, val shouldConfirm: Boolean) : AcceptDeclineInviteEvents
+interface AcceptDeclineInviteEvent {
+ data class AcceptInvite(val invite: InviteData) : AcceptDeclineInviteEvent
+ data class DeclineInvite(val invite: InviteData, val blockUser: Boolean, val shouldConfirm: Boolean) : AcceptDeclineInviteEvent
}
diff --git a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteState.kt b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteState.kt
index 3bfd0430fe..3e9c549620 100644
--- a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteState.kt
+++ b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteState.kt
@@ -14,5 +14,5 @@ import io.element.android.libraries.matrix.api.core.RoomId
data class AcceptDeclineInviteState(
val acceptAction: AsyncAction,
val declineAction: AsyncAction,
- val eventSink: (AcceptDeclineInviteEvents) -> Unit,
+ val eventSink: (AcceptDeclineInviteEvent) -> Unit,
)
diff --git a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteStatePreviewParam.kt b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteStatePreviewParam.kt
index 18acc11e5e..ceda9542ef 100644
--- a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteStatePreviewParam.kt
+++ b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/acceptdecline/AcceptDeclineInviteStatePreviewParam.kt
@@ -14,7 +14,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
fun anAcceptDeclineInviteState(
acceptAction: AsyncAction = AsyncAction.Uninitialized,
declineAction: AsyncAction = AsyncAction.Uninitialized,
- eventSink: (AcceptDeclineInviteEvents) -> Unit = {},
+ eventSink: (AcceptDeclineInviteEvent) -> Unit = {},
) = AcceptDeclineInviteState(
acceptAction = acceptAction,
declineAction = declineAction,
diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInvitePresenter.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInvitePresenter.kt
index 9be255fe1a..e5ee3d20c7 100644
--- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInvitePresenter.kt
+++ b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInvitePresenter.kt
@@ -15,7 +15,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import dev.zacsweers.metro.Inject
import io.element.android.features.invite.api.InviteData
-import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
+import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvent
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.invite.api.acceptdecline.ConfirmingDeclineInvite
import io.element.android.features.invite.impl.AcceptInvite
@@ -40,13 +40,13 @@ class AcceptDeclineInvitePresenter(
val declinedAction: MutableState> =
remember { mutableStateOf(AsyncAction.Uninitialized) }
- fun handleEvent(event: AcceptDeclineInviteEvents) {
+ fun handleEvent(event: AcceptDeclineInviteEvent) {
when (event) {
- is AcceptDeclineInviteEvents.AcceptInvite -> {
+ is AcceptDeclineInviteEvent.AcceptInvite -> {
localCoroutineScope.acceptInvite(event.invite.roomId, acceptedAction)
}
- is AcceptDeclineInviteEvents.DeclineInvite -> {
+ is AcceptDeclineInviteEvent.DeclineInvite -> {
val inviteData = event.invite
if (event.shouldConfirm) {
declinedAction.value = ConfirmingDeclineInvite(inviteData, event.blockUser)
@@ -58,11 +58,11 @@ class AcceptDeclineInvitePresenter(
)
}
}
- is InternalAcceptDeclineInviteEvents.ClearAcceptActionState -> {
+ is InternalAcceptDeclineInviteEvent.ClearAcceptActionState -> {
acceptedAction.value = AsyncAction.Uninitialized
}
- is InternalAcceptDeclineInviteEvents.ClearDeclineActionState -> {
+ is InternalAcceptDeclineInviteEvent.ClearDeclineActionState -> {
declinedAction.value = AsyncAction.Uninitialized
}
}
diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInviteView.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInviteView.kt
index c3df984604..21c59b1860 100644
--- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInviteView.kt
+++ b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInviteView.kt
@@ -14,7 +14,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.features.invite.api.InviteData
-import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
+import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvent
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.invite.api.acceptdecline.ConfirmingDeclineInvite
import io.element.android.features.invite.impl.AcceptInvite
@@ -37,11 +37,11 @@ fun AcceptDeclineInviteView(
AsyncActionView(
async = state.acceptAction,
onSuccess = { roomId ->
- state.eventSink(InternalAcceptDeclineInviteEvents.ClearAcceptActionState)
+ state.eventSink(InternalAcceptDeclineInviteEvent.ClearAcceptActionState)
onAcceptInviteSuccess(roomId)
},
onErrorDismiss = {
- state.eventSink(InternalAcceptDeclineInviteEvents.ClearAcceptActionState)
+ state.eventSink(InternalAcceptDeclineInviteEvent.ClearAcceptActionState)
},
errorTitle = {
stringResource(CommonStrings.common_something_went_wrong)
@@ -57,11 +57,11 @@ fun AcceptDeclineInviteView(
AsyncActionView(
async = state.declineAction,
onSuccess = { roomId ->
- state.eventSink(InternalAcceptDeclineInviteEvents.ClearDeclineActionState)
+ state.eventSink(InternalAcceptDeclineInviteEvent.ClearDeclineActionState)
onDeclineInviteSuccess(roomId)
},
onErrorDismiss = {
- state.eventSink(InternalAcceptDeclineInviteEvents.ClearDeclineActionState)
+ state.eventSink(InternalAcceptDeclineInviteEvent.ClearDeclineActionState)
},
errorTitle = {
stringResource(CommonStrings.common_something_went_wrong)
@@ -77,7 +77,7 @@ fun AcceptDeclineInviteView(
blockUser = confirming.blockUser,
onConfirmClick = {
state.eventSink(
- AcceptDeclineInviteEvents.DeclineInvite(
+ AcceptDeclineInviteEvent.DeclineInvite(
confirming.inviteData,
blockUser = confirming.blockUser,
shouldConfirm = false
@@ -85,7 +85,7 @@ fun AcceptDeclineInviteView(
)
},
onDismissClick = {
- state.eventSink(InternalAcceptDeclineInviteEvents.ClearDeclineActionState)
+ state.eventSink(InternalAcceptDeclineInviteEvent.ClearDeclineActionState)
}
)
}
diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/InternalAcceptDeclineInviteEvents.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/InternalAcceptDeclineInviteEvent.kt
similarity index 79%
rename from features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/InternalAcceptDeclineInviteEvents.kt
rename to features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/InternalAcceptDeclineInviteEvent.kt
index 765c7055d3..805ed9871e 100644
--- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/InternalAcceptDeclineInviteEvents.kt
+++ b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/acceptdecline/InternalAcceptDeclineInviteEvent.kt
@@ -8,9 +8,9 @@
package io.element.android.features.invite.impl.acceptdecline
-import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
+import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvent
-sealed interface InternalAcceptDeclineInviteEvents : AcceptDeclineInviteEvents {
- data object ClearAcceptActionState : InternalAcceptDeclineInviteEvents
- data object ClearDeclineActionState : InternalAcceptDeclineInviteEvents
+sealed interface InternalAcceptDeclineInviteEvent : AcceptDeclineInviteEvent {
+ data object ClearAcceptActionState : InternalAcceptDeclineInviteEvent
+ data object ClearDeclineActionState : InternalAcceptDeclineInviteEvent
}
diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockEvents.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockEvent.kt
similarity index 57%
rename from features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockEvents.kt
rename to features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockEvent.kt
index 1fc160e530..f31b9d042f 100644
--- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockEvents.kt
+++ b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockEvent.kt
@@ -8,10 +8,10 @@
package io.element.android.features.invite.impl.declineandblock
-sealed interface DeclineAndBlockEvents {
- data class UpdateReportReason(val reason: String) : DeclineAndBlockEvents
- data object ToggleReportRoom : DeclineAndBlockEvents
- data object ToggleBlockUser : DeclineAndBlockEvents
- data object Decline : DeclineAndBlockEvents
- data object ClearDeclineAction : DeclineAndBlockEvents
+sealed interface DeclineAndBlockEvent {
+ data class UpdateReportReason(val reason: String) : DeclineAndBlockEvent
+ data object ToggleReportRoom : DeclineAndBlockEvent
+ data object ToggleBlockUser : DeclineAndBlockEvent
+ data object Decline : DeclineAndBlockEvent
+ data object ClearDeclineAction : DeclineAndBlockEvent
}
diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockPresenter.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockPresenter.kt
index af2a10cbfd..170d003bea 100644
--- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockPresenter.kt
+++ b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockPresenter.kt
@@ -49,13 +49,13 @@ class DeclineAndBlockPresenter(
val coroutineScope = rememberCoroutineScope()
- fun handleEvent(event: DeclineAndBlockEvents) {
+ fun handleEvent(event: DeclineAndBlockEvent) {
when (event) {
- DeclineAndBlockEvents.ClearDeclineAction -> declineAction.value = AsyncAction.Uninitialized
- DeclineAndBlockEvents.Decline -> coroutineScope.decline(reportReason, blockUser, reportRoom, declineAction)
- DeclineAndBlockEvents.ToggleBlockUser -> blockUser = !blockUser
- DeclineAndBlockEvents.ToggleReportRoom -> reportRoom = !reportRoom
- is DeclineAndBlockEvents.UpdateReportReason -> reportReason = event.reason
+ DeclineAndBlockEvent.ClearDeclineAction -> declineAction.value = AsyncAction.Uninitialized
+ DeclineAndBlockEvent.Decline -> coroutineScope.decline(reportReason, blockUser, reportRoom, declineAction)
+ DeclineAndBlockEvent.ToggleBlockUser -> blockUser = !blockUser
+ DeclineAndBlockEvent.ToggleReportRoom -> reportRoom = !reportRoom
+ is DeclineAndBlockEvent.UpdateReportReason -> reportReason = event.reason
}
}
diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockState.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockState.kt
index 7dbbbfd60e..057929ea42 100644
--- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockState.kt
+++ b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockState.kt
@@ -15,7 +15,7 @@ data class DeclineAndBlockState(
val reportReason: String,
val blockUser: Boolean,
val declineAction: AsyncAction,
- val eventSink: (DeclineAndBlockEvents) -> Unit
+ val eventSink: (DeclineAndBlockEvent) -> Unit
) {
val canDecline = blockUser || reportRoom && reportReason.isNotEmpty()
}
diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockStatePreviewParam.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockStatePreviewParam.kt
index 704fc9f045..6690a568dd 100644
--- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockStatePreviewParam.kt
+++ b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockStatePreviewParam.kt
@@ -36,7 +36,7 @@ fun aDeclineAndBlockState(
reportReason: String = "",
blockUser: Boolean = false,
declineAction: AsyncAction = AsyncAction.Uninitialized,
- eventSink: (DeclineAndBlockEvents) -> Unit = {},
+ eventSink: (DeclineAndBlockEvent) -> Unit = {},
) = DeclineAndBlockState(
reportRoom = reportRoom,
reportReason = reportReason,
diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockView.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockView.kt
index c30742de12..eaace62309 100644
--- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockView.kt
+++ b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockView.kt
@@ -56,8 +56,8 @@ fun DeclineAndBlockView(
async = state.declineAction,
onSuccess = { onDeclineSuccess() },
errorMessage = { stringResource(CommonStrings.error_unknown) },
- onRetry = { state.eventSink(DeclineAndBlockEvents.Decline) },
- onErrorDismiss = { state.eventSink(DeclineAndBlockEvents.ClearDeclineAction) }
+ onRetry = { state.eventSink(DeclineAndBlockEvent.Decline) },
+ onErrorDismiss = { state.eventSink(DeclineAndBlockEvent.ClearDeclineAction) }
)
Scaffold(
@@ -89,7 +89,7 @@ fun DeclineAndBlockView(
Text(text = stringResource(R.string.screen_decline_and_block_block_user_option_description))
},
onClick = {
- state.eventSink(DeclineAndBlockEvents.ToggleBlockUser)
+ state.eventSink(DeclineAndBlockEvent.ToggleBlockUser)
},
trailingContent = ListItemContent.Switch(checked = state.blockUser)
)
@@ -104,7 +104,7 @@ fun DeclineAndBlockView(
Text(text = stringResource(R.string.screen_decline_and_block_report_user_option_description))
},
onClick = {
- state.eventSink(DeclineAndBlockEvents.ToggleReportRoom)
+ state.eventSink(DeclineAndBlockEvent.ToggleReportRoom)
},
trailingContent = ListItemContent.Switch(checked = state.reportRoom)
)
@@ -113,7 +113,7 @@ fun DeclineAndBlockView(
Spacer(modifier = Modifier.height(24.dp))
TextField(
value = state.reportReason,
- onValueChange = { state.eventSink(DeclineAndBlockEvents.UpdateReportReason(it)) },
+ onValueChange = { state.eventSink(DeclineAndBlockEvent.UpdateReportReason(it)) },
placeholder = stringResource(R.string.screen_decline_and_block_report_user_reason_placeholder),
minLines = 3,
enabled = !isDeclining,
@@ -132,7 +132,7 @@ fun DeclineAndBlockView(
enabled = !isDeclining && state.canDecline,
onClick = {
focusManager.clearFocus(force = true)
- state.eventSink(DeclineAndBlockEvents.Decline)
+ state.eventSink(DeclineAndBlockEvent.Decline)
},
modifier = Modifier
.fillMaxWidth()
diff --git a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInvitePresenterTest.kt b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInvitePresenterTest.kt
index ba080293f8..15624ba9be 100644
--- a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInvitePresenterTest.kt
+++ b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/acceptdecline/AcceptDeclineInvitePresenterTest.kt
@@ -10,7 +10,7 @@ package io.element.android.features.invite.impl.acceptdecline
import com.google.common.truth.Truth.assertThat
import io.element.android.features.invite.api.InviteData
-import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
+import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvent
import io.element.android.features.invite.api.acceptdecline.ConfirmingDeclineInvite
import io.element.android.features.invite.impl.AcceptInvite
import io.element.android.features.invite.impl.DeclineInvite
@@ -51,13 +51,13 @@ class AcceptDeclineInvitePresenterTest {
val inviteData = anInviteData()
awaitItem().also { state ->
state.eventSink(
- AcceptDeclineInviteEvents.DeclineInvite(inviteData, blockUser = false, shouldConfirm = true)
+ AcceptDeclineInviteEvent.DeclineInvite(inviteData, blockUser = false, shouldConfirm = true)
)
}
awaitItem().also { state ->
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData, false))
state.eventSink(
- InternalAcceptDeclineInviteEvents.ClearDeclineActionState
+ InternalAcceptDeclineInviteEvent.ClearDeclineActionState
)
}
awaitItem().also { state ->
@@ -78,20 +78,20 @@ class AcceptDeclineInvitePresenterTest {
val inviteData = anInviteData()
awaitItem().also { state ->
state.eventSink(
- AcceptDeclineInviteEvents.DeclineInvite(inviteData, blockUser = false, shouldConfirm = true)
+ AcceptDeclineInviteEvent.DeclineInvite(inviteData, blockUser = false, shouldConfirm = true)
)
}
awaitItem().also { state ->
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData, false))
state.eventSink(
- AcceptDeclineInviteEvents.DeclineInvite(inviteData, blockUser = false, shouldConfirm = false)
+ AcceptDeclineInviteEvent.DeclineInvite(inviteData, blockUser = false, shouldConfirm = false)
)
}
assertThat(awaitItem().declineAction.isLoading()).isTrue()
awaitItem().also { state ->
assertThat(state.declineAction).isInstanceOf(AsyncAction.Failure::class.java)
state.eventSink(
- InternalAcceptDeclineInviteEvents.ClearDeclineActionState
+ InternalAcceptDeclineInviteEvent.ClearDeclineActionState
)
}
awaitItem().also { state ->
@@ -114,13 +114,13 @@ class AcceptDeclineInvitePresenterTest {
val inviteData = anInviteData()
awaitItem().also { state ->
state.eventSink(
- AcceptDeclineInviteEvents.DeclineInvite(inviteData, blockUser = false, shouldConfirm = true)
+ AcceptDeclineInviteEvent.DeclineInvite(inviteData, blockUser = false, shouldConfirm = true)
)
}
awaitItem().also { state ->
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData, blockUser = false))
state.eventSink(
- AcceptDeclineInviteEvents.DeclineInvite(inviteData, blockUser = false, shouldConfirm = false)
+ AcceptDeclineInviteEvent.DeclineInvite(inviteData, blockUser = false, shouldConfirm = false)
)
}
assertThat(awaitItem().declineAction.isLoading()).isTrue()
@@ -146,7 +146,7 @@ class AcceptDeclineInvitePresenterTest {
val inviteData = anInviteData()
awaitItem().also { state ->
state.eventSink(
- AcceptDeclineInviteEvents.AcceptInvite(inviteData)
+ AcceptDeclineInviteEvent.AcceptInvite(inviteData)
)
}
awaitItem().also { state ->
@@ -155,7 +155,7 @@ class AcceptDeclineInvitePresenterTest {
awaitItem().also { state ->
assertThat(state.acceptAction).isInstanceOf(AsyncAction.Failure::class.java)
state.eventSink(
- InternalAcceptDeclineInviteEvents.ClearAcceptActionState
+ InternalAcceptDeclineInviteEvent.ClearAcceptActionState
)
}
awaitItem().also { state ->
@@ -178,7 +178,7 @@ class AcceptDeclineInvitePresenterTest {
val inviteData = anInviteData()
awaitItem().also { state ->
state.eventSink(
- AcceptDeclineInviteEvents.AcceptInvite(inviteData)
+ AcceptDeclineInviteEvent.AcceptInvite(inviteData)
)
}
awaitItem().also { state ->
diff --git a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockPresenterTest.kt b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockPresenterTest.kt
index 67c2d55490..61c67c34b3 100644
--- a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockPresenterTest.kt
+++ b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockPresenterTest.kt
@@ -53,21 +53,21 @@ class DeclineAndBlockPresenterTest {
assertThat(state.blockUser).isTrue()
assertThat(state.reportReason).isEmpty()
assertThat(state.canDecline).isTrue()
- state.eventSink(DeclineAndBlockEvents.ToggleBlockUser)
+ state.eventSink(DeclineAndBlockEvent.ToggleBlockUser)
}
awaitItem().also { state ->
assertThat(state.reportRoom).isFalse()
assertThat(state.blockUser).isFalse()
assertThat(state.reportReason).isEmpty()
assertThat(state.canDecline).isFalse()
- state.eventSink(DeclineAndBlockEvents.ToggleReportRoom)
+ state.eventSink(DeclineAndBlockEvent.ToggleReportRoom)
}
awaitItem().also { state ->
assertThat(state.reportRoom).isTrue()
assertThat(state.blockUser).isFalse()
assertThat(state.reportReason).isEmpty()
assertThat(state.canDecline).isFalse()
- state.eventSink(DeclineAndBlockEvents.UpdateReportReason("Spam"))
+ state.eventSink(DeclineAndBlockEvent.UpdateReportReason("Spam"))
}
awaitItem().also { state ->
assertThat(state.reportRoom).isTrue()
@@ -87,7 +87,7 @@ class DeclineAndBlockPresenterTest {
)
presenter.test {
awaitItem().also { state ->
- state.eventSink(DeclineAndBlockEvents.Decline)
+ state.eventSink(DeclineAndBlockEvent.Decline)
}
assertThat(awaitItem().declineAction.isLoading()).isTrue()
awaitItem().also { state ->
@@ -110,12 +110,12 @@ class DeclineAndBlockPresenterTest {
)
presenter.test {
awaitItem().also { state ->
- state.eventSink(DeclineAndBlockEvents.Decline)
+ state.eventSink(DeclineAndBlockEvent.Decline)
}
assertThat(awaitItem().declineAction.isLoading()).isTrue()
awaitItem().also { state ->
assertThat(state.declineAction).isInstanceOf(AsyncAction.Failure::class.java)
- state.eventSink(DeclineAndBlockEvents.ClearDeclineAction)
+ state.eventSink(DeclineAndBlockEvent.ClearDeclineAction)
}
awaitItem().also { state ->
assertThat(state.declineAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
@@ -137,7 +137,7 @@ class DeclineAndBlockPresenterTest {
)
presenter.test {
awaitItem().also { state ->
- state.eventSink(DeclineAndBlockEvents.Decline)
+ state.eventSink(DeclineAndBlockEvent.Decline)
}
assertThat(awaitItem().declineAction.isLoading()).isTrue()
awaitItem().also { state ->
diff --git a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockViewTest.kt b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockViewTest.kt
index 5cfb091e82..d3505ae5b2 100644
--- a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockViewTest.kt
+++ b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/declineandblock/DeclineAndBlockViewTest.kt
@@ -30,7 +30,7 @@ import org.junit.Test
class DeclineAndBlockViewTest : RobolectricTest() {
@Test
fun `clicking on back invoke the expected callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce {
setDeclineAndBlockView(
aDeclineAndBlockState(
@@ -44,7 +44,7 @@ class DeclineAndBlockViewTest : RobolectricTest() {
@Test
fun `a successful decline invokes the expected callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce {
setDeclineAndBlockView(
aDeclineAndBlockState(
@@ -58,7 +58,7 @@ class DeclineAndBlockViewTest : RobolectricTest() {
@Test
fun `clicking on decline when enabled emits the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setDeclineAndBlockView(
aDeclineAndBlockState(
blockUser = true,
@@ -66,12 +66,12 @@ class DeclineAndBlockViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_decline)
- eventsRecorder.assertSingle(DeclineAndBlockEvents.Decline)
+ eventsRecorder.assertSingle(DeclineAndBlockEvent.Decline)
}
@Test
fun `clicking on decline when disabled does not emit event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
setDeclineAndBlockView(
aDeclineAndBlockState(
blockUser = false,
@@ -85,7 +85,7 @@ class DeclineAndBlockViewTest : RobolectricTest() {
@Test
fun `clicking on block option emits the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setDeclineAndBlockView(
aDeclineAndBlockState(
blockUser = true,
@@ -93,12 +93,12 @@ class DeclineAndBlockViewTest : RobolectricTest() {
),
)
clickOn(R.string.screen_decline_and_block_block_user_option_title)
- eventsRecorder.assertSingle(DeclineAndBlockEvents.ToggleBlockUser)
+ eventsRecorder.assertSingle(DeclineAndBlockEvent.ToggleBlockUser)
}
@Test
fun `clicking on report room option emits the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setDeclineAndBlockView(
aDeclineAndBlockState(
reportRoom = true,
@@ -106,12 +106,12 @@ class DeclineAndBlockViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_report_room)
- eventsRecorder.assertSingle(DeclineAndBlockEvents.ToggleReportRoom)
+ eventsRecorder.assertSingle(DeclineAndBlockEvent.ToggleReportRoom)
}
@Test
fun `typing text in the reason field emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setDeclineAndBlockView(
aDeclineAndBlockState(
reportRoom = true,
@@ -120,7 +120,7 @@ class DeclineAndBlockViewTest : RobolectricTest() {
),
)
onNodeWithText("").performTextInput("Spam!")
- eventsRecorder.assertSingle(DeclineAndBlockEvents.UpdateReportReason("Spam!"))
+ eventsRecorder.assertSingle(DeclineAndBlockEvent.UpdateReportReason("Spam!"))
}
}
diff --git a/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleEvents.kt b/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleEvent.kt
similarity index 68%
rename from features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleEvents.kt
rename to features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleEvent.kt
index 9570ab8152..884312da67 100644
--- a/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleEvents.kt
+++ b/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleEvent.kt
@@ -11,8 +11,8 @@ package io.element.android.features.invitepeople.api
/**
* Events the invite people UI sends to its presenter through [InvitePeopleState.eventSink].
*/
-interface InvitePeopleEvents {
- data object SendInvites : InvitePeopleEvents
- data object CloseSearch : InvitePeopleEvents
- data object ClearError : InvitePeopleEvents
+interface InvitePeopleEvent {
+ data object SendInvites : InvitePeopleEvent
+ data object CloseSearch : InvitePeopleEvent
+ data object ClearError : InvitePeopleEvent
}
diff --git a/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleState.kt b/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleState.kt
index 0863ec7212..b35ed22f7e 100644
--- a/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleState.kt
+++ b/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleState.kt
@@ -28,5 +28,5 @@ interface InvitePeopleState {
val createRoomFromDmAction: AsyncAction
/** Where the UI sends its events. */
- val eventSink: (InvitePeopleEvents) -> Unit
+ val eventSink: (InvitePeopleEvent) -> Unit
}
diff --git a/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleStatePreviewParam.kt b/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleStatePreviewParam.kt
index 860efc2771..379d80440e 100644
--- a/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleStatePreviewParam.kt
+++ b/features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeopleStatePreviewParam.kt
@@ -27,7 +27,7 @@ private data class PreviewInvitePeopleState(
override val isSearchActive: Boolean,
override val sendInvitesAction: AsyncAction,
override val createRoomFromDmAction: AsyncAction,
- override val eventSink: (InvitePeopleEvents) -> Unit,
+ override val eventSink: (InvitePeopleEvent) -> Unit,
) : InvitePeopleState
private fun aPreviewInvitePeopleState(
@@ -35,7 +35,7 @@ private fun aPreviewInvitePeopleState(
isSearchActive: Boolean = false,
sendInvitesAction: AsyncAction = AsyncAction.Uninitialized,
createRoomFromDmAction: AsyncAction = AsyncAction.Uninitialized,
- eventSink: (InvitePeopleEvents) -> Unit = {},
+ eventSink: (InvitePeopleEvent) -> Unit = {},
) = PreviewInvitePeopleState(
canInvite = canInvite,
isSearchActive = isSearchActive,
diff --git a/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleEvents.kt b/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleEvent.kt
similarity index 77%
rename from features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleEvents.kt
rename to features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleEvent.kt
index 449d0ce6ac..90d6fef59d 100644
--- a/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleEvents.kt
+++ b/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleEvent.kt
@@ -8,12 +8,12 @@
package io.element.android.features.invitepeople.impl
-import io.element.android.features.invitepeople.api.InvitePeopleEvents
+import io.element.android.features.invitepeople.api.InvitePeopleEvent
import io.element.android.libraries.matrix.api.user.MatrixUser
-sealed interface DefaultInvitePeopleEvents : InvitePeopleEvents {
- data class ToggleUser(val user: MatrixUser) : DefaultInvitePeopleEvents
- data class OnSearchActiveChanged(val active: Boolean) : DefaultInvitePeopleEvents
- data object DismissUnknownUsersModal : DefaultInvitePeopleEvents
- data object RemoveUnknownUsers : DefaultInvitePeopleEvents
+sealed interface DefaultInvitePeopleEvent : InvitePeopleEvent {
+ data class ToggleUser(val user: MatrixUser) : DefaultInvitePeopleEvent
+ data class OnSearchActiveChanged(val active: Boolean) : DefaultInvitePeopleEvent
+ data object DismissUnknownUsersModal : DefaultInvitePeopleEvent
+ data object RemoveUnknownUsers : DefaultInvitePeopleEvent
}
diff --git a/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeoplePresenter.kt b/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeoplePresenter.kt
index 79cd0c83be..dbf5c46291 100644
--- a/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeoplePresenter.kt
+++ b/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeoplePresenter.kt
@@ -24,7 +24,7 @@ import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedFactory
import dev.zacsweers.metro.AssistedInject
import dev.zacsweers.metro.ContributesBinding
-import io.element.android.features.invitepeople.api.InvitePeopleEvents
+import io.element.android.features.invitepeople.api.InvitePeopleEvent
import io.element.android.features.invitepeople.api.InvitePeoplePresenter
import io.element.android.features.invitepeople.api.InvitePeopleState
import io.element.android.libraries.architecture.AsyncAction
@@ -179,26 +179,26 @@ class DefaultInvitePeoplePresenter(
)
}
- fun handleEvent(event: InvitePeopleEvents) {
+ fun handleEvent(event: InvitePeopleEvent) {
when (event) {
// Dedicated `when` for exhaustivity.
- is DefaultInvitePeopleEvents -> when (event) {
- is DefaultInvitePeopleEvents.OnSearchActiveChanged -> {
+ is DefaultInvitePeopleEvent -> when (event) {
+ is DefaultInvitePeopleEvent.OnSearchActiveChanged -> {
searchActive = event.active
if (!event.active) {
queryState.clearText()
}
}
- is DefaultInvitePeopleEvents.ToggleUser -> {
+ is DefaultInvitePeopleEvent.ToggleUser -> {
selectedUsers.toggleUser(event.user)
searchResults.toggleUser(event.user)
// suggestions will automatically update via derivedStateOf when selectedUsers changes
}
- is DefaultInvitePeopleEvents.DismissUnknownUsersModal -> {
+ is DefaultInvitePeopleEvent.DismissUnknownUsersModal -> {
sendInvitesAction.value = AsyncAction.Uninitialized
}
- is DefaultInvitePeopleEvents.RemoveUnknownUsers -> {
+ is DefaultInvitePeopleEvent.RemoveUnknownUsers -> {
val usersToRemove = selectedUsers.value.filter { it in unknownUsers }
usersToRemove.forEach { user ->
selectedUsers.toggleUser(user)
@@ -207,7 +207,7 @@ class DefaultInvitePeoplePresenter(
sendInvitesAction.value = AsyncAction.Uninitialized
}
}
- is InvitePeopleEvents.SendInvites -> {
+ is InvitePeopleEvent.SendInvites -> {
if (unknownUsers.isNotEmpty() && sendInvitesAction.value !is ConfirmingUnknownUserInvitation) {
sendInvitesAction.value = ConfirmingUnknownUserInvitation(
unknownUsers
@@ -224,11 +224,11 @@ class DefaultInvitePeoplePresenter(
}
}
}
- is InvitePeopleEvents.CloseSearch -> {
+ is InvitePeopleEvent.CloseSearch -> {
searchActive = false
queryState.clearText()
}
- is InvitePeopleEvents.ClearError -> {
+ is InvitePeopleEvent.ClearError -> {
sendInvitesAction.value = AsyncAction.Uninitialized
createRoomFromDmAction.value = AsyncAction.Uninitialized
}
diff --git a/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleState.kt b/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleState.kt
index 46e5d9f1a5..f1058d1a1b 100644
--- a/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleState.kt
+++ b/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleState.kt
@@ -9,7 +9,7 @@
package io.element.android.features.invitepeople.impl
import androidx.compose.foundation.text.input.TextFieldState
-import io.element.android.features.invitepeople.api.InvitePeopleEvents
+import io.element.android.features.invitepeople.api.InvitePeopleEvent
import io.element.android.features.invitepeople.api.InvitePeopleState
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.AsyncData
@@ -29,5 +29,5 @@ data class DefaultInvitePeopleState(
override val sendInvitesAction: AsyncAction,
override val createRoomFromDmAction: AsyncAction,
val suggestions: ImmutableList,
- override val eventSink: (InvitePeopleEvents) -> Unit
+ override val eventSink: (InvitePeopleEvent) -> Unit
) : InvitePeopleState
diff --git a/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/InvitePeopleView.kt b/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/InvitePeopleView.kt
index 7dced41b13..4da2ec7cea 100644
--- a/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/InvitePeopleView.kt
+++ b/features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/InvitePeopleView.kt
@@ -30,7 +30,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.compound.tokens.generated.CompoundIcons
-import io.element.android.features.invitepeople.api.InvitePeopleEvents
+import io.element.android.features.invitepeople.api.InvitePeopleEvent
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.atomic.molecules.ButtonRowMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
@@ -102,7 +102,7 @@ private fun InvitePeopleContentView(
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
fun toggleUser(user: MatrixUser) {
- state.eventSink(DefaultInvitePeopleEvents.ToggleUser(user))
+ state.eventSink(DefaultInvitePeopleEvent.ToggleUser(user))
}
InvitePeopleSearchBar(
@@ -114,7 +114,7 @@ private fun InvitePeopleContentView(
active = state.isSearchActive,
onActiveChange = {
state.eventSink(
- DefaultInvitePeopleEvents.OnSearchActiveChanged(
+ DefaultInvitePeopleEvent.OnSearchActiveChanged(
it
)
)
@@ -144,7 +144,7 @@ private fun InvitePeopleContentView(
CheckableUserRow(
checked = invitableUser.isSelected,
onCheckedChange = {
- state.eventSink(DefaultInvitePeopleEvents.ToggleUser(invitableUser.matrixUser))
+ state.eventSink(DefaultInvitePeopleEvent.ToggleUser(invitableUser.matrixUser))
},
data = CheckableUserRowData.Resolved(
avatarData = invitableUser.matrixUser.getAvatarData(AvatarSize.UserListItem),
@@ -163,9 +163,9 @@ private fun InvitePeopleContentView(
if (state.sendInvitesAction is ConfirmingUnknownUserInvitation) {
InvitePeopleConfirmModal(
users = state.sendInvitesAction.users,
- onDismiss = { state.eventSink.invoke(DefaultInvitePeopleEvents.DismissUnknownUsersModal) },
- onInvite = { state.eventSink.invoke(InvitePeopleEvents.SendInvites) },
- onRemove = { state.eventSink.invoke(DefaultInvitePeopleEvents.RemoveUnknownUsers) }
+ onDismiss = { state.eventSink.invoke(DefaultInvitePeopleEvent.DismissUnknownUsersModal) },
+ onInvite = { state.eventSink.invoke(InvitePeopleEvent.SendInvites) },
+ onRemove = { state.eventSink.invoke(DefaultInvitePeopleEvent.RemoveUnknownUsers) }
)
}
}
diff --git a/features/invitepeople/impl/src/test/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeoplePresenterTest.kt b/features/invitepeople/impl/src/test/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeoplePresenterTest.kt
index 922fa73060..39cfc3afba 100644
--- a/features/invitepeople/impl/src/test/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeoplePresenterTest.kt
+++ b/features/invitepeople/impl/src/test/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeoplePresenterTest.kt
@@ -11,7 +11,7 @@ package io.element.android.features.invitepeople.impl
import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEnd
import app.cash.turbine.ReceiveTurbine
import com.google.common.truth.Truth.assertThat
-import io.element.android.features.invitepeople.api.InvitePeopleEvents
+import io.element.android.features.invitepeople.api.InvitePeopleEvent
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
@@ -88,13 +88,13 @@ internal class DefaultInvitePeoplePresenterTest {
val initialState = awaitItem()
skipItems(1)
- initialState.eventSink(DefaultInvitePeopleEvents.OnSearchActiveChanged(true))
+ initialState.eventSink(DefaultInvitePeopleEvent.OnSearchActiveChanged(true))
val resultState = awaitItemAsDefault()
assertThat(resultState.isSearchActive).isTrue()
resultState.searchQuery.setTextAndPlaceCursorAtEnd("some query")
assertThat(awaitItemAsDefault().searchQuery.text.toString()).isEqualTo("some query")
- resultState.eventSink(InvitePeopleEvents.CloseSearch)
+ resultState.eventSink(InvitePeopleEvent.CloseSearch)
skipItems(1)
awaitItemAsDefault().also {
assertThat(it.isSearchActive).isFalse()
@@ -290,18 +290,18 @@ internal class DefaultInvitePeoplePresenterTest {
skipItems(1)
// When we toggle a user not in the list, they are added
- initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(aMatrixUser()))
+ initialState.eventSink(DefaultInvitePeopleEvent.ToggleUser(aMatrixUser()))
assertThat(awaitItemAsDefault().selectedUsers).containsExactly(aMatrixUser())
// Toggling a different user also adds them
- initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(aMatrixUser(id = A_USER_ID_2.value)))
+ initialState.eventSink(DefaultInvitePeopleEvent.ToggleUser(aMatrixUser(id = A_USER_ID_2.value)))
assertThat(awaitItemAsDefault().selectedUsers).containsExactly(
aMatrixUser(),
aMatrixUser(id = A_USER_ID_2.value)
)
// Toggling the first user removes them
- initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(aMatrixUser()))
+ initialState.eventSink(DefaultInvitePeopleEvent.ToggleUser(aMatrixUser()))
assertThat(awaitItemAsDefault().selectedUsers).containsExactly(aMatrixUser(id = A_USER_ID_2.value))
}
}
@@ -319,7 +319,7 @@ internal class DefaultInvitePeoplePresenterTest {
val selectedUser = aMatrixUser(displayName = "John Doe")
- initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(selectedUser))
+ initialState.eventSink(DefaultInvitePeopleEvent.ToggleUser(selectedUser))
initialState.searchQuery.setTextAndPlaceCursorAtEnd("some query")
skipItems(1)
@@ -373,7 +373,7 @@ internal class DefaultInvitePeoplePresenterTest {
}
// And then a user is toggled
- initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(selectedUser))
+ initialState.eventSink(DefaultInvitePeopleEvent.ToggleUser(selectedUser))
skipItems(1)
val resultState = awaitItemAsDefault()
@@ -414,13 +414,13 @@ internal class DefaultInvitePeoplePresenterTest {
repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser)
skipItems(1)
// And then a user is toggled
- initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(selectedUser))
+ initialState.eventSink(DefaultInvitePeopleEvent.ToggleUser(selectedUser))
skipItems(1)
val resultState = awaitItemAsDefault()
// The results are updated...
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
// Send invites
- initialState.eventSink(InvitePeopleEvents.SendInvites)
+ initialState.eventSink(InvitePeopleEvent.SendInvites)
// Can't invite in the loading state
awaitItem().run {
@@ -468,13 +468,13 @@ internal class DefaultInvitePeoplePresenterTest {
repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser)
skipItems(1)
// And then a user is toggled
- initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(selectedUser))
+ initialState.eventSink(DefaultInvitePeopleEvent.ToggleUser(selectedUser))
skipItems(1)
val resultState = awaitItemAsDefault()
// The results are updated...
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
// Send invites
- initialState.eventSink(InvitePeopleEvents.SendInvites)
+ initialState.eventSink(InvitePeopleEvent.SendInvites)
// Can't invite in the loading state
awaitItem().run {
@@ -645,17 +645,17 @@ internal class DefaultInvitePeoplePresenterTest {
skipItems(1)
// When we toggle a user not in the list, they are added, and we fetch their identity.
- initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(alice))
+ initialState.eventSink(DefaultInvitePeopleEvent.ToggleUser(alice))
delay(100)
- awaitItemAsDefault().eventSink(DefaultInvitePeopleEvents.ToggleUser(bob))
+ awaitItemAsDefault().eventSink(DefaultInvitePeopleEvent.ToggleUser(bob))
delay(100)
- awaitItemAsDefault().eventSink(DefaultInvitePeopleEvents.ToggleUser(charlie))
+ awaitItemAsDefault().eventSink(DefaultInvitePeopleEvent.ToggleUser(charlie))
delay(100)
// If we do not have their identity cached, or fail to fetch it, we should mark them as unknown.
awaitItemAsDefault().run {
assertThat(selectedUsers).containsExactly(alice, bob, charlie)
- eventSink(InvitePeopleEvents.SendInvites)
+ eventSink(InvitePeopleEvent.SendInvites)
}
getUserIdentityResult.assertions().isCalledExactly(3).withSequence(
@@ -668,7 +668,7 @@ internal class DefaultInvitePeoplePresenterTest {
awaitItemAsDefault().run {
assertThat(sendInvitesAction).isInstanceOf(ConfirmingUnknownUserInvitation::class.java)
assertThat(canInvite).isTrue()
- eventSink(InvitePeopleEvents.SendInvites)
+ eventSink(InvitePeopleEvent.SendInvites)
}
delay(1_000)
@@ -712,11 +712,11 @@ internal class DefaultInvitePeoplePresenterTest {
skipItems(1)
// When we toggle a user not in the list, they are added, and we fetch their identity.
- initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(alice))
+ initialState.eventSink(DefaultInvitePeopleEvent.ToggleUser(alice))
delay(100)
- awaitItemAsDefault().eventSink(DefaultInvitePeopleEvents.ToggleUser(bob))
+ awaitItemAsDefault().eventSink(DefaultInvitePeopleEvent.ToggleUser(bob))
delay(100)
- awaitItemAsDefault().eventSink(DefaultInvitePeopleEvents.ToggleUser(charlie))
+ awaitItemAsDefault().eventSink(DefaultInvitePeopleEvent.ToggleUser(charlie))
delay(100)
// And the search is matching Alice and Bob
@@ -738,7 +738,7 @@ internal class DefaultInvitePeoplePresenterTest {
searchResults.users().map { Pair(it.matrixUser, it.isSelected) }
).containsExactly(Pair(alice, true), Pair(bob, true))
- eventSink(InvitePeopleEvents.SendInvites)
+ eventSink(InvitePeopleEvent.SendInvites)
}
getUserIdentityResult.assertions().isCalledExactly(3).withSequence(
@@ -751,7 +751,7 @@ internal class DefaultInvitePeoplePresenterTest {
awaitItemAsDefault().run {
assertThat(sendInvitesAction).isInstanceOf(ConfirmingUnknownUserInvitation::class.java)
assertThat(canInvite).isTrue()
- eventSink(DefaultInvitePeopleEvents.RemoveUnknownUsers)
+ eventSink(DefaultInvitePeopleEvent.RemoveUnknownUsers)
}
// Selecting "remove" should remove all unknown users, but keeps those who are known.
@@ -794,16 +794,16 @@ internal class DefaultInvitePeoplePresenterTest {
skipItems(1)
// When we toggle a user not in the list, they are added, and we fetch their identity.
- initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(alice))
+ initialState.eventSink(DefaultInvitePeopleEvent.ToggleUser(alice))
delay(100)
- awaitItemAsDefault().eventSink(DefaultInvitePeopleEvents.ToggleUser(bob))
+ awaitItemAsDefault().eventSink(DefaultInvitePeopleEvent.ToggleUser(bob))
delay(100)
- awaitItemAsDefault().eventSink(DefaultInvitePeopleEvents.ToggleUser(charlie))
+ awaitItemAsDefault().eventSink(DefaultInvitePeopleEvent.ToggleUser(charlie))
delay(100)
awaitItemAsDefault().run {
assertThat(selectedUsers).containsExactly(alice, bob, charlie)
- eventSink(InvitePeopleEvents.SendInvites)
+ eventSink(InvitePeopleEvent.SendInvites)
}
getUserIdentityResult.assertions().isCalledExactly(3).withSequence(
@@ -816,7 +816,7 @@ internal class DefaultInvitePeoplePresenterTest {
awaitItemAsDefault().run {
assertThat(sendInvitesAction).isInstanceOf(ConfirmingUnknownUserInvitation::class.java)
assertThat(canInvite).isTrue()
- eventSink(DefaultInvitePeopleEvents.DismissUnknownUsersModal)
+ eventSink(DefaultInvitePeopleEvent.DismissUnknownUsersModal)
}
// Dismissing should not modify the selection at all
@@ -853,10 +853,10 @@ internal class DefaultInvitePeoplePresenterTest {
skipItems(1)
// We want to add a new user to a DM
- initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(alice))
+ initialState.eventSink(DefaultInvitePeopleEvent.ToggleUser(alice))
// And we send the invites
- initialState.eventSink(InvitePeopleEvents.SendInvites)
+ initialState.eventSink(InvitePeopleEvent.SendInvites)
skipItems(1)
diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomEvents.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomEvent.kt
similarity index 60%
rename from features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomEvents.kt
rename to features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomEvent.kt
index 51245dd8f6..a2e53485ce 100644
--- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomEvents.kt
+++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomEvent.kt
@@ -10,15 +10,15 @@ package io.element.android.features.joinroom.impl
import io.element.android.features.invite.api.InviteData
-sealed interface JoinRoomEvents {
- data object RetryFetchingContent : JoinRoomEvents
- data object DismissErrorAndHideContent : JoinRoomEvents
- data object JoinRoom : JoinRoomEvents
- data object KnockRoom : JoinRoomEvents
- data object ForgetRoom : JoinRoomEvents
- data class CancelKnock(val requiresConfirmation: Boolean) : JoinRoomEvents
- data class UpdateKnockMessage(val message: String) : JoinRoomEvents
- data object ClearActionStates : JoinRoomEvents
- data class AcceptInvite(val inviteData: InviteData) : JoinRoomEvents
- data class DeclineInvite(val inviteData: InviteData, val blockUser: Boolean) : JoinRoomEvents
+sealed interface JoinRoomEvent {
+ data object RetryFetchingContent : JoinRoomEvent
+ data object DismissErrorAndHideContent : JoinRoomEvent
+ data object JoinRoom : JoinRoomEvent
+ data object KnockRoom : JoinRoomEvent
+ data object ForgetRoom : JoinRoomEvent
+ data class CancelKnock(val requiresConfirmation: Boolean) : JoinRoomEvent
+ data class UpdateKnockMessage(val message: String) : JoinRoomEvent
+ data object ClearActionStates : JoinRoomEvent
+ data class AcceptInvite(val inviteData: InviteData) : JoinRoomEvent
+ data class DeclineInvite(val inviteData: InviteData, val blockUser: Boolean) : JoinRoomEvent
}
diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt
index d257952209..85ae9cf392 100644
--- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt
+++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt
@@ -26,7 +26,7 @@ import dev.zacsweers.metro.AssistedInject
import im.vector.app.features.analytics.plan.JoinedRoom
import io.element.android.features.invite.api.InviteData
import io.element.android.features.invite.api.SeenInvitesStore
-import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
+import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvent
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.invite.api.toInviteData
import io.element.android.features.joinroom.impl.di.CancelKnockRoom
@@ -151,37 +151,37 @@ class JoinRoomPresenter(
contentState.markRoomInviteAsSeen()
}
- fun handleEvent(event: JoinRoomEvents) {
+ fun handleEvent(event: JoinRoomEvent) {
when (event) {
- JoinRoomEvents.JoinRoom -> coroutineScope.joinRoom(joinAction)
- is JoinRoomEvents.KnockRoom -> coroutineScope.knockRoom(knockAction, knockMessage)
- is JoinRoomEvents.AcceptInvite -> {
+ JoinRoomEvent.JoinRoom -> coroutineScope.joinRoom(joinAction)
+ is JoinRoomEvent.KnockRoom -> coroutineScope.knockRoom(knockAction, knockMessage)
+ is JoinRoomEvent.AcceptInvite -> {
acceptDeclineInviteState.eventSink(
- AcceptDeclineInviteEvents.AcceptInvite(event.inviteData)
+ AcceptDeclineInviteEvent.AcceptInvite(event.inviteData)
)
}
- is JoinRoomEvents.DeclineInvite -> {
+ is JoinRoomEvent.DeclineInvite -> {
acceptDeclineInviteState.eventSink(
- AcceptDeclineInviteEvents.DeclineInvite(invite = event.inviteData, blockUser = event.blockUser, shouldConfirm = true)
+ AcceptDeclineInviteEvent.DeclineInvite(invite = event.inviteData, blockUser = event.blockUser, shouldConfirm = true)
)
}
- is JoinRoomEvents.CancelKnock -> coroutineScope.cancelKnockRoom(event.requiresConfirmation, cancelKnockAction)
- JoinRoomEvents.RetryFetchingContent -> {
+ is JoinRoomEvent.CancelKnock -> coroutineScope.cancelKnockRoom(event.requiresConfirmation, cancelKnockAction)
+ JoinRoomEvent.RetryFetchingContent -> {
retryCount++
}
- JoinRoomEvents.ClearActionStates -> {
+ JoinRoomEvent.ClearActionStates -> {
knockAction.value = AsyncAction.Uninitialized
joinAction.value = AsyncAction.Uninitialized
cancelKnockAction.value = AsyncAction.Uninitialized
forgetRoomAction.value = AsyncAction.Uninitialized
}
- is JoinRoomEvents.UpdateKnockMessage -> {
+ is JoinRoomEvent.UpdateKnockMessage -> {
knockMessage = event.message.take(MAX_KNOCK_MESSAGE_LENGTH)
}
- JoinRoomEvents.DismissErrorAndHideContent -> {
+ JoinRoomEvent.DismissErrorAndHideContent -> {
isDismissingContent = true
}
- JoinRoomEvents.ForgetRoom -> coroutineScope.forgetRoom(forgetRoomAction)
+ JoinRoomEvent.ForgetRoom -> coroutineScope.forgetRoom(forgetRoomAction)
}
}
diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt
index e109bb1315..25f7765a7c 100644
--- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt
+++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt
@@ -37,7 +37,7 @@ data class JoinRoomState(
val knockMessage: String,
val hideInviteAvatars: Boolean,
val canReportRoom: Boolean,
- val eventSink: (JoinRoomEvents) -> Unit
+ val eventSink: (JoinRoomEvent) -> Unit
) {
val isJoinActionUnauthorized = joinAction is AsyncAction.Failure && joinAction.error is JoinRoom.Failures.UnauthorizedJoin
val joinAuthorisationStatus = when (contentState) {
diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStatePreviewParam.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStatePreviewParam.kt
index f47377b16b..a09e33aded 100644
--- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStatePreviewParam.kt
+++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStatePreviewParam.kt
@@ -207,7 +207,7 @@ fun aJoinRoomState(
knockMessage: String = "",
hideInviteAvatars: Boolean = false,
canReportRoom: Boolean = true,
- eventSink: (JoinRoomEvents) -> Unit = {}
+ eventSink: (JoinRoomEvent) -> Unit = {}
) = JoinRoomState(
roomIdOrAlias = roomIdOrAlias,
contentState = contentState,
diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt
index f1adf1705f..3dd964610a 100644
--- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt
+++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt
@@ -115,33 +115,33 @@ fun JoinRoomView(
contentState = state.contentState,
knockMessage = state.knockMessage,
hideAvatarsImages = state.hideAvatarsImages,
- onKnockMessageUpdate = { state.eventSink(JoinRoomEvents.UpdateKnockMessage(it)) },
+ onKnockMessageUpdate = { state.eventSink(JoinRoomEvent.UpdateKnockMessage(it)) },
)
},
footer = {
JoinRoomFooter(
joinAuthorisationStatus = state.joinAuthorisationStatus,
onAcceptInvite = { inviteData ->
- state.eventSink(JoinRoomEvents.AcceptInvite(inviteData))
+ state.eventSink(JoinRoomEvent.AcceptInvite(inviteData))
},
onDeclineInvite = { inviteData, blockUser ->
if (state.canReportRoom && blockUser) {
onDeclineInviteAndBlockUser(inviteData)
} else {
- state.eventSink(JoinRoomEvents.DeclineInvite(inviteData, blockUser = blockUser))
+ state.eventSink(JoinRoomEvent.DeclineInvite(inviteData, blockUser = blockUser))
}
},
onJoinRoom = {
- state.eventSink(JoinRoomEvents.JoinRoom)
+ state.eventSink(JoinRoomEvent.JoinRoom)
},
onKnockRoom = {
- state.eventSink(JoinRoomEvents.KnockRoom)
+ state.eventSink(JoinRoomEvent.KnockRoom)
},
onCancelKnock = {
- state.eventSink(JoinRoomEvents.CancelKnock(requiresConfirmation = true))
+ state.eventSink(JoinRoomEvent.CancelKnock(requiresConfirmation = true))
},
onForgetRoom = {
- state.eventSink(JoinRoomEvents.ForgetRoom)
+ state.eventSink(JoinRoomEvent.ForgetRoom)
},
onGoBack = onBackClick,
)
@@ -152,9 +152,9 @@ fun JoinRoomView(
RetryDialog(
title = stringResource(R.string.screen_join_room_loading_alert_title),
content = stringResource(CommonStrings.error_network_or_server_issue),
- onRetry = { state.eventSink(JoinRoomEvents.RetryFetchingContent) },
+ onRetry = { state.eventSink(JoinRoomEvent.RetryFetchingContent) },
onDismiss = {
- state.eventSink(JoinRoomEvents.DismissErrorAndHideContent)
+ state.eventSink(JoinRoomEvent.DismissErrorAndHideContent)
onBackClick()
}
)
@@ -166,7 +166,7 @@ fun JoinRoomView(
errorTitle = { stringResource(CommonStrings.common_something_went_wrong) },
errorMessage = { stringResource(CommonStrings.error_network_or_server_issue) },
onSuccess = { onJoinSuccess() },
- onErrorDismiss = { state.eventSink(JoinRoomEvents.ClearActionStates) },
+ onErrorDismiss = { state.eventSink(JoinRoomEvent.ClearActionStates) },
)
}
AsyncActionView(
@@ -174,19 +174,19 @@ fun JoinRoomView(
errorTitle = { stringResource(CommonStrings.common_something_went_wrong) },
errorMessage = { stringResource(CommonStrings.error_network_or_server_issue) },
onSuccess = { onKnockSuccess() },
- onErrorDismiss = { state.eventSink(JoinRoomEvents.ClearActionStates) },
+ onErrorDismiss = { state.eventSink(JoinRoomEvent.ClearActionStates) },
)
AsyncActionView(
async = state.forgetAction,
errorTitle = { stringResource(CommonStrings.common_something_went_wrong) },
errorMessage = { stringResource(CommonStrings.error_network_or_server_issue) },
onSuccess = { onForgetSuccess() },
- onErrorDismiss = { state.eventSink(JoinRoomEvents.ClearActionStates) },
+ onErrorDismiss = { state.eventSink(JoinRoomEvent.ClearActionStates) },
)
AsyncActionView(
async = state.cancelKnockAction,
onSuccess = { onCancelKnockSuccess() },
- onErrorDismiss = { state.eventSink(JoinRoomEvents.ClearActionStates) },
+ onErrorDismiss = { state.eventSink(JoinRoomEvent.ClearActionStates) },
errorTitle = { stringResource(CommonStrings.common_something_went_wrong) },
errorMessage = { stringResource(CommonStrings.error_network_or_server_issue) },
confirmationDialog = {
@@ -195,8 +195,8 @@ fun JoinRoomView(
title = stringResource(R.string.screen_join_room_cancel_knock_alert_title),
submitText = stringResource(R.string.screen_join_room_cancel_knock_alert_confirmation),
cancelText = stringResource(CommonStrings.action_no),
- onSubmitClick = { state.eventSink(JoinRoomEvents.CancelKnock(requiresConfirmation = false)) },
- onDismiss = { state.eventSink(JoinRoomEvents.ClearActionStates) },
+ onSubmitClick = { state.eventSink(JoinRoomEvent.CancelKnock(requiresConfirmation = false)) },
+ onDismiss = { state.eventSink(JoinRoomEvent.ClearActionStates) },
)
},
)
diff --git a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt
index 41ed2cce40..3c104e47ae 100644
--- a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt
+++ b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt
@@ -12,7 +12,7 @@ import com.google.common.truth.Truth.assertThat
import im.vector.app.features.analytics.plan.JoinedRoom
import io.element.android.features.invite.api.InviteData
import io.element.android.features.invite.api.SeenInvitesStore
-import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
+import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvent
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.invite.api.acceptdecline.anAcceptDeclineInviteState
import io.element.android.features.invite.api.toInviteData
@@ -365,7 +365,7 @@ class JoinRoomPresenterTest {
@Test
fun `present - when room is invited then accept and decline events are sent to acceptDeclinePresenter`() = runTest {
- val eventSinkRecorder = lambdaRecorder { _: AcceptDeclineInviteEvents -> }
+ val eventSinkRecorder = lambdaRecorder { _: AcceptDeclineInviteEvent -> }
val acceptDeclinePresenter = Presenter {
anAcceptDeclineInviteState(eventSink = eventSinkRecorder)
}
@@ -388,14 +388,14 @@ class JoinRoomPresenterTest {
skipItems(1)
awaitItem().also { state ->
- state.eventSink(JoinRoomEvents.AcceptInvite(inviteData))
- state.eventSink(JoinRoomEvents.DeclineInvite(inviteData, false))
+ state.eventSink(JoinRoomEvent.AcceptInvite(inviteData))
+ state.eventSink(JoinRoomEvent.DeclineInvite(inviteData, false))
assert(eventSinkRecorder)
.isCalledExactly(2)
.withSequence(
- listOf(value(AcceptDeclineInviteEvents.AcceptInvite(inviteData))),
- listOf(value(AcceptDeclineInviteEvents.DeclineInvite(inviteData, blockUser = false, shouldConfirm = true))),
+ listOf(value(AcceptDeclineInviteEvent.AcceptInvite(inviteData))),
+ listOf(value(AcceptDeclineInviteEvent.DeclineInvite(inviteData, blockUser = false, shouldConfirm = true))),
)
}
}
@@ -422,7 +422,7 @@ class JoinRoomPresenterTest {
presenter.test {
skipItems(1)
awaitItem().also { state ->
- state.eventSink(JoinRoomEvents.JoinRoom)
+ state.eventSink(JoinRoomEvent.JoinRoom)
}
awaitItem().also { state ->
assertThat(state.joinAction).isEqualTo(AsyncAction.Loading)
@@ -453,14 +453,14 @@ class JoinRoomPresenterTest {
presenter.test {
skipItems(1)
awaitItem().also { state ->
- state.eventSink(JoinRoomEvents.JoinRoom)
+ state.eventSink(JoinRoomEvent.JoinRoom)
}
awaitItem().also { state ->
assertThat(state.joinAction).isEqualTo(AsyncAction.Loading)
}
awaitItem().also { state ->
assertThat(state.joinAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
- state.eventSink(JoinRoomEvents.ClearActionStates)
+ state.eventSink(JoinRoomEvent.ClearActionStates)
}
awaitItem().also { state ->
assertThat(state.joinAction).isEqualTo(AsyncAction.Uninitialized)
@@ -480,7 +480,7 @@ class JoinRoomPresenterTest {
presenter.test {
skipItems(1)
awaitItem().also { state ->
- state.eventSink(JoinRoomEvents.JoinRoom)
+ state.eventSink(JoinRoomEvent.JoinRoom)
}
awaitItem().also { state ->
assertThat(state.joinAction).isEqualTo(AsyncAction.Loading)
@@ -683,17 +683,17 @@ class JoinRoomPresenterTest {
presenter.test {
skipItems(1)
awaitItem().also { state ->
- state.eventSink(JoinRoomEvents.UpdateKnockMessage(knockMessage))
+ state.eventSink(JoinRoomEvent.UpdateKnockMessage(knockMessage))
}
awaitItem().also { state ->
- state.eventSink(JoinRoomEvents.KnockRoom)
+ state.eventSink(JoinRoomEvent.KnockRoom)
}
assertThat(awaitItem().knockAction).isEqualTo(AsyncAction.Loading)
awaitItem().also { state ->
assertThat(state.knockAction).isEqualTo(AsyncAction.Success(Unit))
fakeKnockRoom.lambda = knockRoomFailure
- state.eventSink(JoinRoomEvents.KnockRoom)
+ state.eventSink(JoinRoomEvent.KnockRoom)
}
assertThat(awaitItem().knockAction).isEqualTo(AsyncAction.Loading)
@@ -731,17 +731,17 @@ class JoinRoomPresenterTest {
presenter.test {
skipItems(1)
awaitItem().also { state ->
- state.eventSink(JoinRoomEvents.CancelKnock(true))
+ state.eventSink(JoinRoomEvent.CancelKnock(true))
}
awaitItem().also { state ->
assertThat(state.cancelKnockAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- state.eventSink(JoinRoomEvents.CancelKnock(false))
+ state.eventSink(JoinRoomEvent.CancelKnock(false))
}
assertThat(awaitItem().cancelKnockAction).isEqualTo(AsyncAction.Loading)
awaitItem().also { state ->
assertThat(state.cancelKnockAction).isEqualTo(AsyncAction.Success(Unit))
cancelKnockRoom.lambda = cancelKnockRoomFailure
- state.eventSink(JoinRoomEvents.CancelKnock(false))
+ state.eventSink(JoinRoomEvent.CancelKnock(false))
}
assertThat(awaitItem().cancelKnockAction).isEqualTo(AsyncAction.Loading)
awaitItem().also { state ->
@@ -778,14 +778,14 @@ class JoinRoomPresenterTest {
presenter.test {
skipItems(1)
awaitItem().also { state ->
- state.eventSink(JoinRoomEvents.ForgetRoom)
+ state.eventSink(JoinRoomEvent.ForgetRoom)
}
assertThat(awaitItem().forgetAction).isEqualTo(AsyncAction.Loading)
awaitItem().also { state ->
assertThat(state.forgetAction).isEqualTo(AsyncAction.Success(Unit))
fakeForgetRoom.lambda = forgetRoomFailure
- state.eventSink(JoinRoomEvents.ForgetRoom)
+ state.eventSink(JoinRoomEvent.ForgetRoom)
}
assertThat(awaitItem().forgetAction).isEqualTo(AsyncAction.Loading)
diff --git a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomViewTest.kt b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomViewTest.kt
index 0c510cacdb..c74e81010d 100644
--- a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomViewTest.kt
+++ b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomViewTest.kt
@@ -34,7 +34,7 @@ import org.junit.Test
class JoinRoomViewTest : RobolectricTest() {
@Test
fun `clicking on back invoke the expected callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce {
setJoinRoomView(
aJoinRoomState(
@@ -48,7 +48,7 @@ class JoinRoomViewTest : RobolectricTest() {
@Test
fun `clicking on Join room on CanJoin room emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setJoinRoomView(
aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanJoin),
@@ -56,12 +56,12 @@ class JoinRoomViewTest : RobolectricTest() {
),
)
clickOn(R.string.screen_join_room_join_action)
- eventsRecorder.assertSingle(JoinRoomEvents.JoinRoom)
+ eventsRecorder.assertSingle(JoinRoomEvent.JoinRoom)
}
@Test
fun `clicking on Knock room on CanKnock room emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setJoinRoomView(
aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanKnock),
@@ -70,12 +70,12 @@ class JoinRoomViewTest : RobolectricTest() {
),
)
clickOn(R.string.screen_join_room_knock_action)
- eventsRecorder.assertSingle(JoinRoomEvents.KnockRoom)
+ eventsRecorder.assertSingle(JoinRoomEvent.KnockRoom)
}
@Test
fun `clicking on closing Knock error emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setJoinRoomView(
aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanKnock),
@@ -84,12 +84,12 @@ class JoinRoomViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_ok)
- eventsRecorder.assertSingle(JoinRoomEvents.ClearActionStates)
+ eventsRecorder.assertSingle(JoinRoomEvent.ClearActionStates)
}
@Test
fun `clicking on cancel knock request emit the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setJoinRoomView(
aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsKnocked),
@@ -97,12 +97,12 @@ class JoinRoomViewTest : RobolectricTest() {
),
)
clickOn(R.string.screen_join_room_cancel_knock_action)
- eventsRecorder.assertSingle(JoinRoomEvents.CancelKnock(true))
+ eventsRecorder.assertSingle(JoinRoomEvent.CancelKnock(true))
}
@Test
fun `clicking on closing Cancel Knock error emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setJoinRoomView(
aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsKnocked),
@@ -111,12 +111,12 @@ class JoinRoomViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_ok)
- eventsRecorder.assertSingle(JoinRoomEvents.ClearActionStates)
+ eventsRecorder.assertSingle(JoinRoomEvent.ClearActionStates)
}
@Test
fun `clicking on closing Join error emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setJoinRoomView(
aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanKnock),
@@ -125,12 +125,12 @@ class JoinRoomViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_ok)
- eventsRecorder.assertSingle(JoinRoomEvents.ClearActionStates)
+ eventsRecorder.assertSingle(JoinRoomEvent.ClearActionStates)
}
@Test
fun `when joining room is successful, the expected callback is invoked`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce {
setJoinRoomView(
aJoinRoomState(
@@ -144,7 +144,7 @@ class JoinRoomViewTest : RobolectricTest() {
@Test
fun `clicking on Accept when JoinAuthorisationStatus is IsInvited emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val inviteData = anInviteData()
setJoinRoomView(
aJoinRoomState(
@@ -153,12 +153,12 @@ class JoinRoomViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_accept)
- eventsRecorder.assertSingle(JoinRoomEvents.AcceptInvite(inviteData))
+ eventsRecorder.assertSingle(JoinRoomEvent.AcceptInvite(inviteData))
}
@Test
fun `clicking on Decline when JoinAuthorisationStatus is IsInvited emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val inviteData = anInviteData()
setJoinRoomView(
aJoinRoomState(
@@ -167,13 +167,13 @@ class JoinRoomViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_decline)
- eventsRecorder.assertSingle(JoinRoomEvents.DeclineInvite(inviteData, false))
+ eventsRecorder.assertSingle(JoinRoomEvent.DeclineInvite(inviteData, false))
}
@Test
fun `clicking on Decline and block when JoinAuthorisationStatus is IsInvited and can report room, the expected callback is invoked`() {
runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
val inviteData = anInviteData()
val joinRoomState = aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsInvited(inviteData, aRoomMember().toInviteSender())),
@@ -192,7 +192,7 @@ class JoinRoomViewTest : RobolectricTest() {
@Test
fun `clicking on Decline and block when JoinAuthorisationStatus is IsInvited and cant report room, emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val inviteData = anInviteData()
val joinRoomState = aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsInvited(inviteData, aRoomMember().toInviteSender())),
@@ -201,12 +201,12 @@ class JoinRoomViewTest : RobolectricTest() {
)
setJoinRoomView(state = joinRoomState)
clickOn(R.string.screen_join_room_decline_and_block_button_title)
- eventsRecorder.assertSingle(JoinRoomEvents.DeclineInvite(inviteData, true))
+ eventsRecorder.assertSingle(JoinRoomEvent.DeclineInvite(inviteData, true))
}
@Test
fun `clicking on Retry when an error occurs emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setJoinRoomView(
aJoinRoomState(
contentState = aFailureContentState(),
@@ -214,12 +214,12 @@ class JoinRoomViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_retry)
- eventsRecorder.assertSingle(JoinRoomEvents.RetryFetchingContent)
+ eventsRecorder.assertSingle(JoinRoomEvent.RetryFetchingContent)
}
@Test
fun `clicking on ok when user is unauthorized the expected callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce {
setJoinRoomView(
aJoinRoomState(
@@ -235,7 +235,7 @@ class JoinRoomViewTest : RobolectricTest() {
@Test
fun `clicking on forget when user is banned invokes the expected callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setJoinRoomView(
aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsBanned(null, null)),
@@ -243,7 +243,7 @@ class JoinRoomViewTest : RobolectricTest() {
),
)
clickOn(R.string.screen_join_room_forget_action)
- eventsRecorder.assertSingle(JoinRoomEvents.ForgetRoom)
+ eventsRecorder.assertSingle(JoinRoomEvent.ForgetRoom)
}
}
diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerEvents.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerEvent.kt
similarity index 65%
rename from features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerEvents.kt
rename to features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerEvent.kt
index 740982b612..b8cd9345c2 100644
--- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerEvents.kt
+++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerEvent.kt
@@ -8,7 +8,7 @@
package io.element.android.features.knockrequests.impl.banner
-sealed interface KnockRequestsBannerEvents {
- data object AcceptSingleRequest : KnockRequestsBannerEvents
- data object Dismiss : KnockRequestsBannerEvents
+sealed interface KnockRequestsBannerEvent {
+ data object AcceptSingleRequest : KnockRequestsBannerEvent
+ data object Dismiss : KnockRequestsBannerEvent
}
diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt
index f340d597b1..a96b6d3de3 100644
--- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt
+++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt
@@ -53,15 +53,15 @@ class KnockRequestsBannerPresenter(
}
}
- fun handleEvent(event: KnockRequestsBannerEvents) {
+ fun handleEvent(event: KnockRequestsBannerEvent) {
when (event) {
- is KnockRequestsBannerEvents.AcceptSingleRequest -> {
+ is KnockRequestsBannerEvent.AcceptSingleRequest -> {
sessionCoroutineScope.acceptSingleKnockRequest(
knockRequests = knockRequests,
displayAcceptError = showAcceptError,
)
}
- is KnockRequestsBannerEvents.Dismiss -> {
+ is KnockRequestsBannerEvent.Dismiss -> {
sessionCoroutineScope.launch {
knockRequestsService.markAllKnockRequestsAsSeen()
}
diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerState.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerState.kt
index e9291b501a..2b6532c355 100644
--- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerState.kt
+++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerState.kt
@@ -20,7 +20,7 @@ data class KnockRequestsBannerState(
val knockRequests: ImmutableList,
val displayAcceptError: Boolean,
val canAccept: Boolean,
- val eventSink: (KnockRequestsBannerEvents) -> Unit,
+ val eventSink: (KnockRequestsBannerEvent) -> Unit,
) {
val subtitle = knockRequests.singleOrNull()?.userId?.value
val reason = knockRequests.singleOrNull()?.reason
diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerStatePreviewParam.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerStatePreviewParam.kt
index fb05ae1fe0..8df5e08985 100644
--- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerStatePreviewParam.kt
+++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerStatePreviewParam.kt
@@ -64,7 +64,7 @@ fun aKnockRequestsBannerState(
displayAcceptError: Boolean = false,
canAccept: Boolean = true,
isVisible: Boolean = true,
- eventSink: (KnockRequestsBannerEvents) -> Unit = {}
+ eventSink: (KnockRequestsBannerEvent) -> Unit = {}
) = KnockRequestsBannerState(
knockRequests = knockRequests.toImmutableList(),
displayAcceptError = displayAcceptError,
diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerView.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerView.kt
index 037ec16d00..329e7a2a56 100644
--- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerView.kt
+++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerView.kt
@@ -109,11 +109,11 @@ private fun KnockRequestsBannerContent(
modifier: Modifier = Modifier,
) {
fun onDismissClick() {
- state.eventSink(KnockRequestsBannerEvents.Dismiss)
+ state.eventSink(KnockRequestsBannerEvent.Dismiss)
}
fun onAcceptClick() {
- state.eventSink(KnockRequestsBannerEvents.AcceptSingleRequest)
+ state.eventSink(KnockRequestsBannerEvent.AcceptSingleRequest)
}
Column(
diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListEvents.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListEvent.kt
similarity index 61%
rename from features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListEvents.kt
rename to features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListEvent.kt
index f1350b1669..6b9a6ac1a8 100644
--- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListEvents.kt
+++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListEvent.kt
@@ -10,12 +10,12 @@ package io.element.android.features.knockrequests.impl.list
import io.element.android.features.knockrequests.impl.data.KnockRequestPresentable
-sealed interface KnockRequestsListEvents {
- data class Accept(val knockRequest: KnockRequestPresentable) : KnockRequestsListEvents
- data class Decline(val knockRequest: KnockRequestPresentable) : KnockRequestsListEvents
- data class DeclineAndBan(val knockRequest: KnockRequestPresentable) : KnockRequestsListEvents
- data object AcceptAll : KnockRequestsListEvents
- data object ResetCurrentAction : KnockRequestsListEvents
- data object RetryCurrentAction : KnockRequestsListEvents
- data object ConfirmCurrentAction : KnockRequestsListEvents
+sealed interface KnockRequestsListEvent {
+ data class Accept(val knockRequest: KnockRequestPresentable) : KnockRequestsListEvent
+ data class Decline(val knockRequest: KnockRequestPresentable) : KnockRequestsListEvent
+ data class DeclineAndBan(val knockRequest: KnockRequestPresentable) : KnockRequestsListEvent
+ data object AcceptAll : KnockRequestsListEvent
+ data object ResetCurrentAction : KnockRequestsListEvent
+ data object RetryCurrentAction : KnockRequestsListEvent
+ data object ConfirmCurrentAction : KnockRequestsListEvent
}
diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenter.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenter.kt
index a56dc40731..76b562d8b3 100644
--- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenter.kt
+++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenter.kt
@@ -39,28 +39,28 @@ class KnockRequestsListPresenter(
val coroutineScope = rememberCoroutineScope()
- fun handleEvent(event: KnockRequestsListEvents) {
+ fun handleEvent(event: KnockRequestsListEvent) {
when (event) {
- KnockRequestsListEvents.AcceptAll -> {
+ KnockRequestsListEvent.AcceptAll -> {
currentAction = KnockRequestsAction.AcceptAll
}
- is KnockRequestsListEvents.Accept -> {
+ is KnockRequestsListEvent.Accept -> {
currentAction = KnockRequestsAction.Accept(event.knockRequest)
}
- is KnockRequestsListEvents.Decline -> {
+ is KnockRequestsListEvent.Decline -> {
currentAction = KnockRequestsAction.Decline(event.knockRequest)
}
- is KnockRequestsListEvents.DeclineAndBan -> {
+ is KnockRequestsListEvent.DeclineAndBan -> {
currentAction = KnockRequestsAction.DeclineAndBan(event.knockRequest)
}
- KnockRequestsListEvents.ResetCurrentAction -> {
+ KnockRequestsListEvent.ResetCurrentAction -> {
asyncAction.value = AsyncAction.Uninitialized
currentAction = KnockRequestsAction.None
}
- KnockRequestsListEvents.RetryCurrentAction -> {
+ KnockRequestsListEvent.RetryCurrentAction -> {
coroutineScope.executeAction(currentAction, asyncAction, isActionConfirmed = true)
}
- KnockRequestsListEvents.ConfirmCurrentAction -> {
+ KnockRequestsListEvent.ConfirmCurrentAction -> {
coroutineScope.executeAction(currentAction, asyncAction, isActionConfirmed = true)
}
}
diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt
index ae770a297d..0a0e576eae 100644
--- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt
+++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt
@@ -20,7 +20,7 @@ data class KnockRequestsListState(
val currentAction: KnockRequestsAction,
val asyncAction: AsyncAction,
val permissions: KnockRequestPermissions,
- val eventSink: (KnockRequestsListEvents) -> Unit,
+ val eventSink: (KnockRequestsListEvent) -> Unit,
) {
val canAcceptAll = permissions.canAccept && knockRequests is AsyncData.Success && knockRequests.data.size > 1
}
diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStatePreviewParam.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStatePreviewParam.kt
index b51223a5e9..691d874af6 100644
--- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStatePreviewParam.kt
+++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStatePreviewParam.kt
@@ -140,7 +140,7 @@ fun aKnockRequestsListState(
canDecline = true,
canBan = true,
),
- eventSink: (KnockRequestsListEvents) -> Unit = {},
+ eventSink: (KnockRequestsListEvent) -> Unit = {},
) = KnockRequestsListState(
knockRequests = knockRequests,
currentAction = currentAction,
diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt
index d750927f74..52b11bc8c4 100644
--- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt
+++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt
@@ -108,15 +108,15 @@ private fun KnockRequestsListContent(
modifier: Modifier = Modifier,
) {
fun onAcceptClick(knockRequest: KnockRequestPresentable) {
- state.eventSink(KnockRequestsListEvents.Accept(knockRequest))
+ state.eventSink(KnockRequestsListEvent.Accept(knockRequest))
}
fun onDeclineClick(knockRequest: KnockRequestPresentable) {
- state.eventSink(KnockRequestsListEvents.Decline(knockRequest))
+ state.eventSink(KnockRequestsListEvent.Decline(knockRequest))
}
fun onBanClick(knockRequest: KnockRequestPresentable) {
- state.eventSink(KnockRequestsListEvents.DeclineAndBan(knockRequest))
+ state.eventSink(KnockRequestsListEvent.DeclineAndBan(knockRequest))
}
var bottomPaddingInPixels by remember { mutableIntStateOf(0) }
@@ -160,19 +160,19 @@ private fun KnockRequestsListContent(
currentAction = state.currentAction,
asyncAction = state.asyncAction,
onConfirm = {
- state.eventSink(KnockRequestsListEvents.ConfirmCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ConfirmCurrentAction)
},
onRetry = {
- state.eventSink(KnockRequestsListEvents.RetryCurrentAction)
+ state.eventSink(KnockRequestsListEvent.RetryCurrentAction)
},
onDismiss = {
- state.eventSink(KnockRequestsListEvents.ResetCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ResetCurrentAction)
},
)
if (state.canAcceptAll) {
KnockRequestsAcceptAll(
onClick = {
- state.eventSink(KnockRequestsListEvents.AcceptAll)
+ state.eventSink(KnockRequestsListEvent.AcceptAll)
},
onHeightChange = { height ->
bottomPaddingInPixels = height
diff --git a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt
index 1595fcdbd9..2c1a185ba2 100644
--- a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt
+++ b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt
@@ -146,7 +146,7 @@ import org.junit.Test
presenter.test {
skipItems(2)
awaitItem().also { state ->
- state.eventSink(KnockRequestsBannerEvents.AcceptSingleRequest)
+ state.eventSink(KnockRequestsBannerEvent.AcceptSingleRequest)
}
awaitItem().also { state ->
assertThat(state.isVisible).isFalse()
@@ -182,7 +182,7 @@ import org.junit.Test
skipItems(2)
awaitItem().also { state ->
assertThat(state.knockRequests).hasSize(1)
- state.eventSink(KnockRequestsBannerEvents.AcceptSingleRequest)
+ state.eventSink(KnockRequestsBannerEvent.AcceptSingleRequest)
}
awaitItem().also { state ->
assertThat(state.isVisible).isFalse()
@@ -206,7 +206,7 @@ import org.junit.Test
presenter.test {
skipItems(2)
awaitItem().also { state ->
- state.eventSink(KnockRequestsBannerEvents.Dismiss)
+ state.eventSink(KnockRequestsBannerEvent.Dismiss)
}
advanceUntilIdle()
assert(markAsSeenLambda).isCalledExactly(3)
diff --git a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerViewTest.kt b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerViewTest.kt
index f55ccb0cef..441b782a4a 100644
--- a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerViewTest.kt
+++ b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerViewTest.kt
@@ -29,7 +29,7 @@ import org.junit.Test
class KnockRequestsBannerViewTest : RobolectricTest() {
@Test
fun `clicking on view on single request invoke the expected callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce {
setKnockRequestsBannerView(
state = aKnockRequestsBannerState(
@@ -43,7 +43,7 @@ class KnockRequestsBannerViewTest : RobolectricTest() {
@Test
fun `clicking on view all when multiple requests invoke the expected callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce {
setKnockRequestsBannerView(
state = aKnockRequestsBannerState(
@@ -62,19 +62,19 @@ class KnockRequestsBannerViewTest : RobolectricTest() {
@Test
fun `clicking on accept on a single request emit the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setKnockRequestsBannerView(
state = aKnockRequestsBannerState(
eventSink = eventsRecorder,
),
)
clickOn(CommonStrings.action_accept)
- eventsRecorder.assertSingle(KnockRequestsBannerEvents.AcceptSingleRequest)
+ eventsRecorder.assertSingle(KnockRequestsBannerEvent.AcceptSingleRequest)
}
@Test
fun `clicking on dismiss emit the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setKnockRequestsBannerView(
state = aKnockRequestsBannerState(
eventSink = eventsRecorder,
@@ -82,7 +82,7 @@ class KnockRequestsBannerViewTest : RobolectricTest() {
)
val close = activity!!.getString(CommonStrings.action_close)
onNodeWithContentDescription(close).performClick()
- eventsRecorder.assertSingle(KnockRequestsBannerEvents.Dismiss)
+ eventsRecorder.assertSingle(KnockRequestsBannerEvent.Dismiss)
}
}
diff --git a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt
index 209e67cadf..dc04889d32 100644
--- a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt
+++ b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt
@@ -65,7 +65,7 @@ class KnockRequestsListPresenterTest {
skipItems(2)
awaitItem().also { state ->
val knockRequestPresentable = state.knockRequests.dataOrNull()?.first()!!
- state.eventSink(KnockRequestsListEvents.Accept(knockRequestPresentable))
+ state.eventSink(KnockRequestsListEvent.Accept(knockRequestPresentable))
}
skipItems(1)
awaitItem().also { state ->
@@ -75,7 +75,7 @@ class KnockRequestsListPresenterTest {
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Success::class.java)
- state.eventSink(KnockRequestsListEvents.ResetCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ResetCurrentAction)
}
skipItems(2)
awaitItem().also { state ->
@@ -99,7 +99,7 @@ class KnockRequestsListPresenterTest {
skipItems(2)
awaitItem().also { state ->
val knockRequestPresentable = state.knockRequests.dataOrNull()?.first()!!
- state.eventSink(KnockRequestsListEvents.Accept(knockRequestPresentable))
+ state.eventSink(KnockRequestsListEvent.Accept(knockRequestPresentable))
}
skipItems(1)
awaitItem().also { state ->
@@ -109,14 +109,14 @@ class KnockRequestsListPresenterTest {
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Failure::class.java)
- state.eventSink(KnockRequestsListEvents.RetryCurrentAction)
+ state.eventSink(KnockRequestsListEvent.RetryCurrentAction)
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Loading::class.java)
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Failure::class.java)
- state.eventSink(KnockRequestsListEvents.ResetCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ResetCurrentAction)
}
skipItems(1)
awaitItem().also { state ->
@@ -140,21 +140,21 @@ class KnockRequestsListPresenterTest {
skipItems(2)
awaitItem().also { state ->
val knockRequestPresentable = state.knockRequests.dataOrNull()?.first()!!
- state.eventSink(KnockRequestsListEvents.Decline(knockRequestPresentable))
+ state.eventSink(KnockRequestsListEvent.Decline(knockRequestPresentable))
}
skipItems(1)
awaitItem().also { state ->
val knockRequestPresentable = state.knockRequests.dataOrNull()?.first()!!
assertThat(state.currentAction).isEqualTo(KnockRequestsAction.Decline(knockRequestPresentable))
assertThat(state.asyncAction).isInstanceOf(AsyncAction.ConfirmingNoParams::class.java)
- state.eventSink(KnockRequestsListEvents.ConfirmCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ConfirmCurrentAction)
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Loading::class.java)
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Success::class.java)
- state.eventSink(KnockRequestsListEvents.ResetCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ResetCurrentAction)
}
skipItems(2)
awaitItem().also { state ->
@@ -178,21 +178,21 @@ class KnockRequestsListPresenterTest {
skipItems(2)
awaitItem().also { state ->
val knockRequestPresentable = state.knockRequests.dataOrNull()?.first()!!
- state.eventSink(KnockRequestsListEvents.DeclineAndBan(knockRequestPresentable))
+ state.eventSink(KnockRequestsListEvent.DeclineAndBan(knockRequestPresentable))
}
skipItems(1)
awaitItem().also { state ->
val knockRequestPresentable = state.knockRequests.dataOrNull()?.first()!!
assertThat(state.currentAction).isEqualTo(KnockRequestsAction.DeclineAndBan(knockRequestPresentable))
assertThat(state.asyncAction).isInstanceOf(AsyncAction.ConfirmingNoParams::class.java)
- state.eventSink(KnockRequestsListEvents.ConfirmCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ConfirmCurrentAction)
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Loading::class.java)
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Success::class.java)
- state.eventSink(KnockRequestsListEvents.ResetCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ResetCurrentAction)
}
skipItems(2)
awaitItem().also { state ->
@@ -220,20 +220,20 @@ class KnockRequestsListPresenterTest {
skipItems(2)
awaitItem().also { state ->
assertThat(state.canAcceptAll).isTrue()
- state.eventSink(KnockRequestsListEvents.AcceptAll)
+ state.eventSink(KnockRequestsListEvent.AcceptAll)
}
skipItems(1)
awaitItem().also { state ->
assertThat(state.currentAction).isEqualTo(KnockRequestsAction.AcceptAll)
assertThat(state.asyncAction).isInstanceOf(AsyncAction.ConfirmingNoParams::class.java)
- state.eventSink(KnockRequestsListEvents.ConfirmCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ConfirmCurrentAction)
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Loading::class.java)
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Success::class.java)
- state.eventSink(KnockRequestsListEvents.ResetCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ResetCurrentAction)
}
skipItems(2)
awaitItem().also { state ->
@@ -262,20 +262,20 @@ class KnockRequestsListPresenterTest {
skipItems(2)
awaitItem().also { state ->
assertThat(state.canAcceptAll).isTrue()
- state.eventSink(KnockRequestsListEvents.AcceptAll)
+ state.eventSink(KnockRequestsListEvent.AcceptAll)
}
skipItems(1)
awaitItem().also { state ->
assertThat(state.currentAction).isEqualTo(KnockRequestsAction.AcceptAll)
assertThat(state.asyncAction).isInstanceOf(AsyncAction.ConfirmingNoParams::class.java)
- state.eventSink(KnockRequestsListEvents.ConfirmCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ConfirmCurrentAction)
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Loading::class.java)
}
awaitItem().also { state ->
assertThat(state.asyncAction).isInstanceOf(AsyncAction.Failure::class.java)
- state.eventSink(KnockRequestsListEvents.ResetCurrentAction)
+ state.eventSink(KnockRequestsListEvent.ResetCurrentAction)
}
skipItems(2)
awaitItem().also { state ->
diff --git a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListViewTest.kt b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListViewTest.kt
index 1fbcb67b21..c1caaddb1e 100644
--- a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListViewTest.kt
+++ b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListViewTest.kt
@@ -31,7 +31,7 @@ import org.junit.Test
class KnockRequestsListViewTest : RobolectricTest() {
@Test
fun `clicking on back invoke the expected callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce {
setKnockRequestsListView(
aKnockRequestsListState(
@@ -45,7 +45,7 @@ class KnockRequestsListViewTest : RobolectricTest() {
@Test
fun `clicking on accept emit the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val knockRequest = aKnockRequestPresentable()
setKnockRequestsListView(
aKnockRequestsListState(
@@ -54,12 +54,12 @@ class KnockRequestsListViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_accept)
- eventsRecorder.assertSingle(KnockRequestsListEvents.Accept(knockRequest))
+ eventsRecorder.assertSingle(KnockRequestsListEvent.Accept(knockRequest))
}
@Test
fun `clicking on decline emit the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val knockRequest = aKnockRequestPresentable()
setKnockRequestsListView(
aKnockRequestsListState(
@@ -68,12 +68,12 @@ class KnockRequestsListViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_decline)
- eventsRecorder.assertSingle(KnockRequestsListEvents.Decline(knockRequest))
+ eventsRecorder.assertSingle(KnockRequestsListEvent.Decline(knockRequest))
}
@Test
fun `clicking on decline and ban emit the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val knockRequest = aKnockRequestPresentable()
setKnockRequestsListView(
aKnockRequestsListState(
@@ -82,12 +82,12 @@ class KnockRequestsListViewTest : RobolectricTest() {
),
)
clickOn(R.string.screen_knock_requests_list_decline_and_ban_action_title)
- eventsRecorder.assertSingle(KnockRequestsListEvents.DeclineAndBan(knockRequest))
+ eventsRecorder.assertSingle(KnockRequestsListEvent.DeclineAndBan(knockRequest))
}
@Test
fun `clicking on accept all emit the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val knockRequests = persistentListOf(aKnockRequestPresentable(), aKnockRequestPresentable())
setKnockRequestsListView(
aKnockRequestsListState(
@@ -96,12 +96,12 @@ class KnockRequestsListViewTest : RobolectricTest() {
),
)
clickOn(R.string.screen_knock_requests_list_accept_all_button_title)
- eventsRecorder.assertSingle(KnockRequestsListEvents.AcceptAll)
+ eventsRecorder.assertSingle(KnockRequestsListEvent.AcceptAll)
}
@Test
fun `retry on async view retry emit the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val knockRequests = persistentListOf(aKnockRequestPresentable(), aKnockRequestPresentable())
setKnockRequestsListView(
aKnockRequestsListState(
@@ -112,12 +112,12 @@ class KnockRequestsListViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_retry)
- eventsRecorder.assertSingle(KnockRequestsListEvents.RetryCurrentAction)
+ eventsRecorder.assertSingle(KnockRequestsListEvent.RetryCurrentAction)
}
@Test
fun `canceling async view emit the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val knockRequests = persistentListOf(aKnockRequestPresentable(), aKnockRequestPresentable())
setKnockRequestsListView(
aKnockRequestsListState(
@@ -128,12 +128,12 @@ class KnockRequestsListViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_cancel)
- eventsRecorder.assertSingle(KnockRequestsListEvents.ResetCurrentAction)
+ eventsRecorder.assertSingle(KnockRequestsListEvent.ResetCurrentAction)
}
@Test
fun `confirming async view emit the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val knockRequests = persistentListOf(aKnockRequestPresentable(), aKnockRequestPresentable())
setKnockRequestsListView(
aKnockRequestsListState(
@@ -144,7 +144,7 @@ class KnockRequestsListViewTest : RobolectricTest() {
),
)
clickOn(R.string.screen_knock_requests_list_accept_all_alert_confirm_button_title)
- eventsRecorder.assertSingle(KnockRequestsListEvents.ConfirmCurrentAction)
+ eventsRecorder.assertSingle(KnockRequestsListEvent.ConfirmCurrentAction)
}
}
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/DefaultPermissionsPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/DefaultPermissionsPresenter.kt
index 5aa7ae6f63..01fa8bca7e 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/DefaultPermissionsPresenter.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/DefaultPermissionsPresenter.kt
@@ -41,9 +41,9 @@ class DefaultPermissionsPresenter(
permissionsRequested = true
}
- fun handleEvent(event: PermissionsEvents) {
+ fun handleEvent(event: PermissionsEvent) {
when (event) {
- PermissionsEvents.RequestPermissions -> {
+ PermissionsEvent.RequestPermissions -> {
multiplePermissionsState.launchMultiplePermissionRequest()
}
}
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/PermissionsEvents.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/PermissionsEvent.kt
similarity index 77%
rename from features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/PermissionsEvents.kt
rename to features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/PermissionsEvent.kt
index a4b5ef1228..226909af5d 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/PermissionsEvents.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/PermissionsEvent.kt
@@ -8,6 +8,6 @@
package io.element.android.features.location.impl.common.permissions
-sealed interface PermissionsEvents {
- data object RequestPermissions : PermissionsEvents
+sealed interface PermissionsEvent {
+ data object RequestPermissions : PermissionsEvent
}
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/PermissionsState.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/PermissionsState.kt
index 25ceb3ba29..a8dfd571e5 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/PermissionsState.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/common/permissions/PermissionsState.kt
@@ -12,7 +12,7 @@ data class PermissionsState(
val permissions: Permissions,
val shouldShowRationale: Boolean,
val permissionsAlreadyRequested: Boolean,
- val eventSink: (PermissionsEvents) -> Unit,
+ val eventSink: (PermissionsEvent) -> Unit,
) {
sealed interface Permissions {
data object AllGranted : Permissions
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt
index 55f1e088d2..ccdf598e93 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt
@@ -29,7 +29,7 @@ import io.element.android.features.location.impl.common.MapDefaults
import io.element.android.features.location.impl.common.SendLiveLocationPermissions
import io.element.android.features.location.impl.common.actions.LocationActions
import io.element.android.features.location.impl.common.checkLocationConstraints
-import io.element.android.features.location.impl.common.permissions.PermissionsEvents
+import io.element.android.features.location.impl.common.permissions.PermissionsEvent
import io.element.android.features.location.impl.common.permissions.PermissionsPresenter
import io.element.android.features.location.impl.common.permissions.PermissionsState
import io.element.android.features.location.impl.common.sendLiveLocationPermissions
@@ -111,7 +111,7 @@ class ShareLocationPresenter(
sendLiveLocationPermissions = SendLiveLocationPermissions.GRANTED
)
if (locationConstraints is LocationConstraintsCheck.PermissionShouldBeRequested) {
- permissionsState.eventSink(PermissionsEvents.RequestPermissions)
+ permissionsState.eventSink(PermissionsEvent.RequestPermissions)
}
trackUserPosition = locationConstraints is LocationConstraintsCheck.Success
dialogState = ShareLocationState.Dialog.Constraints(locationConstraints.toDialogState())
@@ -137,7 +137,7 @@ class ShareLocationPresenter(
}
else -> {
if (locationConstraints is LocationConstraintsCheck.PermissionShouldBeRequested) {
- permissionsState.eventSink(PermissionsEvents.RequestPermissions)
+ permissionsState.eventSink(PermissionsEvent.RequestPermissions)
}
dialogState = ShareLocationState.Dialog.Constraints(locationConstraints.toDialogState())
}
@@ -195,7 +195,7 @@ class ShareLocationPresenter(
}
ShareLocationEvent.RequestPermissions -> {
dialogState = ShareLocationState.Dialog.None
- permissionsState.eventSink(PermissionsEvents.RequestPermissions)
+ permissionsState.eventSink(PermissionsEvent.RequestPermissions)
}
}
}
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt
index bbec7b449f..412e96eb9c 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenter.kt
@@ -32,7 +32,7 @@ import io.element.android.features.location.impl.common.MapDefaults
import io.element.android.features.location.impl.common.SendLiveLocationPermissions
import io.element.android.features.location.impl.common.actions.LocationActions
import io.element.android.features.location.impl.common.checkLocationConstraints
-import io.element.android.features.location.impl.common.permissions.PermissionsEvents
+import io.element.android.features.location.impl.common.permissions.PermissionsEvent
import io.element.android.features.location.impl.common.permissions.PermissionsPresenter
import io.element.android.features.location.impl.common.permissions.PermissionsState
import io.element.android.features.location.impl.common.toDialogState
@@ -99,7 +99,7 @@ class ShowLocationPresenter(
sendLiveLocationPermissions = SendLiveLocationPermissions.GRANTED
)
if (locationConstraints is LocationConstraintsCheck.PermissionShouldBeRequested) {
- permissionsState.eventSink(PermissionsEvents.RequestPermissions)
+ permissionsState.eventSink(PermissionsEvent.RequestPermissions)
}
isTrackMyLocation = locationConstraints is LocationConstraintsCheck.Success
dialogState = locationConstraints.toDialogState()
@@ -130,7 +130,7 @@ class ShowLocationPresenter(
locationActions.openLocationSettings()
dialogState = LocationConstraintsDialogState.None
}
- ShowLocationEvent.RequestPermissions -> permissionsState.eventSink(PermissionsEvents.RequestPermissions)
+ ShowLocationEvent.RequestPermissions -> permissionsState.eventSink(PermissionsEvent.RequestPermissions)
ShowLocationEvent.StopLocationSharing -> coroutineScope.launch {
liveLocationShareManager.stopShare(joinedRoom.roomId)
}
diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/permissions/FakePermissionsPresenter.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/permissions/FakePermissionsPresenter.kt
index 9b8ff7a29a..c25cbc24fc 100644
--- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/permissions/FakePermissionsPresenter.kt
+++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/common/permissions/FakePermissionsPresenter.kt
@@ -11,9 +11,9 @@ package io.element.android.features.location.impl.common.permissions
import androidx.compose.runtime.Composable
class FakePermissionsPresenter : PermissionsPresenter {
- val events = mutableListOf()
+ val events = mutableListOf()
- private fun handleEvent(event: PermissionsEvents) {
+ private fun handleEvent(event: PermissionsEvent) {
events += event
}
diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt
index d249fdaf69..7500d29616 100644
--- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt
+++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt
@@ -26,7 +26,7 @@ import io.element.android.features.location.impl.aPermissionsState
import io.element.android.features.location.impl.common.FakeUserLocationStateFactory
import io.element.android.features.location.impl.common.actions.FakeLocationActions
import io.element.android.features.location.impl.common.permissions.FakePermissionsPresenter
-import io.element.android.features.location.impl.common.permissions.PermissionsEvents
+import io.element.android.features.location.impl.common.permissions.PermissionsEvent
import io.element.android.features.location.impl.common.permissions.PermissionsState
import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState
import io.element.android.features.location.impl.live.LiveLocationStore
@@ -174,7 +174,7 @@ class ShareLocationPresenterTest {
shareLocationPresenter.test {
skipItems(2)
cancelAndIgnoreRemainingEvents()
- assertThat(fakePermissionsPresenter.events).contains(PermissionsEvents.RequestPermissions)
+ assertThat(fakePermissionsPresenter.events).contains(PermissionsEvent.RequestPermissions)
}
}
@@ -298,7 +298,7 @@ class ShareLocationPresenterTest {
// Wait for dialog to be dismissed
awaitItem()
- assertThat(fakePermissionsPresenter.events.last()).isEqualTo(PermissionsEvents.RequestPermissions)
+ assertThat(fakePermissionsPresenter.events.last()).isEqualTo(PermissionsEvent.RequestPermissions)
cancelAndIgnoreRemainingEvents()
}
}
diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt
index 7d9b0d5e03..1fab0d98af 100644
--- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt
+++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/show/ShowLocationPresenterTest.kt
@@ -20,7 +20,7 @@ import io.element.android.features.location.impl.aPermissionsState
import io.element.android.features.location.impl.common.FakeUserLocationStateFactory
import io.element.android.features.location.impl.common.actions.FakeLocationActions
import io.element.android.features.location.impl.common.permissions.FakePermissionsPresenter
-import io.element.android.features.location.impl.common.permissions.PermissionsEvents
+import io.element.android.features.location.impl.common.permissions.PermissionsEvent
import io.element.android.features.location.impl.common.permissions.PermissionsState
import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState
import io.element.android.features.location.test.FakeActiveLiveLocationShareManager
@@ -188,7 +188,7 @@ class ShowLocationPresenterTest {
// Continue the dialog sends permission request to the permissions presenter
trackLocationState.eventSink(ShowLocationEvent.RequestPermissions)
- assertThat(fakePermissionsPresenter.events.last()).isEqualTo(PermissionsEvents.RequestPermissions)
+ assertThat(fakePermissionsPresenter.events.last()).isEqualTo(PermissionsEvent.RequestPermissions)
}
}
@@ -208,7 +208,7 @@ class ShowLocationPresenterTest {
initialState.eventSink(ShowLocationEvent.TrackMyLocation(true))
- assertThat(fakePermissionsPresenter.events).contains(PermissionsEvents.RequestPermissions)
+ assertThat(fakePermissionsPresenter.events).contains(PermissionsEvent.RequestPermissions)
cancelAndIgnoreRemainingEvents()
}
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerEvents.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerEvent.kt
similarity index 83%
rename from features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerEvents.kt
rename to features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerEvent.kt
index 4f0d228dd2..f3fd02713f 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerEvents.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerEvent.kt
@@ -10,9 +10,9 @@ package io.element.android.features.login.impl.changeserver
import io.element.android.features.login.impl.accountprovider.AccountProvider
-sealed interface ChangeServerEvents {
- data class ChangeServer(val accountProvider: AccountProvider) : ChangeServerEvents
- data object ClearError : ChangeServerEvents
- data object RequestLocalNetworkPermission : ChangeServerEvents
- data object DismissLocalNetworkPermission : ChangeServerEvents
+sealed interface ChangeServerEvent {
+ data class ChangeServer(val accountProvider: AccountProvider) : ChangeServerEvent
+ data object ClearError : ChangeServerEvent
+ data object RequestLocalNetworkPermission : ChangeServerEvent
+ data object DismissLocalNetworkPermission : ChangeServerEvent
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt
index b7b04beeb2..9106d6e1c4 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt
@@ -42,12 +42,12 @@ class ChangeServerPresenter(
onProceed = { provider -> changeServer(provider, changeServerAction) },
)
- fun handleEvent(event: ChangeServerEvents) {
+ fun handleEvent(event: ChangeServerEvent) {
when (event) {
- ChangeServerEvents.ClearError -> changeServerAction.value = AsyncData.Uninitialized
- is ChangeServerEvents.ChangeServer -> gateState.submit(event.accountProvider)
- ChangeServerEvents.DismissLocalNetworkPermission -> gateState.abort()
- ChangeServerEvents.RequestLocalNetworkPermission -> gateState.requestPermission()
+ ChangeServerEvent.ClearError -> changeServerAction.value = AsyncData.Uninitialized
+ is ChangeServerEvent.ChangeServer -> gateState.submit(event.accountProvider)
+ ChangeServerEvent.DismissLocalNetworkPermission -> gateState.abort()
+ ChangeServerEvent.RequestLocalNetworkPermission -> gateState.requestPermission()
}
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerState.kt
index 3b4f4d9dad..1b69551e94 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerState.kt
@@ -17,5 +17,5 @@ data class ChangeServerState(
// configuring (and re-networking) the homeserver a second time.
val changeServerAction: AsyncData,
val localNetworkPermissionDialog: LocalNetworkPermissionDialog,
- val eventSink: (ChangeServerEvents) -> Unit
+ val eventSink: (ChangeServerEvent) -> Unit
)
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt
index 8e726c7fe1..e629c6bce3 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt
@@ -47,7 +47,7 @@ fun ChangeServerView(
modifier = modifier,
content = stringResource(R.string.screen_change_server_error_invalid_homeserver),
onSubmit = {
- eventSink.invoke(ChangeServerEvents.ClearError)
+ eventSink.invoke(ChangeServerEvent.ClearError)
}
)
ChangeServerError.UnsupportedServer ->
@@ -55,7 +55,7 @@ fun ChangeServerView(
modifier = modifier,
content = stringResource(R.string.screen_login_error_unsupported_authentication),
onSubmit = {
- eventSink.invoke(ChangeServerEvents.ClearError)
+ eventSink.invoke(ChangeServerEvent.ClearError)
}
)
is ChangeServerError.Error -> {
@@ -63,7 +63,7 @@ fun ChangeServerView(
modifier = modifier,
content = error.messageStr ?: stringResource(CommonStrings.error_unknown),
onSubmit = {
- eventSink.invoke(ChangeServerEvents.ClearError)
+ eventSink.invoke(ChangeServerEvent.ClearError)
}
)
}
@@ -72,10 +72,10 @@ fun ChangeServerView(
modifier = modifier,
onLearnMoreClick = {
onLearnMoreClick()
- eventSink.invoke(ChangeServerEvents.ClearError)
+ eventSink.invoke(ChangeServerEvent.ClearError)
},
onDismiss = {
- eventSink.invoke(ChangeServerEvents.ClearError)
+ eventSink.invoke(ChangeServerEvent.ClearError)
}
)
}
@@ -90,10 +90,10 @@ fun ChangeServerView(
submitText = stringResource(R.string.screen_change_server_error_element_pro_required_action_android),
onSubmitClick = {
context.openGooglePlay(error.applicationId)
- eventSink.invoke(ChangeServerEvents.ClearError)
+ eventSink.invoke(ChangeServerEvent.ClearError)
},
onDismiss = {
- eventSink.invoke(ChangeServerEvents.ClearError)
+ eventSink.invoke(ChangeServerEvent.ClearError)
},
)
}
@@ -106,7 +106,7 @@ fun ChangeServerView(
error.unauthorisedAccountProviderTitle,
),
onSubmit = {
- eventSink.invoke(ChangeServerEvents.ClearError)
+ eventSink.invoke(ChangeServerEvent.ClearError)
}
)
}
@@ -125,10 +125,10 @@ fun ChangeServerView(
LocalNetworkPermissionDialogView(
dialog = state.localNetworkPermissionDialog,
onSubmit = {
- eventSink.invoke(ChangeServerEvents.RequestLocalNetworkPermission)
+ eventSink.invoke(ChangeServerEvent.RequestLocalNetworkPermission)
},
onDismiss = {
- eventSink.invoke(ChangeServerEvents.DismissLocalNetworkPermission)
+ eventSink.invoke(ChangeServerEvent.DismissLocalNetworkPermission)
}
)
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderEvents.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderEvent.kt
similarity index 69%
rename from features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderEvents.kt
rename to features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderEvent.kt
index f60cc3e9da..bb50f123cb 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderEvents.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderEvent.kt
@@ -10,8 +10,8 @@ package io.element.android.features.login.impl.screens.chooseaccountprovider
import io.element.android.features.login.impl.accountprovider.AccountProvider
-sealed interface ChooseAccountProviderEvents {
- data class SelectAccountProvider(val accountProvider: AccountProvider) : ChooseAccountProviderEvents
- data object Continue : ChooseAccountProviderEvents
- data object ClearError : ChooseAccountProviderEvents
+sealed interface ChooseAccountProviderEvent {
+ data class SelectAccountProvider(val accountProvider: AccountProvider) : ChooseAccountProviderEvent
+ data object Continue : ChooseAccountProviderEvent
+ data object ClearError : ChooseAccountProviderEvent
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderPresenter.kt
index 92c3ff0fff..e2863a295a 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderPresenter.kt
@@ -34,9 +34,9 @@ class ChooseAccountProviderPresenter(
val loginModeState = loginModePresenter.present()
var selectedAccountProvider: AccountProvider? by remember { mutableStateOf(null) }
- fun handleEvent(event: ChooseAccountProviderEvents) {
+ fun handleEvent(event: ChooseAccountProviderEvent) {
when (event) {
- ChooseAccountProviderEvents.Continue -> {
+ ChooseAccountProviderEvent.Continue -> {
selectedAccountProvider?.let { provider ->
loginModeState.eventSink(
LoginModeEvent.Submit(
@@ -48,13 +48,13 @@ class ChooseAccountProviderPresenter(
)
}
}
- is ChooseAccountProviderEvents.SelectAccountProvider -> {
+ is ChooseAccountProviderEvent.SelectAccountProvider -> {
// Ensure that the user does not change the server during processing.
if (loginModeState.loginMode is AsyncData.Uninitialized) {
selectedAccountProvider = event.accountProvider
}
}
- ChooseAccountProviderEvents.ClearError -> loginModeState.eventSink(LoginModeEvent.ClearError)
+ ChooseAccountProviderEvent.ClearError -> loginModeState.eventSink(LoginModeEvent.ClearError)
}
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderState.kt
index a31e5c464f..398e32d687 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderState.kt
@@ -17,7 +17,7 @@ data class ChooseAccountProviderState(
val accountProviders: ImmutableList,
val selectedAccountProvider: AccountProvider?,
val loginModeState: LoginModeState,
- val eventSink: (ChooseAccountProviderEvents) -> Unit,
+ val eventSink: (ChooseAccountProviderEvent) -> Unit,
) {
val submitEnabled: Boolean
get() = selectedAccountProvider != null &&
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderStatePreviewParam.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderStatePreviewParam.kt
index 207f434b42..ceb1cfd6ea 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderStatePreviewParam.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderStatePreviewParam.kt
@@ -71,7 +71,7 @@ fun aChooseAccountProviderState(
),
selectedAccountProvider: AccountProvider? = null,
loginModeState: LoginModeState = aLoginModeState(),
- eventSink: (ChooseAccountProviderEvents) -> Unit = {},
+ eventSink: (ChooseAccountProviderEvent) -> Unit = {},
) = ChooseAccountProviderState(
accountProviders = accountProviders.toImmutableList(),
selectedAccountProvider = selectedAccountProvider,
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderView.kt
index fdc69ca295..552165a7b2 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderView.kt
@@ -108,7 +108,7 @@ fun ChooseAccountProviderView(
item = alteredItem,
selected = item == state.selectedAccountProvider,
onClick = {
- state.eventSink(ChooseAccountProviderEvents.SelectAccountProvider(item))
+ state.eventSink(ChooseAccountProviderEvent.SelectAccountProvider(item))
}
)
}
@@ -119,7 +119,7 @@ fun ChooseAccountProviderView(
text = stringResource(id = CommonStrings.action_continue),
showProgress = isLoading,
onClick = {
- state.eventSink(ChooseAccountProviderEvents.Continue)
+ state.eventSink(ChooseAccountProviderEvent.Continue)
},
enabled = state.submitEnabled || isLoading,
modifier = Modifier
@@ -131,7 +131,7 @@ fun ChooseAccountProviderView(
LoginModeView(
loginMode = state.loginModeState.loginMode,
onClearError = {
- state.eventSink(ChooseAccountProviderEvents.ClearError)
+ state.eventSink(ChooseAccountProviderEvent.ClearError)
},
onLearnMoreClick = onLearnMoreClick,
onOAuthDetails = onOAuthDetails,
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderEvents.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderEvent.kt
similarity index 81%
rename from features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderEvents.kt
rename to features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderEvent.kt
index 9093a8121f..24b6fdfcda 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderEvents.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderEvent.kt
@@ -8,11 +8,11 @@
package io.element.android.features.login.impl.screens.confirmaccountprovider
-sealed interface ConfirmAccountProviderEvents {
- data class UserInputChanged(val accountProvider: String) : ConfirmAccountProviderEvents
+sealed interface ConfirmAccountProviderEvent {
+ data class UserInputChanged(val accountProvider: String) : ConfirmAccountProviderEvent
// Carries the account provider to submit (the current field text, or the accepted autocomplete suggestion),
// captured from the view at click time so it can't lag behind fast input (e.g. keyboard autofill).
- data class Continue(val accountProvider: String) : ConfirmAccountProviderEvents
- data object ClearError : ConfirmAccountProviderEvents
+ data class Continue(val accountProvider: String) : ConfirmAccountProviderEvent
+ data object ClearError : ConfirmAccountProviderEvent
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt
index 5c66f8f446..627620ff31 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt
@@ -24,7 +24,7 @@ import io.element.android.appconfig.AuthenticationConfig
import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.features.login.impl.accountprovider.AccountProvider
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
-import io.element.android.features.login.impl.changeserver.ChangeServerEvents
+import io.element.android.features.login.impl.changeserver.ChangeServerEvent
import io.element.android.features.login.impl.changeserver.ChangeServerState
import io.element.android.features.login.impl.login.LoginModeEvent
import io.element.android.features.login.impl.login.LoginModeState
@@ -110,14 +110,14 @@ class ConfirmAccountProviderPresenter(
}
}
- fun handleEvent(event: ConfirmAccountProviderEvents) {
+ fun handleEvent(event: ConfirmAccountProviderEvent) {
when (event) {
- is ConfirmAccountProviderEvents.UserInputChanged -> {
+ is ConfirmAccountProviderEvent.UserInputChanged -> {
userInput = event.accountProvider
}
// Validate (and persist) the chosen account provider before proceeding. This also enforces the
// account-provider access control, which the login submit does not run on its own.
- is ConfirmAccountProviderEvents.Continue -> {
+ is ConfirmAccountProviderEvent.Continue -> {
// Apply the accepted account provider (any accepted completion) back into the field so it
// renders the full server rather than the typed prefix, and survives the OAuth round-trip.
val accountProvider = event.accountProvider.trim()
@@ -134,12 +134,12 @@ class ConfirmAccountProviderPresenter(
val accountProviderUrl = host.ensureProtocol()
submittedAccountProvider = accountProviderUrl
changeServerState.eventSink(
- ChangeServerEvents.ChangeServer(AccountProvider(url = accountProviderUrl))
+ ChangeServerEvent.ChangeServer(AccountProvider(url = accountProviderUrl))
)
}
- ConfirmAccountProviderEvents.ClearError -> {
+ ConfirmAccountProviderEvent.ClearError -> {
loginModeState.eventSink(LoginModeEvent.ClearError)
- changeServerState.eventSink(ChangeServerEvents.ClearError)
+ changeServerState.eventSink(ChangeServerEvent.ClearError)
}
}
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderState.kt
index bf6b0cb0e7..eec082d886 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderState.kt
@@ -19,7 +19,7 @@ data class ConfirmAccountProviderState(
val isAccountCreation: Boolean,
val loginModeState: LoginModeState,
val changeServerState: ChangeServerState,
- val eventSink: (ConfirmAccountProviderEvents) -> Unit
+ val eventSink: (ConfirmAccountProviderEvent) -> Unit
) {
val submitEnabled: Boolean
get() = accountProviderInput.isNotBlank() &&
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderStatePreviewParam.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderStatePreviewParam.kt
index ab6350bb4d..be85a306ba 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderStatePreviewParam.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderStatePreviewParam.kt
@@ -40,7 +40,7 @@ private fun aConfirmAccountProviderState(
isAccountCreation: Boolean = false,
loginModeState: LoginModeState = aLoginModeState(),
changeServerState: ChangeServerState = aChangeServerState(),
- eventSink: (ConfirmAccountProviderEvents) -> Unit = {},
+ eventSink: (ConfirmAccountProviderEvent) -> Unit = {},
) = ConfirmAccountProviderState(
accountProviderInput = accountProviderInput,
accountProviderSuggestion = accountProviderSuggestion,
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt
index 1dab5cd31c..3f08b269a1 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt
@@ -99,7 +99,7 @@ fun ConfirmAccountProviderView(
// Dismiss the keyboard and release focus while the account provider is being validated.
focusManager.clearFocus(force = true)
// Submit the exact field text (plus any accepted suggestion).
- eventSink(ConfirmAccountProviderEvents.Continue(accountProviderToSubmit))
+ eventSink(ConfirmAccountProviderEvent.Continue(accountProviderToSubmit))
}
// Once a validation / login error has been dismissed, return focus and the keyboard to the field so
@@ -115,6 +115,9 @@ fun ConfirmAccountProviderView(
HeaderFooterPage(
modifier = modifier,
+ // Let the header and content scroll so the supporting text is not clipped by the footer when the
+ // keyboard is visible and vertical space is reduced.
+ isScrollable = true,
header = {
IconTitleSubtitleMolecule(
modifier = Modifier.padding(top = 60.dp),
@@ -151,7 +154,7 @@ fun ConfirmAccountProviderView(
value = input,
onValueChange = {
input = it
- eventSink(ConfirmAccountProviderEvents.UserInputChanged(it))
+ eventSink(ConfirmAccountProviderEvent.UserInputChanged(it))
},
modifier = Modifier
.fillMaxWidth()
@@ -181,7 +184,7 @@ fun ConfirmAccountProviderView(
// showing, Done submits directly.
val accepted = input + suggestionSuffix
input = accepted
- eventSink(ConfirmAccountProviderEvents.UserInputChanged(accepted))
+ eventSink(ConfirmAccountProviderEvent.UserInputChanged(accepted))
focusManager.clearFocus(force = true)
} else {
submit()
@@ -197,7 +200,7 @@ fun ConfirmAccountProviderView(
role = Role.Button,
) {
input = ""
- eventSink(ConfirmAccountProviderEvents.UserInputChanged(""))
+ eventSink(ConfirmAccountProviderEvent.UserInputChanged(""))
}
) {
Icon(
@@ -222,7 +225,7 @@ fun ConfirmAccountProviderView(
LoginModeView(
loginMode = state.loginModeState.loginMode,
- onClearError = { eventSink(ConfirmAccountProviderEvents.ClearError) },
+ onClearError = { eventSink(ConfirmAccountProviderEvent.ClearError) },
onLearnMoreClick = onLearnMoreClick,
onOAuthDetails = onOAuthDetails,
onNeedLoginPassword = onNeedLoginPassword,
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordEvents.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordEvent.kt
similarity index 64%
rename from features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordEvents.kt
rename to features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordEvent.kt
index 25a003b531..fa9acb5632 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordEvents.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordEvent.kt
@@ -8,9 +8,9 @@
package io.element.android.features.login.impl.screens.loginpassword
-sealed interface LoginPasswordEvents {
- data class SetLogin(val login: String) : LoginPasswordEvents
- data class SetPassword(val password: String) : LoginPasswordEvents
- data object Submit : LoginPasswordEvents
- data object ClearError : LoginPasswordEvents
+sealed interface LoginPasswordEvent {
+ data class SetLogin(val login: String) : LoginPasswordEvent
+ data class SetPassword(val password: String) : LoginPasswordEvent
+ data object Submit : LoginPasswordEvent
+ data object ClearError : LoginPasswordEvent
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenter.kt
index 6e28bd8781..864bbc7808 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenter.kt
@@ -58,18 +58,18 @@ class LoginPasswordPresenter(
}
val accountProvider by accountProviderDataSource.flow.collectAsState()
- fun handleEvent(event: LoginPasswordEvents) {
+ fun handleEvent(event: LoginPasswordEvent) {
when (event) {
- is LoginPasswordEvents.SetLogin -> updateFormState(formState) {
+ is LoginPasswordEvent.SetLogin -> updateFormState(formState) {
copy(login = event.login)
}
- is LoginPasswordEvents.SetPassword -> updateFormState(formState) {
+ is LoginPasswordEvent.SetPassword -> updateFormState(formState) {
copy(password = event.password)
}
- LoginPasswordEvents.Submit -> {
+ LoginPasswordEvent.Submit -> {
localCoroutineScope.submit(formState.value, loginAction)
}
- LoginPasswordEvents.ClearError -> loginAction.value = AsyncData.Uninitialized
+ LoginPasswordEvent.ClearError -> loginAction.value = AsyncData.Uninitialized
}
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordState.kt
index d8adc7351f..db04e7b7ba 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordState.kt
@@ -18,7 +18,7 @@ data class LoginPasswordState(
val accountProvider: AccountProvider,
val formState: LoginFormState,
val loginAction: AsyncData,
- val eventSink: (LoginPasswordEvents) -> Unit
+ val eventSink: (LoginPasswordEvent) -> Unit
) {
val submitEnabled: Boolean
get() = loginAction !is AsyncData.Failure &&
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordStatePreviewParam.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordStatePreviewParam.kt
index 4d7201dbc8..ba48e57b5d 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordStatePreviewParam.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordStatePreviewParam.kt
@@ -29,7 +29,7 @@ fun aLoginPasswordState(
accountProvider: AccountProvider = anAccountProvider(),
formState: LoginFormState = LoginFormState.Default,
loginAction: AsyncData = AsyncData.Uninitialized,
- eventSink: (LoginPasswordEvents) -> Unit = {},
+ eventSink: (LoginPasswordEvent) -> Unit = {},
) = LoginPasswordState(
accountProvider = accountProvider,
formState = formState,
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt
index a168b14cc8..9a2dc3097b 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt
@@ -97,7 +97,7 @@ fun LoginPasswordView(
autofillManager?.commit()
- state.eventSink(LoginPasswordEvents.Submit)
+ state.eventSink(LoginPasswordEvent.Submit)
}
Scaffold(
@@ -166,7 +166,7 @@ fun LoginPasswordView(
if (state.loginAction is AsyncData.Failure) {
LoginErrorDialog(error = state.loginAction.error, onDismiss = {
- state.eventSink(LoginPasswordEvents.ClearError)
+ state.eventSink(LoginPasswordEvent.ClearError)
})
}
}
@@ -202,7 +202,7 @@ private fun LoginForm(
onValueChange = {
val sanitized = it.sanitize()
loginFieldState = sanitized
- eventSink(LoginPasswordEvents.SetLogin(sanitized))
+ eventSink(LoginPasswordEvent.SetLogin(sanitized))
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email,
@@ -220,7 +220,7 @@ private fun LoginForm(
role = Role.Button,
) {
loginFieldState = ""
- eventSink(LoginPasswordEvents.SetLogin(""))
+ eventSink(LoginPasswordEvent.SetLogin(""))
}
) {
Icon(
@@ -254,7 +254,7 @@ private fun LoginForm(
onValueChange = {
val sanitized = it.sanitize()
passwordFieldState = sanitized
- eventSink(LoginPasswordEvents.SetPassword(sanitized))
+ eventSink(LoginPasswordEvent.SetPassword(sanitized))
},
placeholder = stringResource(CommonStrings.common_password),
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingEvents.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingEvent.kt
similarity index 70%
rename from features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingEvents.kt
rename to features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingEvent.kt
index 6101b21ded..4b3993e2d1 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingEvents.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingEvent.kt
@@ -8,11 +8,11 @@
package io.element.android.features.login.impl.screens.onboarding
-sealed interface OnBoardingEvents {
+sealed interface OnBoardingEvent {
data class OnSignIn(
val defaultAccountProvider: String
- ) : OnBoardingEvents
+ ) : OnBoardingEvent
- data object OnVersionClick : OnBoardingEvents
- data object ClearError : OnBoardingEvents
+ data object OnVersionClick : OnBoardingEvent
+ data object ClearError : OnBoardingEvent
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenter.kt
index e9bdb5e1e9..7e48ae22e8 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenter.kt
@@ -101,9 +101,9 @@ class OnBoardingPresenter(
val loginModeState = loginModePresenter.present()
- fun handleEvent(event: OnBoardingEvents) {
+ fun handleEvent(event: OnBoardingEvent) {
when (event) {
- is OnBoardingEvents.OnSignIn -> localCoroutineScope.launch {
+ is OnBoardingEvent.OnSignIn -> localCoroutineScope.launch {
// Ensure that the current account provider is set
accountProviderDataSource.setUrl(event.defaultAccountProvider)
loginModeState.eventSink(
@@ -115,8 +115,8 @@ class OnBoardingPresenter(
)
)
}
- OnBoardingEvents.ClearError -> loginModeState.eventSink(LoginModeEvent.ClearError)
- OnBoardingEvents.OnVersionClick -> {
+ OnBoardingEvent.ClearError -> loginModeState.eventSink(LoginModeEvent.ClearError)
+ OnBoardingEvent.OnVersionClick -> {
if (canReportBug) {
if (multipleTapToUnlock.unlock(localCoroutineScope)) {
showReportBug = true
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingState.kt
index 4fb4b8090e..97ebed67f6 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingState.kt
@@ -26,7 +26,7 @@ data class OnBoardingState(
@DrawableRes
val onBoardingLogoResId: Int?,
val loginModeState: LoginModeState,
- val eventSink: (OnBoardingEvents) -> Unit,
+ val eventSink: (OnBoardingEvent) -> Unit,
) {
val submitEnabled: Boolean
get() = defaultAccountProvider != null &&
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingStatePreviewParam.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingStatePreviewParam.kt
index d04f85f2a0..c7d89b21d5 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingStatePreviewParam.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingStatePreviewParam.kt
@@ -50,7 +50,7 @@ fun anOnBoardingState(
@DrawableRes
customLogoResId: Int? = null,
loginModeState: LoginModeState = aLoginModeState(),
- eventSink: (OnBoardingEvents) -> Unit = {},
+ eventSink: (OnBoardingEvent) -> Unit = {},
) = OnBoardingState(
isAddingAccount = isAddingAccount,
showBackButton = showBackButton,
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingView.kt
index 78faed7543..bd257d0891 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingView.kt
@@ -78,7 +78,7 @@ fun OnBoardingView(
LoginModeView(
loginMode = state.loginModeState.loginMode,
onClearError = {
- state.eventSink(OnBoardingEvents.ClearError)
+ state.eventSink(OnBoardingEvent.ClearError)
},
onLearnMoreClick = onLearnMoreClick,
onOAuthDetails = onOAuthDetails,
@@ -306,7 +306,7 @@ private fun OnBoardingButtons(
text = stringResource(id = R.string.screen_onboarding_sign_in_to, defaultAccountProvider),
showProgress = isLoading,
onClick = {
- state.eventSink(OnBoardingEvents.OnSignIn(defaultAccountProvider))
+ state.eventSink(OnBoardingEvent.OnSignIn(defaultAccountProvider))
},
enabled = state.submitEnabled || isLoading,
modifier = Modifier
@@ -336,7 +336,7 @@ private fun OnBoardingButtons(
Text(
modifier = Modifier
.clickable(role = Role.Button) {
- state.eventSink(OnBoardingEvents.OnVersionClick)
+ state.eventSink(OnBoardingEvent.OnVersionClick)
}
.padding(16.dp),
text = stringResource(id = R.string.screen_onboarding_app_version, state.version),
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroEvents.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroEvent.kt
similarity index 79%
rename from features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroEvents.kt
rename to features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroEvent.kt
index 11abd63683..a4471d8a92 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroEvents.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroEvent.kt
@@ -8,6 +8,6 @@
package io.element.android.features.login.impl.screens.qrcode.intro
-sealed interface QrCodeIntroEvents {
- data object Continue : QrCodeIntroEvents
+sealed interface QrCodeIntroEvent {
+ data object Continue : QrCodeIntroEvent
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenter.kt
index 13888fe23f..0781942216 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenter.kt
@@ -40,9 +40,9 @@ class QrCodeIntroPresenter(
}
}
- fun handleEvent(event: QrCodeIntroEvents) {
+ fun handleEvent(event: QrCodeIntroEvent) {
when (event) {
- QrCodeIntroEvents.Continue -> if (cameraPermissionState.permissionGranted) {
+ QrCodeIntroEvent.Continue -> if (cameraPermissionState.permissionGranted) {
canContinue = true
} else {
pendingPermissionRequest = true
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroState.kt
index d20a3f58d9..ab84743404 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroState.kt
@@ -15,5 +15,5 @@ data class QrCodeIntroState(
val desktopAppName: String,
val cameraPermissionState: PermissionsState,
val canContinue: Boolean,
- val eventSink: (QrCodeIntroEvents) -> Unit
+ val eventSink: (QrCodeIntroEvent) -> Unit
)
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroStatePreviewParam.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroStatePreviewParam.kt
index b9c286dc16..5e5fbac8b1 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroStatePreviewParam.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroStatePreviewParam.kt
@@ -30,7 +30,7 @@ fun aQrCodeIntroState(
permission = Manifest.permission.CAMERA,
),
canContinue: Boolean = false,
- eventSink: (QrCodeIntroEvents) -> Unit = {},
+ eventSink: (QrCodeIntroEvent) -> Unit = {},
) = QrCodeIntroState(
appName = appName,
desktopAppName = desktopAppName,
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroView.kt
index 08a40b63c5..2691c0cbf5 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroView.kt
@@ -91,7 +91,7 @@ private fun ColumnScope.Buttons(
text = stringResource(id = R.string.screen_qr_code_login_initial_state_button_title),
modifier = Modifier.fillMaxWidth(),
onClick = {
- state.eventSink.invoke(QrCodeIntroEvents.Continue)
+ state.eventSink.invoke(QrCodeIntroEvent.Continue)
}
)
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanEvents.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanEvent.kt
similarity index 81%
rename from features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanEvents.kt
rename to features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanEvent.kt
index f5804aceb0..d1c91b9b42 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanEvents.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanEvent.kt
@@ -8,7 +8,7 @@
package io.element.android.features.login.impl.screens.qrcode.scan
-sealed interface QrCodeScanEvents {
- data class QrCodeScanned(val code: ByteArray) : QrCodeScanEvents
- data object TryAgain : QrCodeScanEvents
+sealed interface QrCodeScanEvent {
+ data class QrCodeScanned(val code: ByteArray) : QrCodeScanEvent
+ data object TryAgain : QrCodeScanEvent
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanPresenter.kt
index 5e298604a4..4075a9d2cd 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanPresenter.kt
@@ -52,13 +52,13 @@ class QrCodeScanPresenter(
authenticationAction.value = AsyncAction.Failure(it)
}
- fun handleEvent(event: QrCodeScanEvents) {
+ fun handleEvent(event: QrCodeScanEvent) {
when (event) {
- QrCodeScanEvents.TryAgain -> {
+ QrCodeScanEvent.TryAgain -> {
isScanning = true
authenticationAction.value = AsyncAction.Uninitialized
}
- is QrCodeScanEvents.QrCodeScanned -> {
+ is QrCodeScanEvent.QrCodeScanned -> {
isScanning = false
coroutineScope.getQrCodeData(authenticationAction, event.code)
}
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanState.kt
index 0e64bfc6a6..5d9fca2543 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanState.kt
@@ -14,5 +14,5 @@ import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginDat
data class QrCodeScanState(
val isScanning: Boolean,
val authenticationAction: AsyncAction,
- val eventSink: (QrCodeScanEvents) -> Unit
+ val eventSink: (QrCodeScanEvent) -> Unit
)
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanStatePreviewParam.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanStatePreviewParam.kt
index 19385b6df1..24164b94c9 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanStatePreviewParam.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanStatePreviewParam.kt
@@ -46,7 +46,7 @@ open class QrCodeScanStatePreviewParam : PreviewParameterProvider = AsyncAction.Uninitialized,
- eventSink: (QrCodeScanEvents) -> Unit = {},
+ eventSink: (QrCodeScanEvent) -> Unit = {},
) = QrCodeScanState(
isScanning = isScanning,
authenticationAction = authenticationAction,
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanView.kt
index 72d624a921..372a46788b 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanView.kt
@@ -105,7 +105,7 @@ private fun Content(
) {
QrCodeCameraView(
modifier = Modifier.fillMaxSize(),
- onScanQrCode = { state.eventSink.invoke(QrCodeScanEvents.QrCodeScanned(it)) },
+ onScanQrCode = { state.eventSink.invoke(QrCodeScanEvent.QrCodeScanned(it)) },
isScanning = state.isScanning,
)
}
@@ -125,7 +125,7 @@ private fun ColumnScope.Buttons(
.fillMaxWidth()
.padding(bottom = 16.dp),
onClick = {
- state.eventSink.invoke(QrCodeScanEvents.TryAgain)
+ state.eventSink.invoke(QrCodeScanEvent.TryAgain)
}
)
Column(
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt
index ad997111e2..44a3bbd5cb 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt
@@ -63,7 +63,7 @@ class ChangeServerPresenterTest {
).test {
val initialState = awaitItem()
assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
- initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
+ initialState.eventSink.invoke(ChangeServerEvent.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
val loadingState = awaitItem()
assertThat(loadingState.changeServerAction).isInstanceOf(AsyncData.Loading::class.java)
val successState = awaitItem()
@@ -87,13 +87,13 @@ class ChangeServerPresenterTest {
).test {
val initialState = awaitItem()
assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
- initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
+ initialState.eventSink.invoke(ChangeServerEvent.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
val loadingState = awaitItem()
assertThat(loadingState.changeServerAction).isInstanceOf(AsyncData.Loading::class.java)
val failureState = awaitItem()
assertThat(failureState.changeServerAction).isInstanceOf(AsyncData.Failure::class.java)
// Clear error
- failureState.eventSink.invoke(ChangeServerEvents.ClearError)
+ failureState.eventSink.invoke(ChangeServerEvent.ClearError)
val finalState = awaitItem()
assertThat(finalState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
}
@@ -115,7 +115,7 @@ class ChangeServerPresenterTest {
).test {
val initialState = awaitItem()
assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
- initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
+ initialState.eventSink.invoke(ChangeServerEvent.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
val loadingState = awaitItem()
assertThat(loadingState.changeServerAction).isInstanceOf(AsyncData.Loading::class.java)
val failureState = awaitItem()
@@ -139,7 +139,7 @@ class ChangeServerPresenterTest {
val initialState = awaitItem()
assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
val anAccountProvider = AccountProvider(url = A_HOMESERVER_URL)
- initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(anAccountProvider))
+ initialState.eventSink.invoke(ChangeServerEvent.ChangeServer(anAccountProvider))
val loadingState = awaitItem()
assertThat(loadingState.changeServerAction).isInstanceOf(AsyncData.Loading::class.java)
val failureState = awaitItem()
@@ -167,7 +167,7 @@ class ChangeServerPresenterTest {
val initialState = awaitItem()
assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
val anAccountProvider = AccountProvider(url = A_HOMESERVER_URL)
- initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(anAccountProvider))
+ initialState.eventSink.invoke(ChangeServerEvent.ChangeServer(anAccountProvider))
// Skip loading state
skipItems(1)
val failureState = awaitItem()
@@ -194,7 +194,7 @@ class ChangeServerPresenterTest {
).test {
val initialState = awaitItem()
assertThat(initialState.localNetworkPermissionDialog).isEqualTo(LocalNetworkPermissionDialog.None)
- initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
+ initialState.eventSink.invoke(ChangeServerEvent.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
val promptState = expectMostRecentItem()
// Dialog is shown, permission has not been requested yet, setHomeserver has not been called.
assertThat(promptState.localNetworkPermissionDialog).isNotEqualTo(LocalNetworkPermissionDialog.None)
@@ -213,10 +213,10 @@ class ChangeServerPresenterTest {
permissionsPresenter = FakePermissionsPresenter(),
).test {
val initialState = awaitItem()
- initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
+ initialState.eventSink.invoke(ChangeServerEvent.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
val promptState = expectMostRecentItem()
assertThat(promptState.localNetworkPermissionDialog).isNotEqualTo(LocalNetworkPermissionDialog.None)
- promptState.eventSink.invoke(ChangeServerEvents.DismissLocalNetworkPermission)
+ promptState.eventSink.invoke(ChangeServerEvent.DismissLocalNetworkPermission)
val dismissedState = expectMostRecentItem()
assertThat(dismissedState.localNetworkPermissionDialog).isEqualTo(LocalNetworkPermissionDialog.None)
assertThat(dismissedState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
@@ -236,7 +236,7 @@ class ChangeServerPresenterTest {
permissionsPresenter = permissionsPresenter,
).test {
val initialState = awaitItem()
- initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
+ initialState.eventSink.invoke(ChangeServerEvent.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
val promptState = expectMostRecentItem()
assertThat(promptState.localNetworkPermissionDialog).isNotEqualTo(LocalNetworkPermissionDialog.None)
permissionsPresenter.setPermissionGranted()
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderPresenterTest.kt
index 4f00bb002b..78f4293489 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderPresenterTest.kt
@@ -88,7 +88,7 @@ class ChooseAccountProviderPresenterTest {
presenter.test {
awaitItem().also {
assertThat(it.selectedAccountProvider).isNull()
- it.eventSink(ChooseAccountProviderEvents.Continue)
+ it.eventSink(ChooseAccountProviderEvent.Continue)
expectNoEvents()
}
}
@@ -112,11 +112,11 @@ class ChooseAccountProviderPresenterTest {
presenter.test {
awaitItem().also {
assertThat(it.selectedAccountProvider).isNull()
- it.eventSink(ChooseAccountProviderEvents.SelectAccountProvider(accountProvider1))
+ it.eventSink(ChooseAccountProviderEvent.SelectAccountProvider(accountProvider1))
}
awaitItem().also {
assertThat(it.selectedAccountProvider).isEqualTo(accountProvider1)
- it.eventSink(ChooseAccountProviderEvents.Continue)
+ it.eventSink(ChooseAccountProviderEvent.Continue)
skipItems(1) // Loading
// Check an error was returned
@@ -124,7 +124,7 @@ class ChooseAccountProviderPresenterTest {
assertThat(submittedState.loginModeState.loginMode).isInstanceOf(AsyncData.Failure::class.java)
// Assert the error is then cleared
- submittedState.eventSink(ChooseAccountProviderEvents.ClearError)
+ submittedState.eventSink(ChooseAccountProviderEvent.ClearError)
val clearedState = awaitItem()
assertThat(clearedState.loginModeState.loginMode).isEqualTo(AsyncData.Uninitialized)
}
@@ -145,15 +145,15 @@ class ChooseAccountProviderPresenterTest {
presenter.test {
awaitItem().also {
assertThat(it.selectedAccountProvider).isNull()
- it.eventSink(ChooseAccountProviderEvents.SelectAccountProvider(accountProvider1))
+ it.eventSink(ChooseAccountProviderEvent.SelectAccountProvider(accountProvider1))
}
awaitItem().also {
assertThat(it.selectedAccountProvider).isEqualTo(accountProvider1)
- it.eventSink(ChooseAccountProviderEvents.Continue)
+ it.eventSink(ChooseAccountProviderEvent.Continue)
}
awaitItem().also {
assertThat(it.loginModeState.loginMode.isLoading()).isTrue()
- it.eventSink(ChooseAccountProviderEvents.SelectAccountProvider(accountProvider2))
+ it.eventSink(ChooseAccountProviderEvent.SelectAccountProvider(accountProvider2))
}
expectNoEvents()
}
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderViewTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderViewTest.kt
index cd64638563..4ef7a71966 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderViewTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/chooseaccountprovider/ChooseAccountProviderViewTest.kt
@@ -35,7 +35,7 @@ import org.robolectric.annotation.Config
class ChooseAccountProviderViewTest : RobolectricTest() {
@Test
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder(expectEvents = false)
+ val eventSink = EventsRecorder(expectEvents = false)
ensureCalledOnce {
setChooseAccountProviderView(
state = aChooseAccountProviderState(
@@ -50,7 +50,7 @@ class ChooseAccountProviderViewTest : RobolectricTest() {
@Config(qualifiers = "h1024dp")
@Test
fun `selecting an account provider emits the the expected event`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder()
+ val eventSink = EventsRecorder()
setChooseAccountProviderView(
state = aChooseAccountProviderState(
accountProviders = listOf(
@@ -62,12 +62,12 @@ class ChooseAccountProviderViewTest : RobolectricTest() {
),
)
onNodeWithText(ChooseAccountProviderPresenterTest.accountProvider1.title).performClick()
- eventSink.assertSingle(ChooseAccountProviderEvents.SelectAccountProvider(ChooseAccountProviderPresenterTest.accountProvider1))
+ eventSink.assertSingle(ChooseAccountProviderEvent.SelectAccountProvider(ChooseAccountProviderPresenterTest.accountProvider1))
}
@Test
fun `when error is displayed - closing the dialog emits the expected event`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder()
+ val eventSink = EventsRecorder()
setChooseAccountProviderView(
state = aChooseAccountProviderState(
loginModeState = aLoginModeState(loginMode = AsyncData.Failure(AN_EXCEPTION)),
@@ -75,7 +75,7 @@ class ChooseAccountProviderViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_ok)
- eventSink.assertSingle(ChooseAccountProviderEvents.ClearError)
+ eventSink.assertSingle(ChooseAccountProviderEvent.ClearError)
}
private fun AndroidComposeUiTest.setChooseAccountProviderView(
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt
index 641eea1563..19afbe0f28 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt
@@ -68,7 +68,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
val successState = awaitLoginMode { it is AsyncData.Success }
assertThat(successState.loginModeState.loginMode.dataOrNull()).isEqualTo(LoginMode.PasswordLogin)
cancelAndIgnoreRemainingEvents()
@@ -87,7 +87,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
val successState = awaitLoginMode { it is AsyncData.Success }
assertThat(successState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
cancelAndIgnoreRemainingEvents()
@@ -108,7 +108,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
val successState = awaitLoginMode { it is AsyncData.Success }
assertThat(successState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
authenticationService.givenOAuthCancelError(AN_EXCEPTION)
@@ -133,7 +133,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
val successState = awaitLoginMode { it is AsyncData.Success }
assertThat(successState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
defaultOAuthActionFlow.post(OAuthAction.GoBack())
@@ -157,7 +157,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
awaitLoginMode { it is AsyncData.Loading }
defaultOAuthActionFlow.post(OAuthAction.GoBack(toUnblock = true))
val cancelFinalState = awaitLoginMode { it is AsyncData.Uninitialized }
@@ -180,7 +180,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
val successState = awaitLoginMode { it is AsyncData.Success }
assertThat(successState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
authenticationService.givenLoginError(AN_EXCEPTION)
@@ -205,7 +205,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
val successState = awaitLoginMode { it is AsyncData.Success }
assertThat(successState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
defaultOidcActionFlow.post(OAuthAction.Success("aUrl"))
@@ -227,7 +227,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink.invoke(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
// The account provider validation fails, so the login is never attempted.
val failureState = awaitState { it.changeServerState.changeServerAction is AsyncData.Failure }
assertThat(failureState.loginModeState.loginMode).isEqualTo(AsyncData.Uninitialized)
@@ -249,13 +249,13 @@ class ConfirmAccountProviderPresenterTest {
val initialState = awaitItem()
// Submit will return an error while validating the account provider
- initialState.eventSink(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
// Check an error was returned
val submittedState = awaitState { it.changeServerState.changeServerAction is AsyncData.Failure }
// Assert the error is then cleared
- submittedState.eventSink(ConfirmAccountProviderEvents.ClearError)
+ submittedState.eventSink(ConfirmAccountProviderEvent.ClearError)
val clearedState = awaitState { it.changeServerState.changeServerAction is AsyncData.Uninitialized }
assertThat(clearedState.loginModeState.loginMode).isEqualTo(AsyncData.Uninitialized)
}
@@ -274,12 +274,12 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
// Check an error was returned
val submittedState = awaitLoginMode { it is AsyncData.Failure }
assertThat(submittedState.loginModeState.loginMode.errorOrNull()).isInstanceOf(AccountCreationNotSupported::class.java)
// Assert the error is then cleared
- submittedState.eventSink(ConfirmAccountProviderEvents.ClearError)
+ submittedState.eventSink(ConfirmAccountProviderEvent.ClearError)
val clearedState = awaitLoginMode { it is AsyncData.Uninitialized }
assertThat(clearedState.loginModeState.loginMode).isEqualTo(AsyncData.Uninitialized)
cancelAndIgnoreRemainingEvents()
@@ -299,7 +299,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
val submittedState = awaitLoginMode { it is AsyncData.Success }
assertThat(submittedState.loginModeState.loginMode.dataOrNull()).isInstanceOf(LoginMode.OAuth::class.java)
cancelAndIgnoreRemainingEvents()
@@ -316,7 +316,7 @@ class ConfirmAccountProviderPresenterTest {
presenter.test {
val initialState = awaitItem()
assertThat(initialState.accountProviderSuggestion).isNull()
- initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("random"))
+ initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("random"))
val suggestionState = awaitState { it.accountProviderInput == "random" }
// Completion is offered without the https:// scheme, even though history stores the full URL.
assertThat(suggestionState.accountProviderSuggestion).isEqualTo("randomcommunity.org")
@@ -340,9 +340,9 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("random"))
+ initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("random"))
val suggestionState = awaitState { it.accountProviderSuggestion != null }
- suggestionState.eventSink(ConfirmAccountProviderEvents.Continue("randomcommunity.org"))
+ suggestionState.eventSink(ConfirmAccountProviderEvent.Continue("randomcommunity.org"))
awaitLoginMode { it is AsyncData.Success }
assertThat(submittedUrls.first()).isEqualTo("https://randomcommunity.org")
cancelAndIgnoreRemainingEvents()
@@ -360,9 +360,9 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("random"))
+ initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("random"))
val suggestionState = awaitState { it.accountProviderSuggestion != null }
- suggestionState.eventSink(ConfirmAccountProviderEvents.Continue("randomcommunity.org"))
+ suggestionState.eventSink(ConfirmAccountProviderEvent.Continue("randomcommunity.org"))
// The field now renders the full accepted server rather than the typed prefix.
val appliedState = awaitState { it.accountProviderInput == "randomcommunity.org" }
assertThat(appliedState.accountProviderInput).isEqualTo("randomcommunity.org")
@@ -381,7 +381,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("ele"))
+ initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("ele"))
val suggestionState = awaitState { it.accountProviderInput == "ele" }
assertThat(suggestionState.accountProviderSuggestion).isEqualTo("element.io")
}
@@ -394,7 +394,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("matr"))
+ initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("matr"))
val suggestionState = awaitState { it.accountProviderInput == "matr" }
assertThat(suggestionState.accountProviderSuggestion).isEqualTo("matrix.org")
}
@@ -409,9 +409,9 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("https://mat"))
+ initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("https://mat"))
assertThat(awaitState { it.accountProviderInput == "https://mat" }.accountProviderSuggestion).isNull()
- initialState.eventSink(ConfirmAccountProviderEvents.UserInputChanged("http://mat"))
+ initialState.eventSink(ConfirmAccountProviderEvent.UserInputChanged("http://mat"))
assertThat(awaitState { it.accountProviderInput == "http://mat" }.accountProviderSuggestion).isNull()
}
}
@@ -430,7 +430,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.Continue("matrix.org"))
+ initialState.eventSink(ConfirmAccountProviderEvent.Continue("matrix.org"))
awaitLoginMode { it is AsyncData.Success }
assertThat(submittedUrls.first()).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
cancelAndIgnoreRemainingEvents()
@@ -453,7 +453,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.Continue(AuthenticationConfig.MATRIX_ORG_URL))
+ initialState.eventSink(ConfirmAccountProviderEvent.Continue(AuthenticationConfig.MATRIX_ORG_URL))
awaitLoginMode { it is AsyncData.Success }
assertThat(submittedUrls).containsExactly(AuthenticationConfig.MATRIX_ORG_URL)
cancelAndIgnoreRemainingEvents()
@@ -472,7 +472,7 @@ class ConfirmAccountProviderPresenterTest {
val presenter = createConfirmAccountProviderPresenter(matrixAuthenticationService = authenticationService)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.Continue("@alice:example.org"))
+ initialState.eventSink(ConfirmAccountProviderEvent.Continue("@alice:example.org"))
awaitLoginMode { it is AsyncData.Success }
assertThat(submittedUrls.first()).isEqualTo("https://example.org")
assertThat(authenticationService.getOAuthUrlLoginHint).isEqualTo("mxid:@alice:example.org")
@@ -492,7 +492,7 @@ class ConfirmAccountProviderPresenterTest {
val presenter = createConfirmAccountProviderPresenter(matrixAuthenticationService = authenticationService)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.Continue("@alice:example.org:8448"))
+ initialState.eventSink(ConfirmAccountProviderEvent.Continue("@alice:example.org:8448"))
awaitLoginMode { it is AsyncData.Success }
assertThat(submittedUrls.first()).isEqualTo("https://example.org:8448")
cancelAndIgnoreRemainingEvents()
@@ -507,7 +507,7 @@ class ConfirmAccountProviderPresenterTest {
val presenter = createConfirmAccountProviderPresenter(matrixAuthenticationService = authenticationService)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.Continue("matrix.org"))
+ initialState.eventSink(ConfirmAccountProviderEvent.Continue("matrix.org"))
awaitLoginMode { it is AsyncData.Success }
assertThat(authenticationService.getOAuthUrlLoginHint).isNull()
cancelAndIgnoreRemainingEvents()
@@ -525,7 +525,7 @@ class ConfirmAccountProviderPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(ConfirmAccountProviderEvents.Continue("@alice:example.org"))
+ initialState.eventSink(ConfirmAccountProviderEvent.Continue("@alice:example.org"))
awaitLoginMode { it is AsyncData.Success }
assertThat(authenticationService.getOAuthUrlLoginHint).isNull()
cancelAndIgnoreRemainingEvents()
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt
index 4dd2859dee..b12c9ec667 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt
@@ -54,7 +54,7 @@ class LoginPasswordPresenterTest {
val initialState = awaitItem()
assertThat(initialState.formState.login).isEqualTo(A_USER_NAME)
// Login can be changed
- initialState.eventSink.invoke(LoginPasswordEvents.SetLogin(A_USER_NAME_2))
+ initialState.eventSink.invoke(LoginPasswordEvent.SetLogin(A_USER_NAME_2))
val loginChangedState = awaitItem()
assertThat(loginChangedState.formState.login).isEqualTo(A_USER_NAME_2)
}
@@ -71,11 +71,11 @@ class LoginPasswordPresenterTest {
authenticationService = authenticationService,
).test {
val initialState = awaitItem()
- initialState.eventSink.invoke(LoginPasswordEvents.SetLogin(A_USER_NAME))
+ initialState.eventSink.invoke(LoginPasswordEvent.SetLogin(A_USER_NAME))
val loginState = awaitItem()
assertThat(loginState.formState).isEqualTo(LoginFormState(login = A_USER_NAME, password = ""))
assertThat(loginState.submitEnabled).isFalse()
- initialState.eventSink.invoke(LoginPasswordEvents.SetPassword(A_PASSWORD))
+ initialState.eventSink.invoke(LoginPasswordEvent.SetPassword(A_PASSWORD))
val loginAndPasswordState = awaitItem()
assertThat(loginAndPasswordState.formState).isEqualTo(LoginFormState(login = A_USER_NAME, password = A_PASSWORD))
assertThat(loginAndPasswordState.submitEnabled).isTrue()
@@ -93,11 +93,11 @@ class LoginPasswordPresenterTest {
authenticationService = authenticationService,
).test {
val initialState = awaitItem()
- initialState.eventSink.invoke(LoginPasswordEvents.SetLogin(A_USER_NAME))
- initialState.eventSink.invoke(LoginPasswordEvents.SetPassword(A_PASSWORD))
+ initialState.eventSink.invoke(LoginPasswordEvent.SetLogin(A_USER_NAME))
+ initialState.eventSink.invoke(LoginPasswordEvent.SetPassword(A_PASSWORD))
skipItems(1)
val loginAndPasswordState = awaitItem()
- loginAndPasswordState.eventSink.invoke(LoginPasswordEvents.Submit)
+ loginAndPasswordState.eventSink.invoke(LoginPasswordEvent.Submit)
val submitState = awaitItem()
assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
val loggedInState = awaitItem()
@@ -118,11 +118,11 @@ class LoginPasswordPresenterTest {
appPreferencesStore = appPreferencesStore,
).test {
val initialState = awaitItem()
- initialState.eventSink.invoke(LoginPasswordEvents.SetLogin(A_USER_NAME))
- initialState.eventSink.invoke(LoginPasswordEvents.SetPassword(A_PASSWORD))
+ initialState.eventSink.invoke(LoginPasswordEvent.SetLogin(A_USER_NAME))
+ initialState.eventSink.invoke(LoginPasswordEvent.SetPassword(A_PASSWORD))
skipItems(1)
val loginAndPasswordState = awaitItem()
- loginAndPasswordState.eventSink.invoke(LoginPasswordEvents.Submit)
+ loginAndPasswordState.eventSink.invoke(LoginPasswordEvent.Submit)
skipItems(1)
val loggedInState = awaitItem()
assertThat(loggedInState.loginAction).isEqualTo(AsyncData.Success(A_SESSION_ID))
@@ -142,12 +142,12 @@ class LoginPasswordPresenterTest {
authenticationService = authenticationService,
).test {
val initialState = awaitItem()
- initialState.eventSink.invoke(LoginPasswordEvents.SetLogin(A_USER_NAME))
- initialState.eventSink.invoke(LoginPasswordEvents.SetPassword(A_PASSWORD))
+ initialState.eventSink.invoke(LoginPasswordEvent.SetLogin(A_USER_NAME))
+ initialState.eventSink.invoke(LoginPasswordEvent.SetPassword(A_PASSWORD))
skipItems(1)
val loginAndPasswordState = awaitItem()
authenticationService.givenLoginError(AN_EXCEPTION)
- loginAndPasswordState.eventSink.invoke(LoginPasswordEvents.Submit)
+ loginAndPasswordState.eventSink.invoke(LoginPasswordEvent.Submit)
val submitState = awaitItem()
assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
val loggedInState = awaitItem()
@@ -166,19 +166,19 @@ class LoginPasswordPresenterTest {
authenticationService = authenticationService,
).test {
val initialState = awaitItem()
- initialState.eventSink.invoke(LoginPasswordEvents.SetLogin(A_USER_NAME))
- initialState.eventSink.invoke(LoginPasswordEvents.SetPassword(A_PASSWORD))
+ initialState.eventSink.invoke(LoginPasswordEvent.SetLogin(A_USER_NAME))
+ initialState.eventSink.invoke(LoginPasswordEvent.SetPassword(A_PASSWORD))
skipItems(1)
val loginAndPasswordState = awaitItem()
authenticationService.givenLoginError(AN_EXCEPTION)
- loginAndPasswordState.eventSink.invoke(LoginPasswordEvents.Submit)
+ loginAndPasswordState.eventSink.invoke(LoginPasswordEvent.Submit)
val submitState = awaitItem()
assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
val loggedInState = awaitItem()
// Check an error was returned
assertThat(loggedInState.loginAction).isEqualTo(AsyncData.Failure(AN_EXCEPTION))
// Assert the error is then cleared
- loggedInState.eventSink(LoginPasswordEvents.ClearError)
+ loggedInState.eventSink(LoginPasswordEvent.ClearError)
val clearedState = awaitItem()
assertThat(clearedState.loginAction).isEqualTo(AsyncData.Uninitialized)
}
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordViewTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordViewTest.kt
index d76c94d5ea..32ce44366f 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordViewTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordViewTest.kt
@@ -39,7 +39,7 @@ import org.robolectric.annotation.Config
class LoginPasswordViewTest : RobolectricTest() {
@Test
fun `clicking on back invoke back callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce { callback ->
setLoginPasswordView(
aLoginPasswordState(
@@ -53,7 +53,7 @@ class LoginPasswordViewTest : RobolectricTest() {
@Test
fun `changing login invokes the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setLoginPasswordView(
aLoginPasswordState(
eventSink = eventsRecorder,
@@ -62,13 +62,13 @@ class LoginPasswordViewTest : RobolectricTest() {
val userNameHint = activity!!.getString(CommonStrings.common_username)
onNodeWithText(userNameHint).performTextInput(A_USER_NAME)
eventsRecorder.assertSingle(
- LoginPasswordEvents.SetLogin(A_USER_NAME)
+ LoginPasswordEvent.SetLogin(A_USER_NAME)
)
}
@Test
fun `changing login removes new lines the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setLoginPasswordView(
aLoginPasswordState(
eventSink = eventsRecorder,
@@ -77,13 +77,13 @@ class LoginPasswordViewTest : RobolectricTest() {
val userNameHint = activity!!.getString(CommonStrings.common_username)
onNodeWithText(userNameHint).performTextInput("a\nb")
eventsRecorder.assertSingle(
- LoginPasswordEvents.SetLogin("ab")
+ LoginPasswordEvent.SetLogin("ab")
)
}
@Test
fun `changing login removes carriage returns the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setLoginPasswordView(
aLoginPasswordState(
eventSink = eventsRecorder,
@@ -92,13 +92,13 @@ class LoginPasswordViewTest : RobolectricTest() {
val userNameHint = activity!!.getString(CommonStrings.common_username)
onNodeWithText(userNameHint).performTextInput("a\r\nb")
eventsRecorder.assertSingle(
- LoginPasswordEvents.SetLogin("ab")
+ LoginPasswordEvent.SetLogin("ab")
)
}
@Test
fun `clearing login invokes the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setLoginPasswordView(
aLoginPasswordState(
formState = aLoginFormState(A_USER_NAME),
@@ -108,13 +108,13 @@ class LoginPasswordViewTest : RobolectricTest() {
val a11yClear = activity!!.getString(CommonStrings.action_clear)
onNodeWithContentDescription(a11yClear).performClick()
eventsRecorder.assertSingle(
- LoginPasswordEvents.SetLogin("")
+ LoginPasswordEvent.SetLogin("")
)
}
@Test
fun `changing password invokes the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setLoginPasswordView(
aLoginPasswordState(
eventSink = eventsRecorder,
@@ -123,13 +123,13 @@ class LoginPasswordViewTest : RobolectricTest() {
val userNameHint = activity!!.getString(CommonStrings.common_password)
onNodeWithText(userNameHint).performTextInput(A_PASSWORD)
eventsRecorder.assertSingle(
- LoginPasswordEvents.SetPassword(A_PASSWORD)
+ LoginPasswordEvent.SetPassword(A_PASSWORD)
)
}
@Test
fun `changing password removes carriage returns the expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setLoginPasswordView(
aLoginPasswordState(
eventSink = eventsRecorder,
@@ -138,13 +138,13 @@ class LoginPasswordViewTest : RobolectricTest() {
val passwordHint = activity!!.getString(CommonStrings.common_password)
onNodeWithText(passwordHint).performTextInput("a\r\nb")
eventsRecorder.assertSingle(
- LoginPasswordEvents.SetPassword("ab")
+ LoginPasswordEvent.SetPassword("ab")
)
}
@Test
fun `reveal password makes the password visible`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
setLoginPasswordView(
aLoginPasswordState(
formState = aLoginFormState(password = A_PASSWORD),
@@ -165,7 +165,7 @@ class LoginPasswordViewTest : RobolectricTest() {
@Test
fun `when login is empty, continue button is not enabled`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
setLoginPasswordView(
aLoginPasswordState(
formState = aLoginFormState(password = A_PASSWORD),
@@ -178,7 +178,7 @@ class LoginPasswordViewTest : RobolectricTest() {
@Test
fun `when password is empty, continue button is not enabled`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
setLoginPasswordView(
aLoginPasswordState(
formState = aLoginFormState(login = A_USER_NAME),
@@ -192,7 +192,7 @@ class LoginPasswordViewTest : RobolectricTest() {
@Config(qualifiers = "h1024dp")
@Test
fun `clicking on Continue sends expected event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setLoginPasswordView(
aLoginPasswordState(
formState = aLoginFormState(login = A_USER_NAME, password = A_PASSWORD),
@@ -203,7 +203,7 @@ class LoginPasswordViewTest : RobolectricTest() {
onNodeWithText(continueStr).assertIsEnabled()
clickOn(CommonStrings.action_continue)
eventsRecorder.assertSingle(
- LoginPasswordEvents.Submit
+ LoginPasswordEvent.Submit
)
}
}
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenterTest.kt
index 3c2e4b574f..1088a87538 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenterTest.kt
@@ -153,7 +153,7 @@ class OnBoardingPresenterTest {
awaitItem().also { state ->
assertThat(state.canReportBug).isFalse()
repeat(7) {
- state.eventSink(OnBoardingEvents.OnVersionClick)
+ state.eventSink(OnBoardingEvent.OnVersionClick)
}
}
expectNoEvents()
@@ -168,7 +168,7 @@ class OnBoardingPresenterTest {
awaitItem().also { state ->
assertThat(state.canReportBug).isFalse()
repeat(7) {
- state.eventSink(OnBoardingEvents.OnVersionClick)
+ state.eventSink(OnBoardingEvent.OnVersionClick)
}
}
assertThat(awaitItem().canReportBug).isTrue()
@@ -272,7 +272,7 @@ class OnBoardingPresenterTest {
awaitItem().also {
assertThat(it.defaultAccountProvider).isEqualTo(A_HOMESERVER_URL)
assertThat(accountProviderDataSource.flow.first().url).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
- it.eventSink(OnBoardingEvents.OnSignIn(A_HOMESERVER_URL_2))
+ it.eventSink(OnBoardingEvent.OnSignIn(A_HOMESERVER_URL_2))
skipItems(1) // Loading
// Account data source has been updated
assertThat(accountProviderDataSource.flow.first().url).isEqualTo(A_HOMESERVER_URL_2)
@@ -281,7 +281,7 @@ class OnBoardingPresenterTest {
assertThat(submittedState.loginModeState.loginMode).isInstanceOf(AsyncData.Failure::class.java)
// Assert the error is then cleared
- submittedState.eventSink(OnBoardingEvents.ClearError)
+ submittedState.eventSink(OnBoardingEvent.ClearError)
val clearedState = awaitItem()
assertThat(clearedState.loginModeState.loginMode).isEqualTo(AsyncData.Uninitialized)
}
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnboardingViewTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnboardingViewTest.kt
index dfa4119711..88c9acf55f 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnboardingViewTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnboardingViewTest.kt
@@ -39,7 +39,7 @@ import org.junit.Test
class OnboardingViewTest : RobolectricTestParameter() {
@Test
fun `when can create account - clicking on create account calls the expected callback`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder(expectEvents = false)
+ val eventSink = EventsRecorder(expectEvents = false)
ensureCalledOnce { callback ->
setOnboardingView(
state = anOnBoardingState(
@@ -58,7 +58,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test
fun `when can go back - clicking on back calls the expected callback`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder(expectEvents = false)
+ val eventSink = EventsRecorder(expectEvents = false)
ensureCalledOnce { callback ->
setOnboardingView(
state = anOnBoardingState(
@@ -73,7 +73,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test
fun `when can login with QR code - clicking on sign in with QR code calls the expected callback`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder(expectEvents = false)
+ val eventSink = EventsRecorder(expectEvents = false)
ensureCalledOnce { callback ->
setOnboardingView(
state = anOnBoardingState(
@@ -93,7 +93,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
"cannot search account provider" to true,
)
) = runAndroidComposeUiTest {
- val eventSink = EventsRecorder(expectEvents = false)
+ val eventSink = EventsRecorder(expectEvents = false)
ensureCalledOnceWithParam(mustChooseAccountProvider) { callback ->
setOnboardingView(
state = anOnBoardingState(
@@ -114,7 +114,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
"cannot search account provider" to true,
)
) = runAndroidComposeUiTest {
- val eventSink = EventsRecorder(expectEvents = false)
+ val eventSink = EventsRecorder(expectEvents = false)
ensureCalledOnceWithParam(mustChooseAccountProvider) { callback ->
setOnboardingView(
state = anOnBoardingState(
@@ -131,7 +131,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test
fun `when sign in to pre defined account provider - clicking on button emits the expected event`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder()
+ val eventSink = EventsRecorder()
setOnboardingView(
state = anOnBoardingState(
defaultAccountProvider = "element.io",
@@ -140,12 +140,12 @@ class OnboardingViewTest : RobolectricTestParameter() {
)
val buttonText = activity!!.getString(R.string.screen_onboarding_sign_in_to, "element.io")
onNodeWithText(buttonText).performClick()
- eventSink.assertSingle(OnBoardingEvents.OnSignIn("element.io"))
+ eventSink.assertSingle(OnBoardingEvent.OnSignIn("element.io"))
}
@Test
fun `when error is displayed - closing the dialog emits the expected event`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder()
+ val eventSink = EventsRecorder()
setOnboardingView(
state = anOnBoardingState(
defaultAccountProvider = "element.io",
@@ -154,12 +154,12 @@ class OnboardingViewTest : RobolectricTestParameter() {
),
)
clickOn(CommonStrings.action_ok)
- eventSink.assertSingle(OnBoardingEvents.ClearError)
+ eventSink.assertSingle(OnBoardingEvent.ClearError)
}
@Test
fun `clicking on report a problem calls the sign in callback`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder(expectEvents = false)
+ val eventSink = EventsRecorder(expectEvents = false)
ensureCalledOnce { callback ->
setOnboardingView(
state = anOnBoardingState(
@@ -176,7 +176,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test
fun `clicking on settings calls the developer settings callback`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder(expectEvents = false)
+ val eventSink = EventsRecorder(expectEvents = false)
ensureCalledOnce { callback ->
setOnboardingView(
state = anOnBoardingState(
@@ -192,7 +192,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test
fun `cannot report a problem when the feature is disabled`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder(expectEvents = false)
+ val eventSink = EventsRecorder(expectEvents = false)
setOnboardingView(
state = anOnBoardingState(
canReportBug = false,
@@ -205,7 +205,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test
fun `when success PasswordLogin - the expected callback is invoked and the event is received`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder()
+ val eventSink = EventsRecorder()
ensureCalledOnce { callback ->
setOnboardingView(
state = anOnBoardingState(
@@ -215,12 +215,12 @@ class OnboardingViewTest : RobolectricTestParameter() {
onNeedLoginPassword = callback,
)
}
- eventSink.assertSingle(OnBoardingEvents.ClearError)
+ eventSink.assertSingle(OnBoardingEvent.ClearError)
}
@Test
fun `when success Oidc - the expected callback is invoked and the event is received`() = runAndroidComposeUiTest {
- val eventSink = EventsRecorder()
+ val eventSink = EventsRecorder()
val oAuthDetails = OAuthDetails("aUrl")
ensureCalledOnceWithParam(oAuthDetails) { callback ->
setOnboardingView(
@@ -231,7 +231,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
onOAuthDetails = callback,
)
}
- eventSink.assertSingle(OnBoardingEvents.ClearError)
+ eventSink.assertSingle(OnBoardingEvent.ClearError)
}
private fun AndroidComposeUiTest.setOnboardingView(
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenterTest.kt
index aabcf12e25..02bace008e 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenterTest.kt
@@ -37,7 +37,7 @@ class QrCodeIntroPresenterTest {
val permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionsPresenter)
val presenter = createQrCodeIntroPresenter(permissionsPresenterFactory = permissionsPresenterFactory)
presenter.test {
- awaitItem().eventSink(QrCodeIntroEvents.Continue)
+ awaitItem().eventSink(QrCodeIntroEvent.Continue)
assertThat(awaitItem().canContinue).isTrue()
}
}
@@ -48,7 +48,7 @@ class QrCodeIntroPresenterTest {
val permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionsPresenter)
val presenter = createQrCodeIntroPresenter(permissionsPresenterFactory = permissionsPresenterFactory)
presenter.test {
- awaitItem().eventSink(QrCodeIntroEvents.Continue)
+ awaitItem().eventSink(QrCodeIntroEvent.Continue)
assertThat(awaitItem().cameraPermissionState.showDialog).isTrue()
}
}
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroViewTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroViewTest.kt
index 5720c68ab4..3bb600ae55 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroViewTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroViewTest.kt
@@ -59,12 +59,12 @@ class QrCodeIntroViewTest : RobolectricTest() {
@Test
fun `on submit button clicked - emits the Continue event`() = runAndroidComposeUiTest {
- val eventRecorder = EventsRecorder()
+ val eventRecorder = EventsRecorder()
setQrCodeIntroView(
state = aQrCodeIntroState(eventSink = eventRecorder),
)
clickOn(R.string.screen_qr_code_login_initial_state_button_title)
- eventRecorder.assertSingle(QrCodeIntroEvents.Continue)
+ eventRecorder.assertSingle(QrCodeIntroEvent.Continue)
}
private fun AndroidComposeUiTest.setQrCodeIntroView(
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanPresenterTest.kt
index d4f23a452c..a13590a1bc 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanPresenterTest.kt
@@ -50,7 +50,7 @@ class QrCodeScanPresenterTest {
)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(QrCodeScanEvents.QrCodeScanned(byteArrayOf()))
+ initialState.eventSink(QrCodeScanEvent.QrCodeScanned(byteArrayOf()))
assertThat(awaitItem().isScanning).isFalse()
assertThat(awaitItem().authenticationAction.isLoading()).isTrue()
assertThat(awaitItem().authenticationAction.isSuccess()).isTrue()
@@ -65,14 +65,14 @@ class QrCodeScanPresenterTest {
val presenter = createQrCodeScanPresenter(qrCodeLoginDataFactory = qrCodeLoginDataFactory)
presenter.test {
val initialState = awaitItem()
- initialState.eventSink(QrCodeScanEvents.QrCodeScanned(byteArrayOf()))
+ initialState.eventSink(QrCodeScanEvent.QrCodeScanned(byteArrayOf()))
assertThat(awaitItem().isScanning).isFalse()
assertThat(awaitItem().authenticationAction.isLoading()).isTrue()
val errorState = awaitItem()
assertThat(errorState.authenticationAction.isFailure()).isTrue()
- errorState.eventSink(QrCodeScanEvents.TryAgain)
+ errorState.eventSink(QrCodeScanEvent.TryAgain)
assertThat(awaitItem().isScanning).isTrue()
assertThat(awaitItem().authenticationAction.isUninitialized()).isTrue()
}
diff --git a/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutEvents.kt b/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutEvent.kt
similarity index 78%
rename from features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutEvents.kt
rename to features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutEvent.kt
index cc16dfdaf1..d19a62768a 100644
--- a/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutEvents.kt
+++ b/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutEvent.kt
@@ -8,7 +8,7 @@
package io.element.android.features.logout.api.direct
-sealed interface DirectLogoutEvents {
- data class Logout(val ignoreSdkError: Boolean) : DirectLogoutEvents
- data object CloseDialogs : DirectLogoutEvents
+sealed interface DirectLogoutEvent {
+ data class Logout(val ignoreSdkError: Boolean) : DirectLogoutEvent
+ data object CloseDialogs : DirectLogoutEvent
}
diff --git a/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutState.kt b/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutState.kt
index 31e0fdcd5f..75c3392ac1 100644
--- a/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutState.kt
+++ b/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutState.kt
@@ -13,5 +13,5 @@ import io.element.android.libraries.architecture.AsyncAction
data class DirectLogoutState(
val canDoDirectSignOut: Boolean,
val logoutAction: AsyncAction,
- val eventSink: (DirectLogoutEvents) -> Unit,
+ val eventSink: (DirectLogoutEvent) -> Unit,
)
diff --git a/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutStatePreviewParam.kt b/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutStatePreviewParam.kt
index c208978fd9..936f7d2a58 100644
--- a/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutStatePreviewParam.kt
+++ b/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutStatePreviewParam.kt
@@ -25,7 +25,7 @@ open class DirectLogoutStatePreviewParam : PreviewParameterProvider = AsyncAction.Uninitialized,
- eventSink: (DirectLogoutEvents) -> Unit = {},
+ eventSink: (DirectLogoutEvent) -> Unit = {},
) = DirectLogoutState(
canDoDirectSignOut = canDoDirectSignOut,
logoutAction = logoutAction,
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutEvents.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutEvent.kt
similarity index 81%
rename from features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutEvents.kt
rename to features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutEvent.kt
index 0822444bea..e23338460c 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutEvents.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutEvent.kt
@@ -8,7 +8,7 @@
package io.element.android.features.logout.impl
-sealed interface LogoutEvents {
- data class Logout(val ignoreSdkError: Boolean) : LogoutEvents
- data object CloseDialogs : LogoutEvents
+sealed interface LogoutEvent {
+ data class Logout(val ignoreSdkError: Boolean) : LogoutEvent
+ data object CloseDialogs : LogoutEvent
}
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutPresenter.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutPresenter.kt
index 8176ed3d28..4ad8a6c78e 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutPresenter.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutPresenter.kt
@@ -74,16 +74,16 @@ class LogoutPresenter(
}
}
- fun handleEvent(event: LogoutEvents) {
+ fun handleEvent(event: LogoutEvent) {
when (event) {
- is LogoutEvents.Logout -> {
+ is LogoutEvent.Logout -> {
if (logoutAction.value.isConfirming() || event.ignoreSdkError) {
localCoroutineScope.logout(logoutAction, event.ignoreSdkError)
} else {
logoutAction.value = AsyncAction.ConfirmingNoParams
}
}
- LogoutEvents.CloseDialogs -> {
+ LogoutEvent.CloseDialogs -> {
logoutAction.value = AsyncAction.Uninitialized
}
}
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutState.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutState.kt
index 9240edc61d..6233c1cb23 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutState.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutState.kt
@@ -21,5 +21,5 @@ data class LogoutState(
val backupUploadState: BackupUploadState,
val waitingForALongTime: Boolean,
val logoutAction: AsyncAction,
- val eventSink: (LogoutEvents) -> Unit,
+ val eventSink: (LogoutEvent) -> Unit,
)
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutStatePreviewParam.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutStatePreviewParam.kt
index 7bd55faa2c..e2d948a7f3 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutStatePreviewParam.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutStatePreviewParam.kt
@@ -50,7 +50,7 @@ fun aLogoutState(
backupUploadState: BackupUploadState = BackupUploadState.Unknown,
waitingForALongTime: Boolean = false,
logoutAction: AsyncAction = AsyncAction.Uninitialized,
- eventSink: (LogoutEvents) -> Unit = {},
+ eventSink: (LogoutEvent) -> Unit = {},
) = LogoutState(
isLastDevice = isLastDevice,
backupState = backupState,
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutView.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutView.kt
index befabe7421..90a502fc16 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutView.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutView.kt
@@ -61,7 +61,7 @@ fun LogoutView(
state = state,
onChangeRecoveryKeyClick = onChangeRecoveryKeyClick,
onLogoutClick = {
- eventSink(LogoutEvents.Logout(ignoreSdkError = false))
+ eventSink(LogoutEvent.Logout(ignoreSdkError = false))
}
)
},
@@ -72,13 +72,13 @@ fun LogoutView(
LogoutActionDialog(
state.logoutAction,
onConfirmClick = {
- eventSink(LogoutEvents.Logout(ignoreSdkError = false))
+ eventSink(LogoutEvent.Logout(ignoreSdkError = false))
},
onForceLogoutClick = {
- eventSink(LogoutEvents.Logout(ignoreSdkError = true))
+ eventSink(LogoutEvent.Logout(ignoreSdkError = true))
},
onDismissDialog = {
- eventSink(LogoutEvents.CloseDialogs)
+ eventSink(LogoutEvent.CloseDialogs)
},
)
}
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutView.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutView.kt
index a8cad6ffba..901e4e9654 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutView.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutView.kt
@@ -11,7 +11,7 @@ package io.element.android.features.logout.impl.direct
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.PreviewParameter
import dev.zacsweers.metro.ContributesBinding
-import io.element.android.features.logout.api.direct.DirectLogoutEvents
+import io.element.android.features.logout.api.direct.DirectLogoutEvent
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.features.logout.api.direct.DirectLogoutStatePreviewParam
import io.element.android.features.logout.api.direct.DirectLogoutView
@@ -28,13 +28,13 @@ class DefaultDirectLogoutView : DirectLogoutView {
LogoutActionDialog(
state.logoutAction,
onConfirmClick = {
- eventSink(DirectLogoutEvents.Logout(ignoreSdkError = false))
+ eventSink(DirectLogoutEvent.Logout(ignoreSdkError = false))
},
onForceLogoutClick = {
- eventSink(DirectLogoutEvents.Logout(ignoreSdkError = true))
+ eventSink(DirectLogoutEvent.Logout(ignoreSdkError = true))
},
onDismissDialog = {
- eventSink(DirectLogoutEvents.CloseDialogs)
+ eventSink(DirectLogoutEvent.CloseDialogs)
},
)
}
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DirectLogoutPresenter.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DirectLogoutPresenter.kt
index 8d8cc9141e..79798dd2ab 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DirectLogoutPresenter.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DirectLogoutPresenter.kt
@@ -16,7 +16,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import dev.zacsweers.metro.Inject
-import io.element.android.features.logout.api.direct.DirectLogoutEvents
+import io.element.android.features.logout.api.direct.DirectLogoutEvent
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.features.logout.impl.tools.isBackingUp
import io.element.android.libraries.architecture.AsyncAction
@@ -48,16 +48,16 @@ class DirectLogoutPresenter(
val isLastDevice by encryptionService.isLastDevice.collectAsState()
- fun handleEvent(event: DirectLogoutEvents) {
+ fun handleEvent(event: DirectLogoutEvent) {
when (event) {
- is DirectLogoutEvents.Logout -> {
+ is DirectLogoutEvent.Logout -> {
if (logoutAction.value.isConfirming() || event.ignoreSdkError) {
localCoroutineScope.logout(logoutAction, event.ignoreSdkError)
} else {
logoutAction.value = AsyncAction.ConfirmingNoParams
}
}
- DirectLogoutEvents.CloseDialogs -> {
+ DirectLogoutEvent.CloseDialogs -> {
logoutAction.value = AsyncAction.Uninitialized
}
}
diff --git a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPresenterTest.kt b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPresenterTest.kt
index 274234a338..5b14bc5cc3 100644
--- a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPresenterTest.kt
+++ b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPresenterTest.kt
@@ -139,10 +139,10 @@ class LogoutPresenterTest {
presenter.present()
}.test {
val initialState = awaitFirstItem()
- initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
+ initialState.eventSink.invoke(LogoutEvent.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- initialState.eventSink.invoke(LogoutEvents.CloseDialogs)
+ initialState.eventSink.invoke(LogoutEvent.CloseDialogs)
val finalState = awaitItem()
assertThat(finalState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
}
@@ -157,10 +157,10 @@ class LogoutPresenterTest {
presenter.present()
}.test {
val initialState = awaitFirstItem()
- initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
+ initialState.eventSink.invoke(LogoutEvent.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- confirmationState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
+ confirmationState.eventSink.invoke(LogoutEvent.Logout(ignoreSdkError = false))
val loadingState = awaitItem()
assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
val successState = awaitItem()
@@ -184,15 +184,15 @@ class LogoutPresenterTest {
presenter.present()
}.test {
val initialState = awaitFirstItem()
- initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
+ initialState.eventSink.invoke(LogoutEvent.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- confirmationState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
+ confirmationState.eventSink.invoke(LogoutEvent.Logout(ignoreSdkError = false))
val loadingState = awaitItem()
assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
val errorState = awaitItem()
assertThat(errorState.logoutAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
- errorState.eventSink.invoke(LogoutEvents.CloseDialogs)
+ errorState.eventSink.invoke(LogoutEvent.CloseDialogs)
val finalState = awaitItem()
assertThat(finalState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
}
@@ -214,15 +214,15 @@ class LogoutPresenterTest {
presenter.present()
}.test {
val initialState = awaitFirstItem()
- initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
+ initialState.eventSink.invoke(LogoutEvent.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- confirmationState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
+ confirmationState.eventSink.invoke(LogoutEvent.Logout(ignoreSdkError = false))
val loadingState = awaitItem()
assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
val errorState = awaitItem()
assertThat(errorState.logoutAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
- errorState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = true))
+ errorState.eventSink.invoke(LogoutEvent.Logout(ignoreSdkError = true))
val loadingState2 = awaitItem()
assertThat(loadingState2.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
val successState = awaitItem()
diff --git a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutViewTest.kt b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutViewTest.kt
index 3fbae4bbc5..f69ec8f0ca 100644
--- a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutViewTest.kt
+++ b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutViewTest.kt
@@ -28,20 +28,20 @@ import org.junit.Test
class LogoutViewTest : RobolectricTest() {
@Test
- fun `clicking on logout sends a LogoutEvents`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ fun `clicking on logout sends a LogoutEvent`() = runAndroidComposeUiTest {
+ val eventsRecorder = EventsRecorder()
setLogoutView(
aLogoutState(
eventSink = eventsRecorder
),
)
clickOn(CommonStrings.action_signout)
- eventsRecorder.assertSingle(LogoutEvents.Logout(false))
+ eventsRecorder.assertSingle(LogoutEvent.Logout(false))
}
@Test
- fun `confirming logout sends a LogoutEvents`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ fun `confirming logout sends a LogoutEvent`() = runAndroidComposeUiTest {
+ val eventsRecorder = EventsRecorder()
setLogoutView(
aLogoutState(
logoutAction = AsyncAction.ConfirmingNoParams,
@@ -49,12 +49,12 @@ class LogoutViewTest : RobolectricTest() {
),
)
pressTag(TestTags.dialogPositive.value)
- eventsRecorder.assertSingle(LogoutEvents.Logout(false))
+ eventsRecorder.assertSingle(LogoutEvent.Logout(false))
}
@Test
fun `clicking on back invoke back callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce { callback ->
setLogoutView(
aLogoutState(
@@ -67,8 +67,8 @@ class LogoutViewTest : RobolectricTest() {
}
@Test
- fun `clicking on confirm after error sends a LogoutEvents`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ fun `clicking on confirm after error sends a LogoutEvent`() = runAndroidComposeUiTest {
+ val eventsRecorder = EventsRecorder()
setLogoutView(
aLogoutState(
logoutAction = AsyncAction.Failure(Exception("Failed to logout")),
@@ -76,12 +76,12 @@ class LogoutViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_signout_anyway)
- eventsRecorder.assertSingle(LogoutEvents.Logout(true))
+ eventsRecorder.assertSingle(LogoutEvent.Logout(true))
}
@Test
- fun `clicking on cancel after error sends a LogoutEvents`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ fun `clicking on cancel after error sends a LogoutEvent`() = runAndroidComposeUiTest {
+ val eventsRecorder = EventsRecorder()
setLogoutView(
aLogoutState(
logoutAction = AsyncAction.Failure(Exception("Failed to logout")),
@@ -89,12 +89,12 @@ class LogoutViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_cancel)
- eventsRecorder.assertSingle(LogoutEvents.CloseDialogs)
+ eventsRecorder.assertSingle(LogoutEvent.CloseDialogs)
}
@Test
fun `last session setting button invoke onChangeRecoveryKeyClicked`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce { callback ->
setLogoutView(
aLogoutState(
diff --git a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutViewTest.kt b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutViewTest.kt
index db8eed2a54..a413ba4e36 100644
--- a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutViewTest.kt
+++ b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutViewTest.kt
@@ -14,7 +14,7 @@ import androidx.activity.ComponentActivity
import androidx.compose.ui.test.AndroidComposeUiTest
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
-import io.element.android.features.logout.api.direct.DirectLogoutEvents
+import io.element.android.features.logout.api.direct.DirectLogoutEvent
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.features.logout.api.direct.aDirectLogoutState
import io.element.android.libraries.architecture.AsyncAction
@@ -29,7 +29,7 @@ import org.junit.Test
class DefaultDirectLogoutViewTest : RobolectricTest() {
@Test
fun `clicking on confirm logout sends expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setDefaultDirectLogoutView(
state = aDirectLogoutState(
logoutAction = AsyncAction.ConfirmingNoParams,
@@ -37,12 +37,12 @@ class DefaultDirectLogoutViewTest : RobolectricTest() {
)
)
clickOn(CommonStrings.action_signout)
- eventsRecorder.assertSingle(DirectLogoutEvents.Logout(false))
+ eventsRecorder.assertSingle(DirectLogoutEvent.Logout(false))
}
@Test
fun `clicking on cancel logout sends expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setDefaultDirectLogoutView(
state = aDirectLogoutState(
logoutAction = AsyncAction.ConfirmingNoParams,
@@ -50,13 +50,13 @@ class DefaultDirectLogoutViewTest : RobolectricTest() {
)
)
clickOn(CommonStrings.action_cancel)
- eventsRecorder.assertSingle(DirectLogoutEvents.CloseDialogs)
+ eventsRecorder.assertSingle(DirectLogoutEvent.CloseDialogs)
}
@Ignore("Pressing back key should dismiss the dialog, and so generate the expected event, but it's not the case.")
@Test
fun `clicking on back invoke back callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setDefaultDirectLogoutView(
state = aDirectLogoutState(
logoutAction = AsyncAction.ConfirmingNoParams,
@@ -64,12 +64,12 @@ class DefaultDirectLogoutViewTest : RobolectricTest() {
)
)
pressBackKey()
- eventsRecorder.assertSingle(DirectLogoutEvents.CloseDialogs)
+ eventsRecorder.assertSingle(DirectLogoutEvent.CloseDialogs)
}
@Test
fun `clicking on confirm after error sends expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setDefaultDirectLogoutView(
state = aDirectLogoutState(
logoutAction = AsyncAction.Failure(Exception("Error")),
@@ -77,12 +77,12 @@ class DefaultDirectLogoutViewTest : RobolectricTest() {
)
)
clickOn(CommonStrings.action_signout_anyway)
- eventsRecorder.assertSingle(DirectLogoutEvents.Logout(true))
+ eventsRecorder.assertSingle(DirectLogoutEvent.Logout(true))
}
@Test
fun `clicking on cancel after error sends expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
setDefaultDirectLogoutView(
state = aDirectLogoutState(
logoutAction = AsyncAction.Failure(Exception("Error")),
@@ -90,7 +90,7 @@ class DefaultDirectLogoutViewTest : RobolectricTest() {
)
)
clickOn(CommonStrings.action_cancel)
- eventsRecorder.assertSingle(DirectLogoutEvents.CloseDialogs)
+ eventsRecorder.assertSingle(DirectLogoutEvent.CloseDialogs)
}
}
diff --git a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DirectLogoutPresenterTest.kt b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DirectLogoutPresenterTest.kt
index 835ed4e94e..d11c31cf1b 100644
--- a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DirectLogoutPresenterTest.kt
+++ b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DirectLogoutPresenterTest.kt
@@ -13,7 +13,7 @@ import app.cash.molecule.moleculeFlow
import app.cash.turbine.ReceiveTurbine
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
-import io.element.android.features.logout.api.direct.DirectLogoutEvents
+import io.element.android.features.logout.api.direct.DirectLogoutEvent
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.encryption.BackupUploadState
@@ -87,10 +87,10 @@ class DirectLogoutPresenterTest {
presenter.present()
}.test {
val initialState = awaitFirstItem()
- initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
+ initialState.eventSink.invoke(DirectLogoutEvent.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- initialState.eventSink.invoke(DirectLogoutEvents.CloseDialogs)
+ initialState.eventSink.invoke(DirectLogoutEvent.CloseDialogs)
val finalState = awaitItem()
assertThat(finalState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
}
@@ -103,10 +103,10 @@ class DirectLogoutPresenterTest {
presenter.present()
}.test {
val initialState = awaitFirstItem()
- initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
+ initialState.eventSink.invoke(DirectLogoutEvent.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- confirmationState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
+ confirmationState.eventSink.invoke(DirectLogoutEvent.Logout(ignoreSdkError = false))
val loadingState = awaitItem()
assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
val successState = awaitItem()
@@ -128,15 +128,15 @@ class DirectLogoutPresenterTest {
presenter.present()
}.test {
val initialState = awaitFirstItem()
- initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
+ initialState.eventSink.invoke(DirectLogoutEvent.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- confirmationState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
+ confirmationState.eventSink.invoke(DirectLogoutEvent.Logout(ignoreSdkError = false))
val loadingState = awaitItem()
assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
val errorState = awaitItem()
assertThat(errorState.logoutAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
- errorState.eventSink.invoke(DirectLogoutEvents.CloseDialogs)
+ errorState.eventSink.invoke(DirectLogoutEvent.CloseDialogs)
val finalState = awaitItem()
assertThat(finalState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
}
@@ -158,15 +158,15 @@ class DirectLogoutPresenterTest {
presenter.present()
}.test {
val initialState = awaitFirstItem()
- initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
+ initialState.eventSink.invoke(DirectLogoutEvent.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.ConfirmingNoParams)
- confirmationState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
+ confirmationState.eventSink.invoke(DirectLogoutEvent.Logout(ignoreSdkError = false))
val loadingState = awaitItem()
assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
val errorState = awaitItem()
assertThat(errorState.logoutAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
- errorState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = true))
+ errorState.eventSink.invoke(DirectLogoutEvent.Logout(ignoreSdkError = true))
val loadingState2 = awaitItem()
assertThat(loadingState2.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
val successState = awaitItem()
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt
index d4fce982e8..97d3465ce7 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt
@@ -43,7 +43,7 @@ import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPr
import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactories
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.roommembermoderation.api.ModerationAction
-import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents
+import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvent
import io.element.android.features.roommembermoderation.api.RoomMemberModerationRenderer
import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab
import io.element.android.libraries.androidutils.system.openUrlInExternalApp
@@ -348,7 +348,7 @@ class MessagesNode(
onSelectAction = { action, target ->
when (action) {
is ModerationAction.DisplayProfile -> callback.navigateToRoomMemberDetails(target.userId)
- else -> state.roomMemberModerationState.eventSink(RoomMemberModerationEvents.ProcessAction(action, target))
+ else -> state.roomMemberModerationState.eventSink(RoomMemberModerationEvent.ProcessAction(action, target))
}
},
onAvatarClick = { user ->
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt
index 4af0c05955..6a019d865b 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt
@@ -51,10 +51,11 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent
import io.element.android.features.messages.impl.timeline.model.event.captionOrNull
+import io.element.android.features.messages.impl.timeline.model.event.htmlCaptionOrNull
import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState
import io.element.android.features.messages.impl.voicemessages.composer.DefaultVoiceMessageComposerPresenter
import io.element.android.features.roomcall.api.RoomCallState
-import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents
+import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvent
import io.element.android.features.roommembermoderation.api.RoomMemberModerationState
import io.element.android.libraries.androidutils.clipboard.ClipboardHelper
import io.element.android.libraries.architecture.AsyncData
@@ -263,7 +264,7 @@ class MessagesPresenter(
}
}
is MessagesEvent.OnUserClicked -> {
- roomMemberModerationState.eventSink(RoomMemberModerationEvents.ShowActionsForUser(event.user))
+ roomMemberModerationState.eventSink(RoomMemberModerationEvent.ShowActionsForUser(event.user))
}
MessagesEvent.StopLiveLocationShare -> {
localCoroutineScope.launch {
@@ -377,7 +378,7 @@ class MessagesPresenter(
TimelineItemAction.Edit,
TimelineItemAction.EditPoll -> handleActionEdit(targetEvent, composerState, enableTextFormatting)
TimelineItemAction.AddCaption -> handleActionAddCaption(targetEvent, composerState)
- TimelineItemAction.EditCaption -> handleActionEditCaption(targetEvent, composerState)
+ TimelineItemAction.EditCaption -> handleActionEditCaption(targetEvent, composerState, enableTextFormatting)
TimelineItemAction.RemoveCaption -> handleRemoveCaption(targetEvent)
TimelineItemAction.Reply -> handleActionReply(targetEvent, composerState, timelineProtectionState)
TimelineItemAction.ReplyInThread -> {
@@ -546,10 +547,15 @@ class MessagesPresenter(
private suspend fun handleActionEditCaption(
targetEvent: TimelineItem.Event,
composerState: MessageComposerState,
+ enableTextFormatting: Boolean,
) {
val composerMode = MessageComposerMode.EditCaption(
eventOrTransactionId = targetEvent.eventOrTransactionId,
- content = targetEvent.content.captionOrNull().orEmpty(),
+ content = if (enableTextFormatting) {
+ targetEvent.content.htmlCaptionOrNull() ?: targetEvent.content.captionOrNull()
+ } else {
+ targetEvent.content.captionOrNull()
+ }.orEmpty(),
)
composerState.eventSink(
MessageComposerEvent.SetMode(composerMode)
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStatePreviewParam.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStatePreviewParam.kt
index 8ab7e64121..d792ab5ed4 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStatePreviewParam.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStatePreviewParam.kt
@@ -38,7 +38,7 @@ import io.element.android.features.messages.impl.timeline.protection.TimelinePro
import io.element.android.features.messages.impl.timeline.protection.aTimelineProtectionState
import io.element.android.features.roomcall.api.RoomCallState
import io.element.android.features.roomcall.api.aStandByCallState
-import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents
+import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvent
import io.element.android.features.roommembermoderation.api.RoomMemberModerationPermissions
import io.element.android.features.roommembermoderation.api.RoomMemberModerationState
import io.element.android.libraries.architecture.AsyncData
@@ -168,7 +168,7 @@ fun aRoomMemberModerationState(
permissions: RoomMemberModerationPermissions = RoomMemberModerationPermissions.DEFAULT,
) = object : RoomMemberModerationState {
override val permissions: RoomMemberModerationPermissions = permissions
- override val eventSink: (RoomMemberModerationEvents) -> Unit = {}
+ override val eventSink: (RoomMemberModerationEvent) -> Unit = {}
}
fun aUserEventPermissions(
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsProcessor.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsProcessor.kt
index 010aff5d4b..8f29693e9a 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsProcessor.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsProcessor.kt
@@ -115,9 +115,10 @@ class SuggestionsProcessor(
.filterUpTo(MAX_BATCH_ITEMS) { member ->
isJoinedMemberAndNotSelf(member) && memberMatchesQuery(member, query)
}
+ .sortedBy { member -> matchRank(member, query) }
.map(ResolvedSuggestion::Member)
- if ("room".contains(query) && canSendRoomMention) {
+ if ("room".startsWith(query, ignoreCase = true) && canSendRoomMention) {
listOf(ResolvedSuggestion.AtRoom) + matchingMembers
} else {
matchingMembers
@@ -125,6 +126,18 @@ class SuggestionsProcessor(
}
}
+ /**
+ * Members whose display name starts with the query come first, then members whose user id
+ * localpart starts with it, then the remaining matches on any other part of the name or id.
+ */
+ private fun matchRank(member: RoomMember, query: String): Int {
+ return when {
+ member.displayName?.startsWith(query, ignoreCase = true) == true -> 0
+ member.userId.extractedDisplayName.startsWith(query, ignoreCase = true) -> 1
+ else -> 2
+ }
+ }
+
companion object {
// We don't want to retrieve thousands of members
private const val MAX_BATCH_ITEMS = 100
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/ThreadedMessagesNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/ThreadedMessagesNode.kt
index b7fd9f572f..cf3c701015 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/ThreadedMessagesNode.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/ThreadedMessagesNode.kt
@@ -46,7 +46,7 @@ import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPr
import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactories
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.roommembermoderation.api.ModerationAction
-import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents
+import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvent
import io.element.android.features.roommembermoderation.api.RoomMemberModerationRenderer
import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab
import io.element.android.libraries.androidutils.system.openUrlInExternalApp
@@ -343,7 +343,7 @@ class ThreadedMessagesNode(
onSelectAction = { action, target ->
when (action) {
is ModerationAction.DisplayProfile -> callback.navigateToRoomMemberDetails(target.userId)
- else -> state.roomMemberModerationState.eventSink(RoomMemberModerationEvents.ProcessAction(action, target))
+ else -> state.roomMemberModerationState.eventSink(RoomMemberModerationEvent.ProcessAction(action, target))
}
},
onAvatarClick = { user ->
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListEvent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListEvent.kt
new file mode 100644
index 0000000000..191d5d111b
--- /dev/null
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListEvent.kt
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2026 Element Creations Ltd.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
+ * Please see LICENSE files in the repository root for full details.
+ */
+
+package io.element.android.features.messages.impl.threads.list
+
+sealed interface ThreadsListEvent {
+ data object Paginate : ThreadsListEvent
+}
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListPresenter.kt
index ba10df46f2..d6d928326c 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListPresenter.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListPresenter.kt
@@ -20,13 +20,10 @@ import io.element.android.features.messages.impl.utils.messagesummary.MessageSum
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.dateformatter.api.DateFormatter
import io.element.android.libraries.dateformatter.api.DateFormatterMode
-import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
-import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.threads.ThreadListPaginationStatus
import io.element.android.libraries.matrix.ui.model.getAvatarData
-import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.onStart
@@ -104,9 +101,9 @@ class ThreadsListPresenter(
derivedStateOf { roomInfo.heroes.map { it.getAvatarData(AvatarSize.CurrentUserTopBar) }.toImmutableList() }
}
- fun handleEvent(event: ThreadsListEvents) {
+ fun handleEvent(event: ThreadsListEvent) {
when (event) {
- ThreadsListEvents.Paginate -> if ((paginationStatus as? ThreadListPaginationStatus.Idle)?.hasMoreToLoad == true) {
+ ThreadsListEvent.Paginate -> if ((paginationStatus as? ThreadListPaginationStatus.Idle)?.hasMoreToLoad == true) {
coroutineScope.launch {
Timber.d("Paginating thread list: $paginationStatus")
threadsListService.paginate()
@@ -129,17 +126,3 @@ class ThreadsListPresenter(
)
}
}
-
-data class ThreadsListState(
- val roomId: RoomId,
- val roomName: String,
- val roomAvatarUrl: String?,
- val isRoomTombstoned: Boolean,
- val heroes: ImmutableList,
- val threads: ImmutableList,
- val eventSink: (ThreadsListEvents) -> Unit,
-)
-
-sealed interface ThreadsListEvents {
- data object Paginate : ThreadsListEvents
-}
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListState.kt
new file mode 100644
index 0000000000..8aafd49d21
--- /dev/null
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListState.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2026 Element Creations Ltd.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
+ * Please see LICENSE files in the repository root for full details.
+ */
+
+package io.element.android.features.messages.impl.threads.list
+
+import io.element.android.libraries.designsystem.components.avatar.AvatarData
+import io.element.android.libraries.matrix.api.core.RoomId
+import kotlinx.collections.immutable.ImmutableList
+
+data class ThreadsListState(
+ val roomId: RoomId,
+ val roomName: String,
+ val roomAvatarUrl: String?,
+ val isRoomTombstoned: Boolean,
+ val heroes: ImmutableList,
+ val threads: ImmutableList,
+ val eventSink: (ThreadsListEvent) -> Unit,
+)
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListView.kt
index 6480dacfcf..c38da19a67 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListView.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListView.kt
@@ -156,7 +156,7 @@ fun ThreadsListView(
}
ScrollHelper(lazyListState) {
- state.eventSink(ThreadsListEvents.Paginate)
+ state.eventSink(ThreadsListEvent.Paginate)
}
}
}
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt
index 040d0450ff..75966db1a3 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt
@@ -108,6 +108,7 @@ class TimelineItemContentMessageFactory(
fileSize = messageType.info?.size ?: 0,
caption = messageType.caption?.trimEnd(),
formattedCaption = formattedCaption,
+ htmlCaption = messageType.formattedCaption?.body,
isEdited = content.isEdited,
mediaSource = messageType.source,
thumbnailSource = messageType.info?.thumbnailSource,
@@ -132,6 +133,7 @@ class TimelineItemContentMessageFactory(
fileSize = messageType.info?.size ?: 0,
caption = messageType.caption?.trimEnd(),
formattedCaption = formattedCaption,
+ htmlCaption = messageType.formattedCaption?.body,
isEdited = content.isEdited,
mediaSource = messageType.source,
thumbnailSource = messageType.info?.thumbnailSource,
@@ -174,6 +176,7 @@ class TimelineItemContentMessageFactory(
fileSize = messageType.info?.size ?: 0,
caption = messageType.caption?.trimEnd(),
formattedCaption = formattedCaption,
+ htmlCaption = messageType.formattedCaption?.body,
isEdited = content.isEdited,
thumbnailSource = messageType.info?.thumbnailSource,
mediaSource = messageType.source,
@@ -198,6 +201,7 @@ class TimelineItemContentMessageFactory(
fileSize = messageType.info?.size ?: 0,
caption = messageType.caption?.trimEnd(),
formattedCaption = formattedCaption,
+ htmlCaption = messageType.formattedCaption?.body,
isEdited = content.isEdited,
mediaSource = messageType.source,
duration = messageType.info?.duration ?: Duration.ZERO,
@@ -216,6 +220,7 @@ class TimelineItemContentMessageFactory(
fileSize = messageType.info?.size ?: 0,
caption = messageType.caption?.trimEnd(),
formattedCaption = formattedCaption,
+ htmlCaption = messageType.formattedCaption?.body,
isEdited = content.isEdited,
mediaSource = messageType.source,
duration = messageType.info?.duration ?: Duration.ZERO,
@@ -235,6 +240,7 @@ class TimelineItemContentMessageFactory(
fileSize = messageType.info?.size ?: 0,
caption = messageType.caption?.trimEnd(),
formattedCaption = formattedCaption,
+ htmlCaption = messageType.formattedCaption?.body,
isEdited = content.isEdited,
thumbnailSource = messageType.info?.thumbnailSource,
mediaSource = messageType.source,
@@ -345,6 +351,7 @@ class TimelineItemContentMessageFactory(
body = messageType.body,
caption = messageType.body.trimEnd().takeIf { it.isNotEmpty() },
formattedCaption = formattedCaption,
+ htmlCaption = messageType.formatted?.body,
isEdited = content.isEdited,
items = galleryItems.toImmutableList(),
)
@@ -402,6 +409,7 @@ class TimelineItemContentMessageFactory(
body = messageType.body,
caption = messageType.body.trimEnd().takeIf { it.isNotEmpty() },
formattedCaption = formattedCaption,
+ htmlCaption = messageType.formatted?.body,
isEdited = content.isEdited,
attachments = attachments.toImmutableList(),
)
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemEventFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemEventFactory.kt
index af3e18e3cc..6cd6b66cf1 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemEventFactory.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemEventFactory.kt
@@ -28,10 +28,12 @@ import io.element.android.libraries.dateformatter.api.DateFormatterMode
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.api.MatrixClient
+import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.EventThreadInfo
+import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails
import io.element.android.libraries.matrix.api.timeline.item.event.getAvatarUrl
import io.element.android.libraries.matrix.api.timeline.item.event.getDisambiguatedDisplayName
import io.element.android.libraries.matrix.ui.messages.reply.map
@@ -64,7 +66,7 @@ class TimelineItemEventFactory(
val currentSender = currentTimelineItem.event.sender
val groupPosition =
computeGroupPosition(currentTimelineItem, timelineItems, index)
- val senderProfile = currentTimelineItem.event.senderProfile
+ val senderProfile = currentTimelineItem.event.senderProfile.orFallbackTo(roomMembers, currentSender)
val sentTime = dateFormatter.format(
timestamp = currentTimelineItem.event.timestamp,
mode = DateFormatterMode.TimeOnly,
@@ -138,11 +140,32 @@ class TimelineItemEventFactory(
roomMembers: List,
renderReadReceipts: Boolean,
): TimelineItem.Event {
+ val senderProfile = receivedMatrixTimelineItem.event.senderProfile.orFallbackTo(roomMembers, timelineItem.senderId)
return timelineItem.copy(
+ senderProfile = senderProfile,
+ senderAvatar = timelineItem.senderAvatar.copy(
+ name = senderProfile.getDisambiguatedDisplayName(timelineItem.senderId),
+ url = senderProfile.getAvatarUrl(),
+ ),
readReceiptState = receivedMatrixTimelineItem.computeReadReceiptState(roomMembers, renderReadReceipts)
)
}
+ /**
+ * The timeline only knows the profiles the SDK has resolved, so a sender it has nothing for is rendered as a raw
+ * user ID. The room member list usually knows that user, so use it rather than showing the ID.
+ */
+ private fun ProfileDetails.orFallbackTo(roomMembers: List, senderId: UserId): ProfileDetails {
+ if (this is ProfileDetails.Ready) return this
+ val member = roomMembers.find { it.userId == senderId } ?: return this
+ return ProfileDetails.Ready(
+ displayName = member.displayName,
+ displayNameAmbiguous = member.isNameAmbiguous,
+ avatarUrl = member.avatarUrl,
+ displayedStatus = member.displayedStatus,
+ )
+ }
+
private fun MatrixTimelineItem.Event.computeReactionsState(): TimelineItemReactions {
if (!config.computeReactions) {
return TimelineItemReactions(reactions = persistentListOf())
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt
index 431942378a..3b16f79f79 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/Groupability.kt
@@ -91,7 +91,7 @@ internal fun MatrixTimelineItem.Event.canBeDisplayedInBubbleBlock(): Boolean {
// Can be grouped
is FailedToParseMessageLikeContent,
is MessageContent,
- RedactedContent,
+ is RedactedContent,
is StickerContent,
is PollContent,
is UnableToDecryptContent,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouper.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouper.kt
index 2e01e53828..b34c66a08d 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouper.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouper.kt
@@ -12,6 +12,7 @@ import androidx.annotation.VisibleForTesting
import dev.zacsweers.metro.Inject
import dev.zacsweers.metro.SingleIn
import io.element.android.features.messages.impl.timeline.model.TimelineItem
+import io.element.android.features.messages.impl.timeline.model.TimelineItemThreadInfo
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.core.UniqueId
@@ -99,7 +100,8 @@ internal const val MIN_REDACTED_RUN_SIZE = 3
* Fold runs of [MIN_REDACTED_RUN_SIZE] or more consecutive deleted (redacted) messages into a single
* [TimelineItem.GroupedEvents], so a long stretch of "Message removed" tiles shows as one expandable
* "N removed messages" line, like element-web. Shorter runs, and anything that is not a redacted event
- * (day dividers included), are left untouched.
+ * (day dividers included), are left untouched. A deleted message that still heads a thread is left
+ * untouched too, so that its thread summary stays reachable.
*
* This runs as the final step of [TimelineItemGrouper.group], after the state and membership events
* have been grouped. It is deliberately kept out of the normal grouping: a run needs a higher minimum
@@ -134,7 +136,7 @@ internal fun List.collapseRedactedRuns(groupIds: MutableMap,
) : TimelineItemEventContent, TimelineItemEventMutableContent {
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt
index f28de4f673..8c191ef140 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt
@@ -17,6 +17,7 @@ data class TimelineItemAudioContent(
override val fileSize: Long?,
override val caption: String?,
override val formattedCaption: CharSequence?,
+ override val htmlCaption: String? = null,
override val isEdited: Boolean,
val duration: Duration,
override val mediaSource: MediaSource,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt
index 01146a070b..efa73b91fc 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt
@@ -33,6 +33,9 @@ sealed interface TimelineItemEventContentWithAttachment :
val fileSize: Long?
val caption: String?
val formattedCaption: CharSequence?
+
+ /** The caption as it was written, in HTML, so that editing it can start from the formatted text. */
+ val htmlCaption: String?
val mediaSource: MediaSource
val mimeType: String
val formattedFileSize: String
@@ -127,6 +130,13 @@ fun TimelineItemEventContent.formattedCaptionOrNull(): CharSequence? = when (thi
else -> null
}
+fun TimelineItemEventContent.htmlCaptionOrNull(): String? = when (this) {
+ is TimelineItemEventContentWithAttachment -> htmlCaption
+ is TimelineItemGalleryContent -> htmlCaption
+ is TimelineItemAttachmentsContent -> htmlCaption
+ else -> null
+}
+
fun TimelineItemEventContentWithAttachment.duration(): Duration? {
return when (this) {
is TimelineItemAudioContent -> duration
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt
index 680797e36b..36beeeb91d 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt
@@ -16,6 +16,7 @@ data class TimelineItemFileContent(
override val fileSize: Long?,
override val caption: String?,
override val formattedCaption: CharSequence?,
+ override val htmlCaption: String? = null,
override val isEdited: Boolean,
override val mediaSource: MediaSource,
val thumbnailSource: MediaSource?,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemGalleryContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemGalleryContent.kt
index f376a2a00a..840f19488d 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemGalleryContent.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemGalleryContent.kt
@@ -16,6 +16,7 @@ data class TimelineItemGalleryContent(
val body: String,
val caption: String?,
val formattedCaption: CharSequence?,
+ val htmlCaption: String? = null,
override val isEdited: Boolean,
val items: ImmutableList,
) : TimelineItemEventContent, TimelineItemEventMutableContent {
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt
index 4828f22ba8..5e78adc945 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt
@@ -19,6 +19,7 @@ data class TimelineItemImageContent(
override val fileSize: Long?,
override val caption: String?,
override val formattedCaption: CharSequence?,
+ override val htmlCaption: String? = null,
override val isEdited: Boolean,
override val mediaSource: MediaSource,
val thumbnailSource: MediaSource?,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentPreviewParam.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentPreviewParam.kt
index cd93c7c006..316b2ab79b 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentPreviewParam.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentPreviewParam.kt
@@ -28,6 +28,7 @@ fun aTimelineItemImageContent(
blurhash: String? = A_BLUR_HASH,
filename: String = "A picture.jpg",
caption: String? = null,
+ htmlCaption: String? = null,
width: Int? = null,
height: Int? = 300,
) = TimelineItemImageContent(
@@ -35,6 +36,7 @@ fun aTimelineItemImageContent(
fileSize = 4 * 1024 * 1024L,
caption = caption,
formattedCaption = null,
+ htmlCaption = htmlCaption,
isEdited = false,
mediaSource = MediaSource(""),
thumbnailSource = null,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt
index 9e2f08d5c7..65585bc028 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt
@@ -15,6 +15,7 @@ data class TimelineItemStickerContent(
override val fileSize: Long?,
override val caption: String?,
override val formattedCaption: CharSequence?,
+ override val htmlCaption: String? = null,
override val isEdited: Boolean,
override val mediaSource: MediaSource,
val thumbnailSource: MediaSource?,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt
index 80635c6e18..a1c8e279cd 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt
@@ -16,6 +16,7 @@ data class TimelineItemVideoContent(
override val fileSize: Long?,
override val caption: String?,
override val formattedCaption: CharSequence?,
+ override val htmlCaption: String? = null,
override val isEdited: Boolean,
val duration: Duration,
override val mediaSource: MediaSource,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt
index 29a432e6bd..806a703ea5 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt
@@ -19,6 +19,7 @@ data class TimelineItemVoiceContent(
override val fileSize: Long?,
override val caption: String?,
override val formattedCaption: CharSequence?,
+ override val htmlCaption: String? = null,
override val isEdited: Boolean,
val duration: Duration,
override val mediaSource: MediaSource,
diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt
index 227088f78c..4c0abc0a34 100644
--- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt
+++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt
@@ -989,6 +989,33 @@ class MessagesPresenterTest {
}
}
+ @Test
+ fun `present - handle action edit caption starts from the formatted caption`() = runTest {
+ val messageEvent = aMessageEvent(
+ content = aTimelineItemImageContent(
+ caption = "Hello world",
+ htmlCaption = "Hello world",
+ )
+ )
+ val composerRecorder = EventsRecorder()
+ val presenter = createMessagesPresenter(
+ messageComposerPresenter = { aMessageComposerState(eventSink = composerRecorder, showTextFormatting = true) },
+ )
+ presenter.testWithLifecycleOwner {
+ val initialState = awaitItem()
+ initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.EditCaption, messageEvent))
+ awaitItem()
+ composerRecorder.assertSingle(
+ MessageComposerEvent.SetMode(
+ composerMode = MessageComposerMode.EditCaption(
+ eventOrTransactionId = AN_EVENT_ID.toEventOrTransactionId(),
+ content = "Hello world",
+ )
+ )
+ )
+ }
+ }
+
@Test
fun `present - handle action add caption`() = runTest {
val composerRecorder = EventsRecorder()
diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsProcessorTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsProcessorTest.kt
index 6283d7236a..71a9ada1a8 100644
--- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsProcessorTest.kt
+++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsProcessorTest.kt
@@ -383,6 +383,48 @@ class SuggestionsProcessorTest {
)
}
+ @Test
+ fun `processing Mention suggestion returns the members matching the start of the query first`() = runTest {
+ val matchingOnAnyPart = aRoomMember(userId = UserId("@carol:server.org"), displayName = "Not Alice")
+ val matchingOnUserIdStart = aRoomMember(userId = UserId("@alicia:server.org"), displayName = null)
+ val matchingOnDisplayNameStart = aRoomMember(userId = UserId("@zoe:server.org"), displayName = "Alice")
+ val result = suggestionsProcessor.process(
+ suggestion = aMentionSuggestion("ali"),
+ roomMembersState = RoomMembersState.Ready(
+ persistentListOf(matchingOnAnyPart, matchingOnUserIdStart, matchingOnDisplayNameStart)
+ ),
+ roomAliasSuggestions = emptyList(),
+ currentUserId = A_USER_ID_2,
+ canSendRoomMention = { false },
+ isInThread = false,
+ )
+ assertThat(result).isEqualTo(
+ listOf(
+ ResolvedSuggestion.Member(matchingOnDisplayNameStart),
+ ResolvedSuggestion.Member(matchingOnUserIdStart),
+ ResolvedSuggestion.Member(matchingOnAnyPart),
+ )
+ )
+ }
+
+ @Test
+ fun `processing Mention suggestion returns room ignoring the case of the query`() = runTest {
+ val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), displayName = "alice")
+ val result = suggestionsProcessor.process(
+ suggestion = aMentionSuggestion("RO"),
+ roomMembersState = RoomMembersState.Ready(persistentListOf(aRoomMember)),
+ roomAliasSuggestions = emptyList(),
+ currentUserId = A_USER_ID_2,
+ canSendRoomMention = { true },
+ isInThread = false,
+ )
+ assertThat(result).isEqualTo(
+ listOf(
+ ResolvedSuggestion.AtRoom,
+ )
+ )
+ }
+
@Test
fun `processing Mention suggestion with return matching display name but not room if not allowed`() = runTest {
val aRoomMember = aRoomMember(userId = UserId("@alice:server.org"), displayName = "ro")
diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/threads/ThreadsListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/threads/ThreadsListPresenterTest.kt
index 9f8d210a16..fab7602906 100644
--- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/threads/ThreadsListPresenterTest.kt
+++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/threads/ThreadsListPresenterTest.kt
@@ -10,7 +10,7 @@ package io.element.android.features.messages.impl.threads
import com.google.common.truth.Truth.assertThat
import io.element.android.features.messages.impl.fixtures.aTimelineItemContentFactory
import io.element.android.features.messages.impl.messagesummary.FakeMessageSummaryFormatter
-import io.element.android.features.messages.impl.threads.list.ThreadsListEvents
+import io.element.android.features.messages.impl.threads.list.ThreadsListEvent
import io.element.android.features.messages.impl.threads.list.ThreadsListPresenter
import io.element.android.features.messages.impl.threads.list.aThreadListItem
import io.element.android.libraries.dateformatter.test.FakeDateFormatter
@@ -48,7 +48,7 @@ class ThreadsListPresenterTest {
// Pagination is automatically triggered on start, so we should have one call to paginate already
paginateRecorder.assertions().isCalledOnce()
- initialItem.eventSink(ThreadsListEvents.Paginate)
+ initialItem.eventSink(ThreadsListEvent.Paginate)
// Simulate a pagination result
threadsListService.emit(listOf(aThreadListItem()))
diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt
index e00cec3322..3b20614dac 100644
--- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt
+++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt
@@ -51,7 +51,6 @@ import io.element.android.libraries.matrix.api.timeline.item.event.EventReaction
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
import io.element.android.libraries.matrix.api.timeline.item.event.ReactionSender
import io.element.android.libraries.matrix.api.timeline.item.event.Receipt
-import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent
import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
import io.element.android.libraries.matrix.test.AN_EVENT_ID
@@ -69,6 +68,7 @@ import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
import io.element.android.libraries.matrix.test.timeline.aMessageContent
+import io.element.android.libraries.matrix.test.timeline.aRedactedContent
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
import io.element.android.libraries.matrix.test.timeline.item.event.aRoomMembershipContent
import io.element.android.libraries.matrix.ui.components.aMatrixUserList
@@ -880,7 +880,7 @@ class TimelinePresenterTest {
(0 until 3).map { index ->
MatrixTimelineItem.Event(
uniqueId = UniqueId("redacted_$index"),
- event = anEventTimelineItem(eventId = EventId("\$R$index"), content = RedactedContent),
+ event = anEventTimelineItem(eventId = EventId("\$R$index"), content = aRedactedContent()),
)
}
),
diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/TimelineItemsFactoryTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/TimelineItemsFactoryTest.kt
index f93c8f196e..0e174ce312 100644
--- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/TimelineItemsFactoryTest.kt
+++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/TimelineItemsFactoryTest.kt
@@ -12,12 +12,21 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.features.messages.impl.fixtures.aTimelineItemsFactory
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.TimelineItemGroupPosition
+import io.element.android.features.messages.impl.timeline.model.TimelineItemThreadInfo
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent
+import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.core.UniqueId
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
+import io.element.android.libraries.matrix.api.timeline.item.EventThreadInfo
+import io.element.android.libraries.matrix.api.timeline.item.ThreadSummary
import io.element.android.libraries.matrix.api.timeline.item.event.OtherMessageType
+import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails
+import io.element.android.libraries.matrix.test.A_THREAD_ID
import io.element.android.libraries.matrix.test.A_USER_ID
+import io.element.android.libraries.matrix.test.A_USER_ID_2
+import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.matrix.test.timeline.aMessageContent
+import io.element.android.libraries.matrix.test.timeline.aRedactedContent
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
@@ -84,6 +93,42 @@ class TimelineItemsFactoryTest {
).inOrder()
}
+ @Test
+ fun `redacted message keeps its thread info`() = runTest {
+ val factory = aTimelineItemsFactory(
+ config = TimelineItemsFactoryConfig(
+ computeReadReceipts = false,
+ computeReactions = false,
+ )
+ )
+ val items = listOf(
+ MatrixTimelineItem.Event(
+ uniqueId = UniqueId("event-0"),
+ event = anEventTimelineItem(
+ sender = A_USER_ID,
+ timestamp = 0L,
+ content = aRedactedContent(
+ threadInfo = EventThreadInfo.ThreadResponse(A_THREAD_ID),
+ ),
+ ),
+ )
+ )
+ var threadInfo: TimelineItemThreadInfo? = null
+ factory.timelineItems.test {
+ factory.replaceWith(
+ timelineItems = items,
+ roomMembers = emptyList(),
+ renderReadReceipts = false,
+ )
+ threadInfo = awaitItem()
+ .filterIsInstance()
+ .firstOrNull()
+ ?.threadInfo
+ cancelAndIgnoreRemainingEvents()
+ }
+ assertThat(threadInfo).isEqualTo(TimelineItemThreadInfo.ThreadResponse(A_THREAD_ID))
+ }
+
@Test
fun `a key verification request is not rendered`() = runTest {
val factory = aTimelineItemsFactory(
@@ -128,6 +173,111 @@ class TimelineItemsFactoryTest {
}
}
+ @Test
+ fun `a deleted message keeps the summary of the thread it heads`() = runTest {
+ val factory = aTimelineItemsFactory(
+ config = TimelineItemsFactoryConfig(
+ computeReadReceipts = false,
+ computeReactions = false,
+ )
+ )
+ val items = listOf(
+ MatrixTimelineItem.Event(
+ uniqueId = UniqueId("event-0"),
+ event = anEventTimelineItem(
+ sender = A_USER_ID,
+ content = aRedactedContent(
+ threadInfo = EventThreadInfo.ThreadRoot(
+ summary = ThreadSummary(latestEvent = AsyncData.Uninitialized, numberOfReplies = 3),
+ ),
+ ),
+ ),
+ ),
+ )
+ factory.timelineItems.test {
+ factory.replaceWith(
+ timelineItems = items,
+ roomMembers = emptyList(),
+ renderReadReceipts = false,
+ )
+ val threadInfo = awaitItem()
+ .filterIsInstance()
+ .single()
+ .threadInfo
+ assertThat(threadInfo).isInstanceOf(TimelineItemThreadInfo.ThreadRoot::class.java)
+ assertThat((threadInfo as TimelineItemThreadInfo.ThreadRoot).summary.numberOfReplies).isEqualTo(3)
+ cancelAndIgnoreRemainingEvents()
+ }
+ }
+
+ @Test
+ fun `a sender the timeline knows nothing about is named from the room member list`() = runTest {
+ val factory = aTimelineItemsFactory(
+ config = TimelineItemsFactoryConfig(
+ computeReadReceipts = false,
+ computeReactions = false,
+ )
+ )
+ val items = listOf(
+ MatrixTimelineItem.Event(
+ uniqueId = UniqueId("event-0"),
+ event = anEventTimelineItem(
+ sender = A_USER_ID,
+ senderProfile = ProfileDetails.Unavailable,
+ content = aMessageContent(body = "A regular message"),
+ ),
+ ),
+ )
+ factory.timelineItems.test {
+ factory.replaceWith(
+ timelineItems = items,
+ roomMembers = listOf(aRoomMember(userId = A_USER_ID, displayName = "Alice")),
+ renderReadReceipts = false,
+ )
+ val event = awaitItem().filterIsInstance().single()
+ assertThat(event.senderProfile).isEqualTo(
+ ProfileDetails.Ready(
+ displayName = "Alice",
+ displayNameAmbiguous = false,
+ avatarUrl = null,
+ displayedStatus = null,
+ )
+ )
+ assertThat(event.senderAvatar.name).isEqualTo("Alice")
+ cancelAndIgnoreRemainingEvents()
+ }
+ }
+
+ @Test
+ fun `a sender the room member list knows nothing about keeps the profile the timeline gave`() = runTest {
+ val factory = aTimelineItemsFactory(
+ config = TimelineItemsFactoryConfig(
+ computeReadReceipts = false,
+ computeReactions = false,
+ )
+ )
+ val items = listOf(
+ MatrixTimelineItem.Event(
+ uniqueId = UniqueId("event-0"),
+ event = anEventTimelineItem(
+ sender = A_USER_ID,
+ senderProfile = ProfileDetails.Unavailable,
+ content = aMessageContent(body = "A regular message"),
+ ),
+ ),
+ )
+ factory.timelineItems.test {
+ factory.replaceWith(
+ timelineItems = items,
+ roomMembers = listOf(aRoomMember(userId = A_USER_ID_2, displayName = "Bob")),
+ renderReadReceipts = false,
+ )
+ val event = awaitItem().filterIsInstance().single()
+ assertThat(event.senderProfile).isEqualTo(ProfileDetails.Unavailable)
+ cancelAndIgnoreRemainingEvents()
+ }
+ }
+
private suspend fun TestScope.groupPositionsOf(timestamps: List): List {
val factory = aTimelineItemsFactory(
config = TimelineItemsFactoryConfig(
diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt
index c014b003d7..0c6c81a513 100644
--- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt
+++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt
@@ -316,6 +316,7 @@ class TimelineItemContentMessageFactoryTest : RobolectricTest() {
fileSize = 555L,
caption = "body.mp4 caption",
formattedCaption = SpannedString("formatted"),
+ htmlCaption = "formatted",
isEdited = true,
duration = 1.minutes,
mediaSource = MediaSource(url = "url", json = null),
@@ -558,6 +559,7 @@ class TimelineItemContentMessageFactoryTest : RobolectricTest() {
fileSize = 888L,
caption = "body.jpg caption",
formattedCaption = SpannedString("formatted"),
+ htmlCaption = "formatted",
isEdited = true,
mediaSource = MediaSource(url = "url", json = null),
thumbnailSource = MediaSource("url_thumbnail"),
diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouperTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouperTest.kt
index 005eb5730e..f6ef4f0fc2 100644
--- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouperTest.kt
+++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouperTest.kt
@@ -15,11 +15,14 @@ import io.element.android.features.messages.impl.timeline.aTimelineItemReactions
import io.element.android.features.messages.impl.timeline.model.ReadReceiptData
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.TimelineItemReadReceipts
+import io.element.android.features.messages.impl.timeline.model.TimelineItemThreadInfo
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateEventContent
import io.element.android.features.messages.impl.timeline.model.virtual.aTimelineItemDaySeparatorModel
+import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.components.avatar.anAvatarData
import io.element.android.libraries.matrix.api.core.UniqueId
+import io.element.android.libraries.matrix.api.timeline.item.ThreadSummary
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.A_USER_ID
@@ -190,6 +193,22 @@ class TimelineItemGrouperTest {
)
}
+ @Test
+ fun `a deleted message that still heads a thread is left out of the removed messages group`() {
+ val threadRoot = aGroupableItem.copy(
+ id = UniqueId("r1"),
+ content = TimelineItemRedactedContent,
+ threadInfo = TimelineItemThreadInfo.ThreadRoot(
+ summary = ThreadSummary(latestEvent = AsyncData.Uninitialized, numberOfReplies = 2),
+ latestEventText = null,
+ ),
+ )
+ val r0 = aGroupableItem.copy(id = UniqueId("r0"), content = TimelineItemRedactedContent)
+ val r2 = aGroupableItem.copy(id = UniqueId("r2"), content = TimelineItemRedactedContent)
+ val result = sut.group(listOf(r0, threadRoot, r2))
+ assertThat(result).isEqualTo(listOf(r0, threadRoot, r2))
+ }
+
@Test
fun `a run of fewer than three redacted events is left untouched`() {
val r0 = aGroupableItem.copy(id = UniqueId("r0"), content = TimelineItemRedactedContent)
diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/RedactedVoiceMessageManagerTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/RedactedVoiceMessageManagerTest.kt
index a1ffd1f02b..9a5eda366b 100644
--- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/RedactedVoiceMessageManagerTest.kt
+++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/RedactedVoiceMessageManagerTest.kt
@@ -16,11 +16,11 @@ import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails
-import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.AN_EVENT_ID_2
import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.core.FakeSendHandle
+import io.element.android.libraries.matrix.test.timeline.aRedactedContent
import io.element.android.libraries.mediaplayer.api.MediaPlayer
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
import io.element.android.tests.testutils.testCoroutineDispatchers
@@ -88,7 +88,7 @@ fun aRedactedMatrixTimeline(eventId: EventId) = listOf(
sender = A_USER_ID,
senderProfile = ProfileDetails.Unavailable,
timestamp = 9442,
- content = RedactedContent,
+ content = aRedactedContent(),
origin = null,
timelineItemDebugInfoProvider = {
TimelineItemDebugInfo(
diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryEvents.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryEvent.kt
similarity index 81%
rename from features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryEvents.kt
rename to features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryEvent.kt
index 14ce13d67a..9d0d699d89 100644
--- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryEvents.kt
+++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryEvent.kt
@@ -11,9 +11,9 @@ package io.element.android.features.poll.impl.history
import io.element.android.features.poll.impl.history.model.PollHistoryFilter
import io.element.android.libraries.matrix.api.core.EventId
-sealed interface PollHistoryEvents {
- data object LoadMore : PollHistoryEvents
- data class SelectPollAnswer(val pollStartId: EventId, val answerId: String) : PollHistoryEvents
- data class EndPoll(val pollStartId: EventId) : PollHistoryEvents
- data class SelectFilter(val filter: PollHistoryFilter) : PollHistoryEvents
+sealed interface PollHistoryEvent {
+ data object LoadMore : PollHistoryEvent
+ data class SelectPollAnswer(val pollStartId: EventId, val answerId: String) : PollHistoryEvent
+ data class EndPoll(val pollStartId: EventId) : PollHistoryEvent
+ data class SelectFilter(val filter: PollHistoryFilter) : PollHistoryEvent
}
diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenter.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenter.kt
index 434e2ed18c..74a511da45 100644
--- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenter.kt
+++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenter.kt
@@ -63,22 +63,22 @@ class PollHistoryPresenter(
}
}
val coroutineScope = rememberCoroutineScope()
- fun handleEvent(event: PollHistoryEvents) {
+ fun handleEvent(event: PollHistoryEvent) {
when (event) {
- is PollHistoryEvents.LoadMore -> {
+ is PollHistoryEvent.LoadMore -> {
coroutineScope.loadMore(timeline)
}
- is PollHistoryEvents.SelectPollAnswer -> sessionCoroutineScope.launch {
+ is PollHistoryEvent.SelectPollAnswer -> sessionCoroutineScope.launch {
sendPollResponseAction.execute(
timeline = timeline,
pollStartId = event.pollStartId,
answerId = event.answerId
)
}
- is PollHistoryEvents.EndPoll -> sessionCoroutineScope.launch {
+ is PollHistoryEvent.EndPoll -> sessionCoroutineScope.launch {
endPollAction.execute(timeline = timeline, pollStartId = event.pollStartId)
}
- is PollHistoryEvents.SelectFilter -> {
+ is PollHistoryEvent.SelectFilter -> {
activeFilter = event.filter
}
}
diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryState.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryState.kt
index bddfd153f6..67225e85c2 100644
--- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryState.kt
+++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryState.kt
@@ -18,7 +18,7 @@ data class PollHistoryState(
val hasMoreToLoad: Boolean,
val activeFilter: PollHistoryFilter,
val pollHistoryItems: PollHistoryItems,
- val eventSink: (PollHistoryEvents) -> Unit,
+ val eventSink: (PollHistoryEvent) -> Unit,
) {
fun pollHistoryForFilter(filter: PollHistoryFilter): ImmutableList {
return when (filter) {
diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryStatePreviewParam.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryStatePreviewParam.kt
index ff07eaee37..40144f261e 100644
--- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryStatePreviewParam.kt
+++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryStatePreviewParam.kt
@@ -48,7 +48,7 @@ internal fun aPollHistoryState(
currentItems: List = listOf(
aPollHistoryItem(),
),
- eventSink: (PollHistoryEvents) -> Unit = {},
+ eventSink: (PollHistoryEvent) -> Unit = {},
) = PollHistoryState(
isLoading = isLoading,
hasMoreToLoad = hasMoreToLoad,
diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt
index 01b475593d..61c7809f49 100644
--- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt
+++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt
@@ -62,15 +62,15 @@ fun PollHistoryView(
modifier: Modifier = Modifier,
) {
fun onLoadMore() {
- state.eventSink(PollHistoryEvents.LoadMore)
+ state.eventSink(PollHistoryEvent.LoadMore)
}
fun onSelectAnswer(pollStartId: EventId, answerId: String) {
- state.eventSink(PollHistoryEvents.SelectPollAnswer(pollStartId, answerId))
+ state.eventSink(PollHistoryEvent.SelectPollAnswer(pollStartId, answerId))
}
fun onEndPoll(pollStartId: EventId) {
- state.eventSink(PollHistoryEvents.EndPoll(pollStartId))
+ state.eventSink(PollHistoryEvent.EndPoll(pollStartId))
}
Scaffold(
@@ -97,7 +97,7 @@ fun PollHistoryView(
}
PollHistoryFilterButtons(
activeFilter = state.activeFilter,
- onSelectFilter = { state.eventSink(PollHistoryEvents.SelectFilter(it)) },
+ onSelectFilter = { state.eventSink(PollHistoryEvent.SelectFilter(it)) },
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
diff --git a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenterTest.kt b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenterTest.kt
index 8d4cedc6a8..1342f89c60 100644
--- a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenterTest.kt
+++ b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryPresenterTest.kt
@@ -88,12 +88,12 @@ class PollHistoryPresenterTest {
}.test {
awaitItem().also { state ->
assertThat(state.activeFilter).isEqualTo(PollHistoryFilter.ONGOING)
- state.eventSink(PollHistoryEvents.SelectFilter(PollHistoryFilter.PAST))
+ state.eventSink(PollHistoryEvent.SelectFilter(PollHistoryFilter.PAST))
}
skipItems(1)
awaitItem().also { state ->
assertThat(state.activeFilter).isEqualTo(PollHistoryFilter.PAST)
- state.eventSink(PollHistoryEvents.SelectFilter(PollHistoryFilter.ONGOING))
+ state.eventSink(PollHistoryEvent.SelectFilter(PollHistoryFilter.ONGOING))
}
awaitItem().also { state ->
assertThat(state.activeFilter).isEqualTo(PollHistoryFilter.ONGOING)
@@ -114,10 +114,10 @@ class PollHistoryPresenterTest {
presenter.present()
}.test {
val state = awaitItem()
- state.eventSink(PollHistoryEvents.EndPoll(AN_EVENT_ID))
+ state.eventSink(PollHistoryEvent.EndPoll(AN_EVENT_ID))
runCurrent()
endPollAction.verifyExecutionCount(1)
- state.eventSink(PollHistoryEvents.SelectPollAnswer(AN_EVENT_ID, "answer"))
+ state.eventSink(PollHistoryEvent.SelectPollAnswer(AN_EVENT_ID, "answer"))
runCurrent()
sendPollResponseAction.verifyExecutionCount(1)
cancelAndConsumeRemainingEvents()
@@ -139,7 +139,7 @@ class PollHistoryPresenterTest {
skipItems(1)
val loadedState = awaitItem()
assertThat(loadedState.isLoading).isFalse()
- loadedState.eventSink(PollHistoryEvents.LoadMore)
+ loadedState.eventSink(PollHistoryEvent.LoadMore)
backwardPaginationStatus.getAndUpdate { it.copy(isPaginating = true) }
awaitItem().also { state ->
assertThat(state.isLoading).isTrue()
diff --git a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryViewTest.kt b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryViewTest.kt
index ee6ad69ba6..1b74118734 100644
--- a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryViewTest.kt
+++ b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryViewTest.kt
@@ -35,7 +35,7 @@ import org.robolectric.annotation.Config
class PollHistoryViewTest : RobolectricTest() {
@Test
fun `clicking on back invokes the expected callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
ensureCalledOnce {
setPollHistoryViewView(
aPollHistoryState(
@@ -50,7 +50,7 @@ class PollHistoryViewTest : RobolectricTest() {
@Config(qualifiers = "h1024dp")
@Test
fun `clicking on edit poll invokes the expected callback`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder(expectEvents = false)
+ val eventsRecorder = EventsRecorder(expectEvents = false)
val eventId = EventId("\$anEventId")
val state = aPollHistoryState(
currentItems = listOf(
@@ -76,7 +76,7 @@ class PollHistoryViewTest : RobolectricTest() {
@Config(qualifiers = "h1024dp")
@Test
fun `clicking on poll end emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val eventId = EventId("\$anEventId")
val state = aPollHistoryState(
currentItems = listOf(
@@ -102,14 +102,14 @@ class PollHistoryViewTest : RobolectricTest() {
eventsRecorder.assertEmpty()
clickOn(CommonStrings.action_ok)
eventsRecorder.assertSingle(
- PollHistoryEvents.EndPoll(eventId)
+ PollHistoryEvent.EndPoll(eventId)
)
}
@Config(qualifiers = "h1024dp")
@Test
fun `clicking on poll answer emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder()
+ val eventsRecorder = EventsRecorder()
val eventId = EventId("\$anEventId")
val state = aPollHistoryState(
currentItems = listOf(
@@ -133,13 +133,13 @@ class PollHistoryViewTest : RobolectricTest() {
useUnmergedTree = true,
).performClick()
eventsRecorder.assertSingle(
- PollHistoryEvents.SelectPollAnswer(eventId, answer.id)
+ PollHistoryEvent.SelectPollAnswer(eventId, answer.id)
)
}
@Test
fun `clicking on past tab emits the expected Event`() = runAndroidComposeUiTest {
- val eventsRecorder = EventsRecorder