Merge branch 'develop' into feature/fga/sending_queue_iteration
This commit is contained in:
commit
b874d3e38c
31 changed files with 161 additions and 86 deletions
|
|
@ -52,6 +52,7 @@ fun FlowStepPage(
|
|||
iconStyle: BigIcon.Style,
|
||||
title: String,
|
||||
modifier: Modifier = Modifier,
|
||||
isScrollable: Boolean = false,
|
||||
onBackClick: (() -> Unit)? = null,
|
||||
subTitle: String? = null,
|
||||
buttons: @Composable ColumnScope.() -> Unit = {},
|
||||
|
|
@ -62,6 +63,7 @@ fun FlowStepPage(
|
|||
}
|
||||
HeaderFooterPage(
|
||||
modifier = modifier,
|
||||
isScrollable = isScrollable,
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
navigationIcon = {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ import androidx.compose.foundation.layout.PaddingValues
|
|||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
|
@ -39,6 +41,7 @@ import io.element.android.libraries.designsystem.theme.components.Text
|
|||
* @param modifier Classical modifier.
|
||||
* @param paddingValues padding values to apply to the content.
|
||||
* @param containerColor color of the container. Set to [Color.Transparent] if you provide a background in the [modifier].
|
||||
* @param isScrollable if the whole content should be scrollable.
|
||||
* @param background optional background component.
|
||||
* @param topBar optional topBar.
|
||||
* @param header optional header.
|
||||
|
|
@ -50,6 +53,7 @@ fun HeaderFooterPage(
|
|||
modifier: Modifier = Modifier,
|
||||
paddingValues: PaddingValues = PaddingValues(20.dp),
|
||||
containerColor: Color = MaterialTheme.colorScheme.background,
|
||||
isScrollable: Boolean = false,
|
||||
background: @Composable () -> Unit = {},
|
||||
topBar: @Composable () -> Unit = {},
|
||||
header: @Composable () -> Unit = {},
|
||||
|
|
@ -63,25 +67,53 @@ fun HeaderFooterPage(
|
|||
) { padding ->
|
||||
Box {
|
||||
background()
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(paddingValues = paddingValues)
|
||||
.padding(padding)
|
||||
.consumeWindowInsets(padding)
|
||||
) {
|
||||
// Header
|
||||
header()
|
||||
// Content
|
||||
if (isScrollable) {
|
||||
// Render in a LazyColumn
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.padding(paddingValues = paddingValues)
|
||||
.padding(padding)
|
||||
.consumeWindowInsets(padding)
|
||||
.imePadding()
|
||||
) {
|
||||
// Header
|
||||
item {
|
||||
header()
|
||||
}
|
||||
// Content
|
||||
item {
|
||||
content()
|
||||
}
|
||||
// Footer
|
||||
item {
|
||||
Box(modifier = Modifier.padding(horizontal = 16.dp)) {
|
||||
footer()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Render in a Column
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth(),
|
||||
.padding(paddingValues = paddingValues)
|
||||
.padding(padding)
|
||||
.consumeWindowInsets(padding)
|
||||
.imePadding()
|
||||
) {
|
||||
content()
|
||||
}
|
||||
// Footer
|
||||
Box(modifier = Modifier.padding(horizontal = 16.dp)) {
|
||||
footer()
|
||||
// Header
|
||||
header()
|
||||
// Content
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
content()
|
||||
}
|
||||
// Footer
|
||||
Box(modifier = Modifier.padding(horizontal = 16.dp)) {
|
||||
footer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package io.element.android.libraries.matrix.api.auth
|
||||
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.MatrixClientProvider
|
||||
import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData
|
||||
import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
|
|
@ -31,6 +32,7 @@ interface MatrixAuthenticationService {
|
|||
/**
|
||||
* Restore a session from a [sessionId].
|
||||
* Do not restore anything it the access token is not valid anymore.
|
||||
* Generally this method should not be used directly, prefer using [MatrixClientProvider.getOrRestore] instead.
|
||||
*/
|
||||
suspend fun restoreSession(sessionId: SessionId): Result<MatrixClient>
|
||||
fun getHomeserverDetails(): StateFlow<MatrixHomeServerDetails?>
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ class RoomSummaryListProcessorTest {
|
|||
|
||||
override suspend fun applyInput(input: RoomListInput) = Unit
|
||||
|
||||
override suspend fun room(roomId: String): RoomListItem {
|
||||
override fun room(roomId: String): RoomListItem {
|
||||
return RoomListItem(Pointer.NULL)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import kotlinx.coroutines.flow.StateFlow
|
|||
|
||||
class FakeRoomListService : RoomListService {
|
||||
private val allRoomSummariesFlow = MutableStateFlow<List<RoomSummary>>(emptyList())
|
||||
private val inviteRoomSummariesFlow = MutableStateFlow<List<RoomSummary>>(emptyList())
|
||||
private val allRoomsLoadingStateFlow = MutableStateFlow<RoomList.LoadingState>(RoomList.LoadingState.NotLoaded)
|
||||
private val roomListStateFlow = MutableStateFlow<RoomListService.State>(RoomListService.State.Idle)
|
||||
private val syncIndicatorStateFlow = MutableStateFlow<RoomListService.SyncIndicator>(RoomListService.SyncIndicator.Hide)
|
||||
|
|
@ -35,10 +34,6 @@ class FakeRoomListService : RoomListService {
|
|||
allRoomSummariesFlow.emit(roomSummaries)
|
||||
}
|
||||
|
||||
suspend fun postInviteRooms(roomSummaries: List<RoomSummary>) {
|
||||
inviteRoomSummariesFlow.emit(roomSummaries)
|
||||
}
|
||||
|
||||
suspend fun postAllRoomsLoadingState(loadingState: RoomList.LoadingState) {
|
||||
allRoomsLoadingStateFlow.emit(loadingState)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import com.squareup.anvil.annotations.ContributesBinding
|
|||
import io.element.android.libraries.core.extensions.flatMap
|
||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.api.MatrixClientProvider
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.pushproviders.api.PusherSubscriber
|
||||
import io.element.android.libraries.pushstore.api.UserPushStoreFactory
|
||||
|
|
@ -43,7 +43,7 @@ class DefaultFirebaseNewTokenHandler @Inject constructor(
|
|||
private val pusherSubscriber: PusherSubscriber,
|
||||
private val sessionStore: SessionStore,
|
||||
private val userPushStoreFactory: UserPushStoreFactory,
|
||||
private val matrixAuthenticationService: MatrixAuthenticationService,
|
||||
private val matrixClientProvider: MatrixClientProvider,
|
||||
private val firebaseStore: FirebaseStore,
|
||||
) : FirebaseNewTokenHandler {
|
||||
override suspend fun handle(firebaseToken: String) {
|
||||
|
|
@ -54,8 +54,8 @@ class DefaultFirebaseNewTokenHandler @Inject constructor(
|
|||
.forEach { sessionId ->
|
||||
val userDataStore = userPushStoreFactory.getOrCreate(sessionId)
|
||||
if (userDataStore.getPushProviderName() == FirebaseConfig.NAME) {
|
||||
matrixAuthenticationService
|
||||
.restoreSession(sessionId)
|
||||
matrixClientProvider
|
||||
.getOrRestore(sessionId)
|
||||
.onFailure {
|
||||
Timber.tag(loggerTag.value).e(it, "Failed to restore session $sessionId")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ package io.element.android.libraries.pushproviders.firebase
|
|||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.api.MatrixClientProvider
|
||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||
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.A_USER_ID_3
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClientProvider
|
||||
import io.element.android.libraries.push.test.FakePusherSubscriber
|
||||
import io.element.android.libraries.pushproviders.api.PusherSubscriber
|
||||
import io.element.android.libraries.pushstore.api.UserPushStoreFactory
|
||||
|
|
@ -64,16 +64,14 @@ class DefaultFirebaseNewTokenHandlerTest {
|
|||
storeData(aSessionData(A_USER_ID_2))
|
||||
storeData(aSessionData(A_USER_ID_3))
|
||||
},
|
||||
matrixAuthenticationService = FakeMatrixAuthenticationService(
|
||||
matrixClientResult = { sessionId ->
|
||||
when (sessionId) {
|
||||
A_USER_ID -> Result.success(aMatrixClient1)
|
||||
A_USER_ID_2 -> Result.success(aMatrixClient2)
|
||||
A_USER_ID_3 -> Result.success(aMatrixClient3)
|
||||
else -> Result.failure(IllegalStateException())
|
||||
}
|
||||
matrixClientProvider = FakeMatrixClientProvider { sessionId ->
|
||||
when (sessionId) {
|
||||
A_USER_ID -> Result.success(aMatrixClient1)
|
||||
A_USER_ID_2 -> Result.success(aMatrixClient2)
|
||||
A_USER_ID_3 -> Result.success(aMatrixClient3)
|
||||
else -> Result.failure(IllegalStateException())
|
||||
}
|
||||
),
|
||||
},
|
||||
userPushStoreFactory = FakeUserPushStoreFactory(
|
||||
userPushStore = { sessionId ->
|
||||
when (sessionId) {
|
||||
|
|
@ -103,11 +101,9 @@ class DefaultFirebaseNewTokenHandlerTest {
|
|||
sessionStore = InMemoryMultiSessionsStore().apply {
|
||||
storeData(aSessionData(A_USER_ID))
|
||||
},
|
||||
matrixAuthenticationService = FakeMatrixAuthenticationService(
|
||||
matrixClientResult = { _ ->
|
||||
Result.failure(IllegalStateException())
|
||||
}
|
||||
),
|
||||
matrixClientProvider = FakeMatrixClientProvider {
|
||||
Result.failure(IllegalStateException())
|
||||
},
|
||||
userPushStoreFactory = FakeUserPushStoreFactory(
|
||||
userPushStore = { _ ->
|
||||
FakeUserPushStore(pushProviderName = FirebaseConfig.NAME)
|
||||
|
|
@ -129,11 +125,9 @@ class DefaultFirebaseNewTokenHandlerTest {
|
|||
sessionStore = InMemoryMultiSessionsStore().apply {
|
||||
storeData(aSessionData(A_USER_ID))
|
||||
},
|
||||
matrixAuthenticationService = FakeMatrixAuthenticationService(
|
||||
matrixClientResult = { _ ->
|
||||
Result.success(aMatrixClient1)
|
||||
}
|
||||
),
|
||||
matrixClientProvider = FakeMatrixClientProvider {
|
||||
Result.success(aMatrixClient1)
|
||||
},
|
||||
userPushStoreFactory = FakeUserPushStoreFactory(
|
||||
userPushStore = { _ ->
|
||||
FakeUserPushStore(pushProviderName = FirebaseConfig.NAME)
|
||||
|
|
@ -152,14 +146,14 @@ class DefaultFirebaseNewTokenHandlerTest {
|
|||
pusherSubscriber: PusherSubscriber = FakePusherSubscriber(),
|
||||
sessionStore: SessionStore = InMemorySessionStore(),
|
||||
userPushStoreFactory: UserPushStoreFactory = FakeUserPushStoreFactory(),
|
||||
matrixAuthenticationService: MatrixAuthenticationService = FakeMatrixAuthenticationService(),
|
||||
matrixClientProvider: MatrixClientProvider = FakeMatrixClientProvider(),
|
||||
firebaseStore: FirebaseStore = InMemoryFirebaseStore(),
|
||||
): FirebaseNewTokenHandler {
|
||||
return DefaultFirebaseNewTokenHandler(
|
||||
pusherSubscriber = pusherSubscriber,
|
||||
sessionStore = sessionStore,
|
||||
userPushStoreFactory = userPushStoreFactory,
|
||||
matrixAuthenticationService = matrixAuthenticationService,
|
||||
matrixClientProvider = matrixClientProvider,
|
||||
firebaseStore = firebaseStore
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import com.squareup.anvil.annotations.ContributesBinding
|
|||
import io.element.android.libraries.core.extensions.flatMap
|
||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.api.MatrixClientProvider
|
||||
import io.element.android.libraries.pushproviders.api.PusherSubscriber
|
||||
import io.element.android.libraries.pushstore.api.UserPushStoreFactory
|
||||
import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret
|
||||
|
|
@ -41,7 +41,7 @@ class DefaultUnifiedPushNewGatewayHandler @Inject constructor(
|
|||
private val pusherSubscriber: PusherSubscriber,
|
||||
private val userPushStoreFactory: UserPushStoreFactory,
|
||||
private val pushClientSecret: PushClientSecret,
|
||||
private val matrixAuthenticationService: MatrixAuthenticationService,
|
||||
private val matrixClientProvider: MatrixClientProvider,
|
||||
) : UnifiedPushNewGatewayHandler {
|
||||
override suspend fun handle(endpoint: String, pushGateway: String, clientSecret: String): Result<Unit> {
|
||||
// Register the pusher for the session with this client secret, if is it using UnifiedPush.
|
||||
|
|
@ -52,8 +52,8 @@ class DefaultUnifiedPushNewGatewayHandler @Inject constructor(
|
|||
}
|
||||
val userDataStore = userPushStoreFactory.getOrCreate(userId)
|
||||
return if (userDataStore.getPushProviderName() == UnifiedPushConfig.NAME) {
|
||||
matrixAuthenticationService
|
||||
.restoreSession(userId)
|
||||
matrixClientProvider
|
||||
.getOrRestore(userId)
|
||||
.flatMap { client ->
|
||||
pusherSubscriber.registerPusher(client, endpoint, pushGateway)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ package io.element.android.libraries.pushproviders.unifiedpush
|
|||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.api.MatrixClientProvider
|
||||
import io.element.android.libraries.matrix.test.A_SECRET
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClientProvider
|
||||
import io.element.android.libraries.push.test.FakePusherSubscriber
|
||||
import io.element.android.libraries.pushproviders.api.PusherSubscriber
|
||||
import io.element.android.libraries.pushstore.api.UserPushStoreFactory
|
||||
|
|
@ -86,7 +86,7 @@ class DefaultUnifiedPushNewGatewayHandlerTest {
|
|||
pusherSubscriber = FakePusherSubscriber(
|
||||
registerPusherResult = { _, _, _ -> Result.failure(IllegalStateException("an error")) }
|
||||
),
|
||||
matrixAuthenticationService = FakeMatrixAuthenticationService(matrixClientResult = { Result.success(aMatrixClient) }),
|
||||
matrixClientProvider = FakeMatrixClientProvider { Result.success(aMatrixClient) },
|
||||
)
|
||||
val result = defaultUnifiedPushNewGatewayHandler.handle(
|
||||
endpoint = "aEndpoint",
|
||||
|
|
@ -114,7 +114,7 @@ class DefaultUnifiedPushNewGatewayHandlerTest {
|
|||
pusherSubscriber = FakePusherSubscriber(
|
||||
registerPusherResult = lambda
|
||||
),
|
||||
matrixAuthenticationService = FakeMatrixAuthenticationService(matrixClientResult = { Result.success(aMatrixClient) }),
|
||||
matrixClientProvider = FakeMatrixClientProvider { Result.success(aMatrixClient) },
|
||||
)
|
||||
val result = defaultUnifiedPushNewGatewayHandler.handle(
|
||||
endpoint = "aEndpoint",
|
||||
|
|
@ -131,13 +131,13 @@ class DefaultUnifiedPushNewGatewayHandlerTest {
|
|||
pusherSubscriber: PusherSubscriber = FakePusherSubscriber(),
|
||||
userPushStoreFactory: UserPushStoreFactory = FakeUserPushStoreFactory(),
|
||||
pushClientSecret: PushClientSecret = FakePushClientSecret(),
|
||||
matrixAuthenticationService: MatrixAuthenticationService = FakeMatrixAuthenticationService()
|
||||
matrixClientProvider: MatrixClientProvider = FakeMatrixClientProvider()
|
||||
): DefaultUnifiedPushNewGatewayHandler {
|
||||
return DefaultUnifiedPushNewGatewayHandler(
|
||||
pusherSubscriber = pusherSubscriber,
|
||||
userPushStoreFactory = userPushStoreFactory,
|
||||
pushClientSecret = pushClientSecret,
|
||||
matrixAuthenticationService = matrixAuthenticationService
|
||||
matrixClientProvider = matrixClientProvider,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,6 @@ class StableCharSequence(initialText: CharSequence = "") {
|
|||
fun needsDisplaying(): Boolean = needsDisplaying
|
||||
|
||||
override fun toString(): String {
|
||||
return "ImmutableCharSequence(value='$value', needsDisplaying=$needsDisplaying)"
|
||||
return "StableCharSequence(value='$value', needsDisplaying=$needsDisplaying)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ class MarkdownTextInputTest {
|
|||
onTyping: (Boolean) -> Unit = {},
|
||||
onSuggestionReceived: (Suggestion?) -> Unit = {},
|
||||
) {
|
||||
rule.setContent {
|
||||
setContent {
|
||||
val style = ElementRichTextEditorStyle.composerStyle(hasFocus = state.hasFocus)
|
||||
MarkdownTextInput(
|
||||
state = state,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue