Skip to content

Commit

Permalink
Merge branch 'release/0.6.1' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
bmarty committed Sep 17, 2024
2 parents e80cfe4 + 8a655de commit da57b04
Show file tree
Hide file tree
Showing 307 changed files with 4,445 additions and 1,190 deletions.
19 changes: 19 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
Changes in Element X v0.6.0 (2024-09-12)
========================================

### 🙌 Improvements
* Enables pinned messages feature by default. by @ganfra in https://github.com/element-hq/element-x-android/pull/3439
* Pinned messages list : hide reactions by @ganfra in https://github.com/element-hq/element-x-android/pull/3430

### 🐛 Bugfixes
* Feature/fga/pinned messages fix timeline provider by @ganfra in https://github.com/element-hq/element-x-android/pull/3432

### Dependency upgrades
* Update activity to v1.9.2 by @renovate in https://github.com/element-hq/element-x-android/pull/3397
* Update peter-evans/create-pull-request action to v7 by @renovate in https://github.com/element-hq/element-x-android/pull/3383
* Rust sdk upgrade to 0.2.43 by @bmarty in https://github.com/element-hq/element-x-android/pull/3446

### Others
* DeviceId and cleanup. by @bmarty in https://github.com/element-hq/element-x-android/pull/3442
* Update application store assets by @bmarty in https://github.com/element-hq/element-x-android/pull/3441

Changes in Element X v0.5.3 (2024-09-10)
========================================

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ object OnBoardingConfig {
const val CAN_LOGIN_WITH_QR_CODE = true

/** Whether the user can create an account using the app. */
const val CAN_CREATE_ACCOUNT = false
const val CAN_CREATE_ACCOUNT = true
}
1 change: 1 addition & 0 deletions appnav/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ dependencies {
testImplementation(libs.test.turbine)
testImplementation(projects.libraries.matrix.test)
testImplementation(projects.libraries.oidc.impl)
testImplementation(projects.libraries.preferences.test)
testImplementation(projects.libraries.push.test)
testImplementation(projects.libraries.pushproviders.test)
testImplementation(projects.features.networkmonitor.test)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ package io.element.android.appnav.loggedin

sealed interface LoggedInEvents {
data class CloseErrorDialog(val doNotShowAgain: Boolean) : LoggedInEvents
data object CheckSlidingSyncProxyAvailability : LoggedInEvents
data object LogoutAndMigrateToNativeSlidingSync : LoggedInEvents
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import im.vector.app.features.analytics.plan.CryptoSessionStateChange
import im.vector.app.features.analytics.plan.UserProperties
import io.element.android.features.networkmonitor.api.NetworkMonitor
Expand All @@ -29,6 +30,7 @@ import io.element.android.libraries.matrix.api.encryption.RecoveryState
import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
import io.element.android.libraries.preferences.api.store.EnableNativeSlidingSyncUseCase
import io.element.android.libraries.push.api.PushService
import io.element.android.libraries.pushproviders.api.RegistrationFailure
import io.element.android.services.analytics.api.AnalyticsService
Expand All @@ -48,6 +50,7 @@ class LoggedInPresenter @Inject constructor(
private val sessionVerificationService: SessionVerificationService,
private val analyticsService: AnalyticsService,
private val encryptionService: EncryptionService,
private val enableNativeSlidingSyncUseCase: EnableNativeSlidingSyncUseCase,
) : Presenter<LoggedInState> {
@Composable
override fun present(): LoggedInState {
Expand Down Expand Up @@ -78,6 +81,7 @@ class LoggedInPresenter @Inject constructor(
networkStatus == NetworkStatus.Online && syncIndicator == RoomListService.SyncIndicator.Show
}
}
var forceNativeSlidingSyncMigration by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
combine(
sessionVerificationService.sessionVerifiedStatus,
Expand All @@ -97,13 +101,26 @@ class LoggedInPresenter @Inject constructor(
}
}
}
LoggedInEvents.CheckSlidingSyncProxyAvailability -> coroutineScope.launch {
// Force the user to log out if they were using the proxy sliding sync and it's no longer available, but native sliding sync is.
forceNativeSlidingSyncMigration = !matrixClient.isUsingNativeSlidingSync() &&
matrixClient.isNativeSlidingSyncSupported() &&
!matrixClient.isSlidingSyncProxySupported()
}
LoggedInEvents.LogoutAndMigrateToNativeSlidingSync -> coroutineScope.launch {
// Enable native sliding sync if it wasn't already the case
enableNativeSlidingSyncUseCase()
// Then force the logout
matrixClient.logout(userInitiated = true, ignoreSdkError = true)
}
}
}

return LoggedInState(
showSyncSpinner = showSyncSpinner,
pusherRegistrationState = pusherRegistrationState.value,
ignoreRegistrationError = ignoreRegistrationError,
forceNativeSlidingSyncMigration = forceNativeSlidingSyncMigration,
eventSink = ::handleEvent
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ data class LoggedInState(
val showSyncSpinner: Boolean,
val pusherRegistrationState: AsyncData<Unit>,
val ignoreRegistrationError: Boolean,
val forceNativeSlidingSyncMigration: Boolean,
val eventSink: (LoggedInEvents) -> Unit,
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@ open class LoggedInStateProvider : PreviewParameterProvider<LoggedInState> {
aLoggedInState(),
aLoggedInState(showSyncSpinner = true),
aLoggedInState(pusherRegistrationState = AsyncData.Failure(PusherRegistrationFailure.NoDistributorsAvailable())),
aLoggedInState(forceNativeSlidingSyncMigration = true),
)
}

fun aLoggedInState(
showSyncSpinner: Boolean = false,
pusherRegistrationState: AsyncData<Unit> = AsyncData.Uninitialized,
forceNativeSlidingSyncMigration: Boolean = false,
) = LoggedInState(
showSyncSpinner = showSyncSpinner,
pusherRegistrationState = pusherRegistrationState,
ignoreRegistrationError = false,
forceNativeSlidingSyncMigration = forceNativeSlidingSyncMigration,
eventSink = {},
)
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.lifecycle.Lifecycle
import io.element.android.appnav.R
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialogWithDoNotShowAgain
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.utils.OnLifecycleEvent
import io.element.android.libraries.matrix.api.exception.isNetworkError
import io.element.android.libraries.ui.strings.CommonStrings

Expand All @@ -28,6 +32,11 @@ fun LoggedInView(
navigateToNotificationTroubleshoot: () -> Unit,
modifier: Modifier = Modifier
) {
OnLifecycleEvent { _, event ->
if (event == Lifecycle.Event.ON_RESUME) {
state.eventSink(LoggedInEvents.CheckSlidingSyncProxyAvailability)
}
}
Box(
modifier = modifier
.fillMaxSize()
Expand Down Expand Up @@ -61,6 +70,13 @@ fun LoggedInView(
}
}
}

// Set the force migration dialog here so it's always displayed over every screen
if (state.forceNativeSlidingSyncMigration) {
ForceNativeSlidingSyncMigrationDialog(onSubmit = {
state.eventSink(LoggedInEvents.LogoutAndMigrateToNativeSlidingSync)
})
}
}

private fun Throwable.getReason(): String? {
Expand All @@ -80,6 +96,19 @@ private fun Throwable.getReason(): String? {
}
}

@Composable
private fun ForceNativeSlidingSyncMigrationDialog(
onSubmit: () -> Unit,
) {
ErrorDialog(
title = null,
content = stringResource(R.string.banner_migrate_to_native_sliding_sync_force_logout_title),
submitText = stringResource(R.string.banner_migrate_to_native_sliding_sync_action),
onSubmit = onSubmit,
canDismiss = false,
)
}

@PreviewsDayNight
@Composable
internal fun LoggedInViewPreview(@PreviewParameter(LoggedInStateProvider::class) state: LoggedInState) = ElementPreview {
Expand Down
5 changes: 5 additions & 0 deletions appnav/src/main/res/values-cs/translations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Odhlásit se a upgradovat"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Váš domovský server již nepodporuje starý protokol. Chcete-li pokračovat v používání aplikace, odhlaste se a znovu se přihlaste."</string>
</resources>
5 changes: 5 additions & 0 deletions appnav/src/main/res/values-de/translations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Abmelden und aktualisieren"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Dein Homeserver unterstützt das alte Protokoll nicht mehr. Bitte logge dich aus und melde dich wieder an, um die App weiter zu nutzen."</string>
</resources>
5 changes: 5 additions & 0 deletions appnav/src/main/res/values-el/translations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Αποσύνδεση &amp;amp; Αναβάθμιση"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Ο οικιακός διακομιστής σου δεν υποστηρίζει πλέον το παλιό πρωτόκολλο. Αποσυνδέσου και συνδέσου ξανά για να συνεχίσεις να χρησιμοποιείς την εφαρμογή."</string>
</resources>
5 changes: 5 additions & 0 deletions appnav/src/main/res/values-et/translations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Logi välja ja uuenda"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Sinu koduserver enam ei toeta vana protokolli. Jätkamaks rakenduse kasutamist palun logi välja ning seejärel tagasi."</string>
</resources>
5 changes: 5 additions & 0 deletions appnav/src/main/res/values-fr/translations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Déconnecter et mettre à niveau"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Votre serveur d’accueil ne prend plus en charge l’ancien protocole. Veuillez vous déconnecter puis vous reconnecter pour continuer à utiliser l’application."</string>
</resources>
5 changes: 5 additions & 0 deletions appnav/src/main/res/values-hu/translations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Kijelentkezés és frissítés"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"A Matrix-kiszolgáló már nem támogatja a régi protokollt. Az alkalmazás további használatához jelentkezzen ki és be."</string>
</resources>
5 changes: 5 additions & 0 deletions appnav/src/main/res/values-ru/translations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Выйти и обновить"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Ваш homeserver больше не поддерживает старый протокол. Пожалуйста, выйдите из системы и войдите снова, чтобы продолжить использование приложения."</string>
</resources>
5 changes: 5 additions & 0 deletions appnav/src/main/res/values-sk/translations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Odhlásiť sa a aktualizovať"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Váš domovský server už nepodporuje starý protokol. Ak chcete pokračovať v používaní aplikácie, odhláste sa a znova sa prihláste."</string>
</resources>
5 changes: 5 additions & 0 deletions appnav/src/main/res/values/localazy.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Log Out &amp; Upgrade"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Your homeserver no longer supports the old protocol. Please log out and log back in to continue using the app."</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
import io.element.android.libraries.preferences.api.store.EnableNativeSlidingSyncUseCase
import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore
import io.element.android.libraries.push.api.PushService
import io.element.android.libraries.push.test.FakePushService
import io.element.android.libraries.pushproviders.api.Distributor
Expand All @@ -42,6 +44,10 @@ import io.element.android.tests.testutils.lambda.any
import io.element.android.tests.testutils.lambda.lambdaError
import io.element.android.tests.testutils.lambda.lambdaRecorder
import io.element.android.tests.testutils.lambda.value
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
Expand Down Expand Up @@ -91,7 +97,8 @@ class LoggedInPresenterTest {
pushService = FakePushService(),
sessionVerificationService = verificationService,
analyticsService = analyticsService,
encryptionService = encryptionService
encryptionService = encryptionService,
enableNativeSlidingSyncUseCase = EnableNativeSlidingSyncUseCase(InMemoryAppPreferencesStore(), this),
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
Expand Down Expand Up @@ -487,26 +494,103 @@ class LoggedInPresenterTest {
)
}

@Test
fun `present - CheckSlidingSyncProxyAvailability forces the sliding sync migration under the right circumstances`() = runTest {
// The migration will be forced if:
// - The user is not using the native sliding sync
// - The sliding sync proxy is no longer supported
// - The native sliding sync is supported
val matrixClient = FakeMatrixClient(
isUsingNativeSlidingSyncLambda = { false },
isSlidingSyncProxySupportedLambda = { false },
isNativeSlidingSyncSupportedLambda = { true },
)
val presenter = createLoggedInPresenter(matrixClient = matrixClient)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.forceNativeSlidingSyncMigration).isFalse()

initialState.eventSink(LoggedInEvents.CheckSlidingSyncProxyAvailability)

assertThat(awaitItem().forceNativeSlidingSyncMigration).isTrue()
}
}

@Test
fun `present - CheckSlidingSyncProxyAvailability will not force the migration if native sliding sync is not supported too`() = runTest {
val matrixClient = FakeMatrixClient(
isUsingNativeSlidingSyncLambda = { false },
isSlidingSyncProxySupportedLambda = { false },
isNativeSlidingSyncSupportedLambda = { false },
)
val presenter = createLoggedInPresenter(matrixClient = matrixClient)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.forceNativeSlidingSyncMigration).isFalse()

initialState.eventSink(LoggedInEvents.CheckSlidingSyncProxyAvailability)

expectNoEvents()
}
}

@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun `present - LogoutAndMigrateToNativeSlidingSync enables native sliding sync and logs out the user`() = runTest {
val logoutLambda = lambdaRecorder<Boolean, Boolean, String?> { userInitiated, ignoreSdkError ->
assertThat(userInitiated).isTrue()
assertThat(ignoreSdkError).isTrue()
null
}
val matrixClient = FakeMatrixClient().apply {
this.logoutLambda = logoutLambda
}
val appPreferencesStore = InMemoryAppPreferencesStore()
val enableNativeSlidingSyncUseCase = EnableNativeSlidingSyncUseCase(appPreferencesStore, this)
val presenter = createLoggedInPresenter(matrixClient = matrixClient, enableNativeSlidingSyncUseCase = enableNativeSlidingSyncUseCase)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()

assertThat(appPreferencesStore.isSimplifiedSlidingSyncEnabledFlow().first()).isFalse()

initialState.eventSink(LoggedInEvents.LogoutAndMigrateToNativeSlidingSync)

advanceUntilIdle()

assertThat(appPreferencesStore.isSimplifiedSlidingSyncEnabledFlow().first()).isTrue()
assertThat(logoutLambda.assertions().isCalledOnce())
}
}

private suspend fun <T> ReceiveTurbine<T>.awaitFirstItem(): T {
skipItems(1)
return awaitItem()
}

private fun createLoggedInPresenter(
private fun TestScope.createLoggedInPresenter(
roomListService: RoomListService = FakeRoomListService(),
networkStatus: NetworkStatus = NetworkStatus.Offline,
analyticsService: AnalyticsService = FakeAnalyticsService(),
sessionVerificationService: SessionVerificationService = FakeSessionVerificationService(),
encryptionService: EncryptionService = FakeEncryptionService(),
pushService: PushService = FakePushService(),
enableNativeSlidingSyncUseCase: EnableNativeSlidingSyncUseCase = EnableNativeSlidingSyncUseCase(InMemoryAppPreferencesStore(), this),
matrixClient: MatrixClient = FakeMatrixClient(roomListService = roomListService),
): LoggedInPresenter {
return LoggedInPresenter(
matrixClient = FakeMatrixClient(roomListService = roomListService),
matrixClient = matrixClient,
networkMonitor = FakeNetworkMonitor(networkStatus),
pushService = pushService,
sessionVerificationService = sessionVerificationService,
analyticsService = analyticsService,
encryptionService = encryptionService
encryptionService = encryptionService,
enableNativeSlidingSyncUseCase = enableNativeSlidingSyncUseCase,
)
}
}
2 changes: 2 additions & 0 deletions fastlane/metadata/android/en-US/changelogs/40006010.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Element X is the new generation of Element for professional and personal use on mobile. It’s the fastest Matrix client with a seamless & intuitive user interface.
Full changelog: https://github.com/element-hq/element-x-android/releases
Loading

0 comments on commit da57b04

Please sign in to comment.