Remember flows (#4533)
* Add Konsist test to ensure that the result of a function returning a flow is remembered. * Remember flows before they are collected by state. * Fix compilation issue * Make isOnline a val. * Make selectedUsers() a val. * Make flow() a val. * Make getUserConsent(), didAskUserConsent() and getAnalyticsId() some val. * Remove Timeline.paginationStatus() and replace by direct access to the underlined flow. * Simplify test * userConsentFlow must be initialized before because it's used in observeUserConsent * Fix test compilation
This commit is contained in:
parent
e557ee2c77
commit
a230b83e99
52 changed files with 221 additions and 172 deletions
|
|
@ -27,8 +27,7 @@ class AnalyticsPreferencesPresenter @Inject constructor(
|
|||
@Composable
|
||||
override fun present(): AnalyticsPreferencesState {
|
||||
val localCoroutineScope = rememberCoroutineScope()
|
||||
val isEnabled = analyticsService.getUserConsent()
|
||||
.collectAsState(initial = false)
|
||||
val isEnabled = analyticsService.userConsentFlow.collectAsState(initial = false)
|
||||
|
||||
fun handleEvents(event: AnalyticsOptInEvents) {
|
||||
when (event) {
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ class AnalyticsOptInPresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(analyticsService.didAskUserConsent().first()).isFalse()
|
||||
assertThat(analyticsService.didAskUserConsentFlow.first()).isFalse()
|
||||
initialState.eventSink.invoke(AnalyticsOptInEvents.EnableAnalytics(true))
|
||||
assertThat(analyticsService.didAskUserConsent().first()).isTrue()
|
||||
assertThat(analyticsService.getUserConsent().first()).isTrue()
|
||||
assertThat(analyticsService.didAskUserConsentFlow.first()).isTrue()
|
||||
assertThat(analyticsService.userConsentFlow.first()).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,10 +53,10 @@ class AnalyticsOptInPresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(analyticsService.didAskUserConsent().first()).isFalse()
|
||||
assertThat(analyticsService.didAskUserConsentFlow.first()).isFalse()
|
||||
initialState.eventSink.invoke(AnalyticsOptInEvents.EnableAnalytics(false))
|
||||
assertThat(analyticsService.didAskUserConsent().first()).isTrue()
|
||||
assertThat(analyticsService.getUserConsent().first()).isFalse()
|
||||
assertThat(analyticsService.didAskUserConsentFlow.first()).isTrue()
|
||||
assertThat(analyticsService.userConsentFlow.first()).isFalse()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class CreateRoomDataStore @Inject constructor(
|
|||
}
|
||||
|
||||
val createRoomConfigWithInvites: Flow<CreateRoomConfig> = combine(
|
||||
selectedUserListDataStore.selectedUsers(),
|
||||
selectedUserListDataStore.selectedUsers,
|
||||
createRoomConfigFlow,
|
||||
) { selectedUsers, config ->
|
||||
config.copy(invites = selectedUsers.toImmutableList())
|
||||
|
|
|
|||
|
|
@ -66,7 +66,9 @@ class ConfigureRoomPresenter @Inject constructor(
|
|||
val cameraPermissionState = cameraPermissionPresenter.present()
|
||||
val createRoomConfig by dataStore.createRoomConfigWithInvites.collectAsState(CreateRoomConfig())
|
||||
val homeserverName = remember { matrixClient.userIdServerName() }
|
||||
val isKnockFeatureEnabled by featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock).collectAsState(initial = false)
|
||||
val isKnockFeatureEnabled by remember {
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock)
|
||||
}.collectAsState(initial = false)
|
||||
val roomAddressValidity = remember {
|
||||
mutableStateOf<RoomAddressValidity>(RoomAddressValidity.Unknown)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,9 @@ class CreateRoomRootPresenter @Inject constructor(
|
|||
val localCoroutineScope = rememberCoroutineScope()
|
||||
val startDmActionState: MutableState<AsyncAction<RoomId>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
|
||||
|
||||
val isRoomDirectorySearchEnabled by featureFlagService.isFeatureEnabledFlow(FeatureFlags.RoomDirectorySearch).collectAsState(initial = false)
|
||||
val isRoomDirectorySearchEnabled by remember {
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.RoomDirectorySearch)
|
||||
}.collectAsState(initial = false)
|
||||
|
||||
fun handleEvents(event: CreateRoomRootEvents) {
|
||||
when (event) {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class DefaultUserListPresenter @AssistedInject constructor(
|
|||
recentDirectRooms = matrixClient.getRecentDirectRooms()
|
||||
}
|
||||
var isSearchActive by rememberSaveable { mutableStateOf(false) }
|
||||
val selectedUsers by userListDataStore.selectedUsers().collectAsState(emptyList())
|
||||
val selectedUsers by userListDataStore.selectedUsers.collectAsState(emptyList())
|
||||
var searchQuery by rememberSaveable { mutableStateOf("") }
|
||||
var searchResults: SearchBarResultState<ImmutableList<UserSearchResult>> by remember {
|
||||
mutableStateOf(SearchBarResultState.Initial())
|
||||
|
|
|
|||
|
|
@ -8,22 +8,22 @@
|
|||
package io.element.android.features.createroom.impl.userlist
|
||||
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import javax.inject.Inject
|
||||
|
||||
class UserListDataStore @Inject constructor() {
|
||||
private val selectedUsers: MutableStateFlow<List<MatrixUser>> = MutableStateFlow(emptyList())
|
||||
private val _selectedUsers: MutableStateFlow<List<MatrixUser>> = MutableStateFlow(emptyList())
|
||||
|
||||
fun selectUser(user: MatrixUser) {
|
||||
if (!selectedUsers.value.contains(user)) {
|
||||
selectedUsers.tryEmit(selectedUsers.value.plus(user))
|
||||
if (!_selectedUsers.value.contains(user)) {
|
||||
_selectedUsers.tryEmit(_selectedUsers.value.plus(user))
|
||||
}
|
||||
}
|
||||
|
||||
fun removeUserFromSelection(user: MatrixUser) {
|
||||
selectedUsers.tryEmit(selectedUsers.value.minus(user))
|
||||
_selectedUsers.tryEmit(_selectedUsers.value.minus(user))
|
||||
}
|
||||
|
||||
fun selectedUsers(): Flow<List<MatrixUser>> = selectedUsers
|
||||
val selectedUsers = _selectedUsers.asStateFlow()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class FtueFlowNode @AssistedInject constructor(
|
|||
moveToNextStepIfNeeded()
|
||||
})
|
||||
|
||||
analyticsService.didAskUserConsent()
|
||||
analyticsService.didAskUserConsentFlow
|
||||
.distinctUntilChanged()
|
||||
.onEach { moveToNextStepIfNeeded() }
|
||||
.launchIn(lifecycleScope)
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class DefaultFtueService @Inject constructor(
|
|||
.onEach { updateState() }
|
||||
.launchIn(sessionCoroutineScope)
|
||||
|
||||
analyticsService.didAskUserConsent()
|
||||
analyticsService.didAskUserConsentFlow
|
||||
.distinctUntilChanged()
|
||||
.onEach { updateState() }
|
||||
.launchIn(sessionCoroutineScope)
|
||||
|
|
@ -118,7 +118,7 @@ class DefaultFtueService @Inject constructor(
|
|||
}
|
||||
|
||||
private suspend fun needsAnalyticsOptIn(): Boolean {
|
||||
return analyticsService.didAskUserConsent().first().not()
|
||||
return analyticsService.didAskUserConsentFlow.first().not()
|
||||
}
|
||||
|
||||
private suspend fun shouldAskNotificationPermissions(): Boolean {
|
||||
|
|
|
|||
|
|
@ -82,7 +82,9 @@ class JoinRoomPresenter @AssistedInject constructor(
|
|||
override fun present(): JoinRoomState {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
var retryCount by remember { mutableIntStateOf(0) }
|
||||
val roomInfo by matrixClient.getRoomInfoFlow(roomId.toRoomIdOrAlias()).collectAsState(initial = Optional.empty())
|
||||
val roomInfo by remember {
|
||||
matrixClient.getRoomInfoFlow(roomId.toRoomIdOrAlias())
|
||||
}.collectAsState(initial = Optional.empty())
|
||||
val joinAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
|
||||
val knockAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
|
||||
val cancelKnockAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
|
||||
|
|
|
|||
|
|
@ -87,7 +87,9 @@ class DefaultBiometricAuthenticatorManager @Inject constructor(
|
|||
|
||||
@Composable
|
||||
override fun rememberUnlockBiometricAuthenticator(): BiometricAuthenticator {
|
||||
val isBiometricAllowed by lockScreenStore.isBiometricUnlockAllowed().collectAsState(initial = false)
|
||||
val isBiometricAllowed by remember {
|
||||
lockScreenStore.isBiometricUnlockAllowed()
|
||||
}.collectAsState(initial = false)
|
||||
val lifecycleState by LocalLifecycleOwner.current.lifecycle.currentStateFlow.collectAsState()
|
||||
val isAvailable by remember(lifecycleState) {
|
||||
derivedStateOf { isBiometricAllowed && hasAvailableAuthenticator }
|
||||
|
|
|
|||
|
|
@ -38,7 +38,9 @@ class LockScreenSettingsPresenter @Inject constructor(
|
|||
value = !lockScreenConfig.isPinMandatory && hasPinCode
|
||||
}
|
||||
}
|
||||
val isBiometricEnabled by lockScreenStore.isBiometricUnlockAllowed().collectAsState(initial = false)
|
||||
val isBiometricEnabled by remember {
|
||||
lockScreenStore.isBiometricUnlockAllowed()
|
||||
}.collectAsState(initial = false)
|
||||
var showRemovePinConfirmation by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@ class AccountProviderDataSource @Inject constructor(
|
|||
defaultAccountProvider
|
||||
)
|
||||
|
||||
fun flow(): StateFlow<AccountProvider> {
|
||||
return accountProvider.asStateFlow()
|
||||
}
|
||||
val flow: StateFlow<AccountProvider> = accountProvider.asStateFlow()
|
||||
|
||||
fun reset() {
|
||||
accountProvider.tryEmit(defaultAccountProvider)
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(
|
|||
|
||||
@Composable
|
||||
override fun present(): ConfirmAccountProviderState {
|
||||
val accountProvider by accountProviderDataSource.flow().collectAsState()
|
||||
val accountProvider by accountProviderDataSource.flow.collectAsState()
|
||||
val localCoroutineScope = rememberCoroutineScope()
|
||||
|
||||
val loginFlowAction: MutableState<AsyncData<LoginFlow>> = remember {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class DefaultMessageParser @Inject constructor(
|
|||
val parser = Json { ignoreUnknownKeys = true }
|
||||
val response = parser.decodeFromString(MobileRegistrationResponse.serializer(), message)
|
||||
val userId = response.userId ?: error("No user ID in response")
|
||||
val homeServer = response.homeServer ?: accountProviderDataSource.flow().value.url
|
||||
val homeServer = response.homeServer ?: accountProviderDataSource.flow.value.url
|
||||
val accessToken = response.accessToken ?: error("No access token in response")
|
||||
val deviceId = response.deviceId ?: error("No device ID in response")
|
||||
return ExternalSession(
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class LoginPasswordPresenter @Inject constructor(
|
|||
val formState = rememberSaveable {
|
||||
mutableStateOf(LoginFormState.Default)
|
||||
}
|
||||
val accountProvider by accountProviderDataSource.flow().collectAsState()
|
||||
val accountProvider by accountProviderDataSource.flow.collectAsState()
|
||||
|
||||
fun handleEvents(event: LoginPasswordEvents) {
|
||||
when (event) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class AccountProviderDataSourceTest {
|
|||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val sut = AccountProviderDataSource(FakeEnterpriseService())
|
||||
sut.flow().test {
|
||||
sut.flow.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState).isEqualTo(
|
||||
AccountProvider(
|
||||
|
|
@ -43,7 +43,7 @@ class AccountProviderDataSourceTest {
|
|||
val sut = AccountProviderDataSource(FakeEnterpriseService(
|
||||
defaultHomeserverResult = { AuthenticationConfig.MATRIX_ORG_URL }
|
||||
))
|
||||
sut.flow().test {
|
||||
sut.flow.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState).isEqualTo(
|
||||
AccountProvider(
|
||||
|
|
@ -61,7 +61,7 @@ class AccountProviderDataSourceTest {
|
|||
@Test
|
||||
fun `present - user change and reset`() = runTest {
|
||||
val sut = AccountProviderDataSource(FakeEnterpriseService())
|
||||
sut.flow().test {
|
||||
sut.flow.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.url).isEqualTo(FakeEnterpriseService.A_FAKE_HOMESERVER)
|
||||
sut.userSelection(AccountProvider(url = "https://example.com"))
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther
|
|||
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.canSendMessage
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.api.sync.isOnline
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
||||
import io.element.android.libraries.matrix.ui.messages.reply.map
|
||||
import io.element.android.libraries.matrix.ui.model.getAvatarData
|
||||
|
|
@ -183,7 +182,7 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
showReinvitePrompt = !hasDismissedInviteDialog && composerHasFocus && roomInfo.isDm && roomInfo.activeMembersCount == 1L
|
||||
}
|
||||
}
|
||||
val isOnline by syncService.isOnline().collectAsState()
|
||||
val isOnline by syncService.isOnline.collectAsState()
|
||||
|
||||
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,9 @@ class DefaultActionListPresenter @AssistedInject constructor(
|
|||
mutableStateOf(ActionListState.Target.None)
|
||||
}
|
||||
|
||||
val isDeveloperModeEnabled by appPreferencesStore.isDeveloperModeEnabledFlow().collectAsState(initial = false)
|
||||
val isDeveloperModeEnabled by remember {
|
||||
appPreferencesStore.isDeveloperModeEnabledFlow()
|
||||
}.collectAsState(initial = false)
|
||||
val isPinnedEventsEnabled = isPinnedMessagesFeatureEnabled()
|
||||
val pinnedEventIds by remember {
|
||||
room.roomInfoFlow.map { it.pinnedEventIds }
|
||||
|
|
|
|||
|
|
@ -78,8 +78,12 @@ class AttachmentsPreviewPresenter @AssistedInject constructor(
|
|||
|
||||
val ongoingSendAttachmentJob = remember { mutableStateOf<Job?>(null) }
|
||||
|
||||
val allowCaption by featureFlagService.isFeatureEnabledFlow(FeatureFlags.MediaCaptionCreation).collectAsState(initial = false)
|
||||
val showCaptionCompatibilityWarning by featureFlagService.isFeatureEnabledFlow(FeatureFlags.MediaCaptionWarning).collectAsState(initial = false)
|
||||
val allowCaption by remember {
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.MediaCaptionCreation)
|
||||
}.collectAsState(initial = false)
|
||||
val showCaptionCompatibilityWarning by remember {
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.MediaCaptionWarning)
|
||||
}.collectAsState(initial = false)
|
||||
|
||||
var useSendQueue by remember { mutableStateOf(false) }
|
||||
var preprocessMediaJob by remember { mutableStateOf<Job?>(null) }
|
||||
|
|
|
|||
|
|
@ -177,7 +177,9 @@ class MessageComposerPresenter @AssistedInject constructor(
|
|||
}
|
||||
var showAttachmentSourcePicker: Boolean by remember { mutableStateOf(false) }
|
||||
|
||||
val sendTypingNotifications by sessionPreferencesStore.isSendTypingNotificationsEnabled().collectAsState(initial = true)
|
||||
val sendTypingNotifications by remember {
|
||||
sessionPreferencesStore.isSendTypingNotificationsEnabled()
|
||||
}.collectAsState(initial = true)
|
||||
|
||||
LaunchedEffect(cameraPermissionState.permissionGranted) {
|
||||
if (cameraPermissionState.permissionGranted) {
|
||||
|
|
@ -397,16 +399,16 @@ class MessageComposerPresenter @AssistedInject constructor(
|
|||
.stateIn(this, SharingStarted.Lazily, emptyList())
|
||||
|
||||
combine(mentionTriggerFlow, room.membersStateFlow, roomAliasSuggestionsFlow) { suggestion, roomMembersState, roomAliasSuggestions ->
|
||||
val result = suggestionsProcessor.process(
|
||||
suggestion = suggestion,
|
||||
roomMembersState = roomMembersState,
|
||||
roomAliasSuggestions = roomAliasSuggestions,
|
||||
currentUserId = currentUserId,
|
||||
canSendRoomMention = ::canSendRoomMention,
|
||||
)
|
||||
suggestions.clear()
|
||||
suggestions.addAll(result)
|
||||
}
|
||||
val result = suggestionsProcessor.process(
|
||||
suggestion = suggestion,
|
||||
roomMembersState = roomMembersState,
|
||||
roomAliasSuggestions = roomAliasSuggestions,
|
||||
currentUserId = currentUserId,
|
||||
canSendRoomMention = ::canSendRoomMention,
|
||||
)
|
||||
suggestions.clear()
|
||||
suggestions.addAll(result)
|
||||
}
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,9 +109,15 @@ class TimelinePresenter @AssistedInject constructor(
|
|||
val messageShield: MutableState<MessageShield?> = remember { mutableStateOf(null) }
|
||||
|
||||
val resolveVerifiedUserSendFailureState = resolveVerifiedUserSendFailurePresenter.present()
|
||||
val isSendPublicReadReceiptsEnabled by sessionPreferencesStore.isSendPublicReadReceiptsEnabled().collectAsState(initial = true)
|
||||
val renderReadReceipts by sessionPreferencesStore.isRenderReadReceiptsEnabled().collectAsState(initial = true)
|
||||
val isLive by timelineController.isLive().collectAsState(initial = true)
|
||||
val isSendPublicReadReceiptsEnabled by remember {
|
||||
sessionPreferencesStore.isSendPublicReadReceiptsEnabled()
|
||||
}.collectAsState(initial = true)
|
||||
val renderReadReceipts by remember {
|
||||
sessionPreferencesStore.isRenderReadReceiptsEnabled()
|
||||
}.collectAsState(initial = true)
|
||||
val isLive by remember {
|
||||
timelineController.isLive()
|
||||
}.collectAsState(initial = true)
|
||||
|
||||
fun handleEvents(event: TimelineEvents) {
|
||||
when (event) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ class TimelineProtectionPresenter @Inject constructor(
|
|||
) : Presenter<TimelineProtectionState> {
|
||||
@Composable
|
||||
override fun present(): TimelineProtectionState {
|
||||
val hideMediaContent by appPreferencesStore.doesHideImagesAndVideosFlow().collectAsState(initial = false)
|
||||
val hideMediaContent by remember {
|
||||
appPreferencesStore.doesHideImagesAndVideosFlow()
|
||||
}.collectAsState(initial = false)
|
||||
var allowedEvents by remember { mutableStateOf<Set<EventId>>(setOf()) }
|
||||
val protectionState by remember(hideMediaContent) {
|
||||
derivedStateOf {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ class TypingNotificationPresenter @Inject constructor(
|
|||
) : Presenter<TypingNotificationState> {
|
||||
@Composable
|
||||
override fun present(): TypingNotificationState {
|
||||
val renderTypingNotifications by sessionPreferencesStore.isRenderTypingNotificationsEnabled().collectAsState(initial = true)
|
||||
val renderTypingNotifications by remember {
|
||||
sessionPreferencesStore.isRenderTypingNotificationsEnabled()
|
||||
}.collectAsState(initial = true)
|
||||
val typingMembersState by produceState(initialValue = persistentListOf(), key1 = renderTypingNotifications) {
|
||||
if (renderTypingNotifications) {
|
||||
observeRoomTypingMembers()
|
||||
|
|
|
|||
|
|
@ -33,7 +33,9 @@ class MigrationPresenter @Inject constructor(
|
|||
|
||||
@Composable
|
||||
override fun present(): MigrationState {
|
||||
val migrationStoreVersion by migrationStore.applicationMigrationVersion().collectAsState(initial = null)
|
||||
val migrationStoreVersion by remember {
|
||||
migrationStore.applicationMigrationVersion()
|
||||
}.collectAsState(initial = null)
|
||||
var migrationAction: AsyncData<Unit> by remember { mutableStateOf(AsyncData.Uninitialized) }
|
||||
|
||||
// Uncomment this block to run the migration everytime
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class PollHistoryPresenter @Inject constructor(
|
|||
@Composable
|
||||
override fun present(): PollHistoryState {
|
||||
val timeline = room.liveTimeline
|
||||
val paginationState by timeline.paginationStatus(Timeline.PaginationDirection.BACKWARDS).collectAsState()
|
||||
val paginationState by timeline.backwardPaginationStatus.collectAsState()
|
||||
val pollHistoryItemsFlow = remember {
|
||||
timeline.timelineItems.map { items ->
|
||||
pollHistoryItemFactory.create(items)
|
||||
|
|
|
|||
|
|
@ -29,19 +29,18 @@ class AdvancedSettingsPresenter @Inject constructor(
|
|||
@Composable
|
||||
override fun present(): AdvancedSettingsState {
|
||||
val localCoroutineScope = rememberCoroutineScope()
|
||||
val isDeveloperModeEnabled by appPreferencesStore
|
||||
.isDeveloperModeEnabledFlow()
|
||||
.collectAsState(initial = false)
|
||||
val isSharePresenceEnabled by sessionPreferencesStore
|
||||
.isSharePresenceEnabled()
|
||||
.collectAsState(initial = true)
|
||||
val doesCompressMedia by sessionPreferencesStore
|
||||
.doesCompressMedia()
|
||||
.collectAsState(initial = true)
|
||||
val isDeveloperModeEnabled by remember {
|
||||
appPreferencesStore.isDeveloperModeEnabledFlow()
|
||||
}.collectAsState(initial = false)
|
||||
val isSharePresenceEnabled by remember {
|
||||
sessionPreferencesStore.isSharePresenceEnabled()
|
||||
}.collectAsState(initial = true)
|
||||
val doesCompressMedia by remember {
|
||||
sessionPreferencesStore.doesCompressMedia()
|
||||
}.collectAsState(initial = true)
|
||||
val theme by remember {
|
||||
appPreferencesStore.getThemeFlow().mapToTheme()
|
||||
}
|
||||
.collectAsState(initial = Theme.System)
|
||||
}.collectAsState(initial = Theme.System)
|
||||
var showChangeThemeDialog by remember { mutableStateOf(false) }
|
||||
|
||||
fun handleEvents(event: AdvancedSettingsEvents) {
|
||||
|
|
|
|||
|
|
@ -44,17 +44,17 @@ class BlockedUsersPresenter @Inject constructor(
|
|||
mutableStateOf(AsyncAction.Uninitialized)
|
||||
}
|
||||
|
||||
val renderBlockedUsersDetail = featureFlagService
|
||||
.isFeatureEnabledFlow(FeatureFlags.ShowBlockedUsersDetails)
|
||||
.collectAsState(initial = false)
|
||||
val renderBlockedUsersDetail by remember {
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.ShowBlockedUsersDetails)
|
||||
}.collectAsState(initial = false)
|
||||
val ignoredUserIds by matrixClient.ignoredUsersFlow.collectAsState()
|
||||
val ignoredMatrixUser by produceState(
|
||||
initialValue = ignoredUserIds.map { MatrixUser(userId = it) },
|
||||
key1 = renderBlockedUsersDetail.value,
|
||||
key1 = renderBlockedUsersDetail,
|
||||
key2 = ignoredUserIds
|
||||
) {
|
||||
value = ignoredUserIds.map {
|
||||
if (renderBlockedUsersDetail.value) {
|
||||
if (renderBlockedUsersDetail) {
|
||||
matrixClient.getProfile(it).getOrNull()
|
||||
} else {
|
||||
null
|
||||
|
|
|
|||
|
|
@ -71,12 +71,14 @@ class DeveloperSettingsPresenter @Inject constructor(
|
|||
val clearCacheAction = remember {
|
||||
mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized)
|
||||
}
|
||||
val customElementCallBaseUrl by appPreferencesStore
|
||||
.getCustomElementCallBaseUrlFlow()
|
||||
.collectAsState(initial = null)
|
||||
val hideImagesAndVideos by appPreferencesStore
|
||||
.doesHideImagesAndVideosFlow()
|
||||
.collectAsState(initial = false)
|
||||
val customElementCallBaseUrl by remember {
|
||||
appPreferencesStore
|
||||
.getCustomElementCallBaseUrlFlow()
|
||||
}.collectAsState(initial = null)
|
||||
val hideImagesAndVideos by remember {
|
||||
appPreferencesStore
|
||||
.doesHideImagesAndVideosFlow()
|
||||
}.collectAsState(initial = false)
|
||||
|
||||
val tracingLogLevelFlow = remember {
|
||||
appPreferencesStore.getTracingLogLevelFlow().map { AsyncData.Success(it.toLogLevelItem()) }
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ class NotificationSettingsPresenter @Inject constructor(
|
|||
val changeNotificationSettingAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
|
||||
|
||||
val localCoroutineScope = rememberCoroutineScope()
|
||||
val appNotificationsEnabled = userPushStore
|
||||
.getNotificationEnabledForDevice()
|
||||
.collectAsState(initial = false)
|
||||
val appNotificationsEnabled by remember {
|
||||
userPushStore.getNotificationEnabledForDevice()
|
||||
}.collectAsState(initial = false)
|
||||
|
||||
val matrixSettings: MutableState<NotificationSettingsState.MatrixSettings> = remember {
|
||||
mutableStateOf(NotificationSettingsState.MatrixSettings.Uninitialized)
|
||||
|
|
@ -158,7 +158,7 @@ class NotificationSettingsPresenter @Inject constructor(
|
|||
matrixSettings = matrixSettings.value,
|
||||
appSettings = NotificationSettingsState.AppSettings(
|
||||
systemNotificationsEnabled = systemNotificationsEnabled.value,
|
||||
appNotificationsEnabled = appNotificationsEnabled.value
|
||||
appNotificationsEnabled = appNotificationsEnabled,
|
||||
),
|
||||
changeNotificationSettingAction = changeNotificationSettingAction.value,
|
||||
currentPushDistributor = currentDistributor,
|
||||
|
|
|
|||
|
|
@ -64,9 +64,9 @@ class BugReportPresenter @Inject constructor(
|
|||
screenshotHolder.getFileUri()
|
||||
)
|
||||
}
|
||||
val crashInfo: String by crashDataStore
|
||||
.crashInfo()
|
||||
.collectAsState(initial = "")
|
||||
val crashInfo: String by remember {
|
||||
crashDataStore.crashInfo()
|
||||
}.collectAsState(initial = "")
|
||||
|
||||
val sendingProgress = remember {
|
||||
mutableFloatStateOf(0f)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ package io.element.android.features.rageshake.impl.preferences
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
|
|
@ -39,13 +40,13 @@ class DefaultRageshakePreferencesPresenter @Inject constructor(
|
|||
mutableStateOf(rageshake.isAvailable())
|
||||
}
|
||||
val isFeatureAvailable = remember { rageshakeFeatureAvailability.isAvailable() }
|
||||
val isEnabled = rageshakeDataStore
|
||||
.isEnabled()
|
||||
.collectAsState(initial = false)
|
||||
val isEnabled by remember {
|
||||
rageshakeDataStore.isEnabled()
|
||||
}.collectAsState(initial = false)
|
||||
|
||||
val sensitivity = rageshakeDataStore
|
||||
.sensitivity()
|
||||
.collectAsState(initial = 0f)
|
||||
val sensitivity by remember {
|
||||
rageshakeDataStore.sensitivity()
|
||||
}.collectAsState(initial = 0f)
|
||||
|
||||
fun handleEvents(event: RageshakePreferencesEvents) {
|
||||
when (event) {
|
||||
|
|
@ -56,9 +57,9 @@ class DefaultRageshakePreferencesPresenter @Inject constructor(
|
|||
|
||||
return RageshakePreferencesState(
|
||||
isFeatureEnabled = isFeatureAvailable,
|
||||
isEnabled = isEnabled.value,
|
||||
isEnabled = isEnabled,
|
||||
isSupported = isSupported.value,
|
||||
sensitivity = sensitivity.value,
|
||||
sensitivity = sensitivity,
|
||||
eventSink = ::handleEvents
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,9 @@ class RoomDetailsPresenter @Inject constructor(
|
|||
}
|
||||
|
||||
val canHandleKnockRequests by room.canHandleKnockRequestsAsState(syncUpdateFlow.value)
|
||||
val isKnockRequestsEnabled by featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock).collectAsState(false)
|
||||
val isKnockRequestsEnabled by remember {
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock)
|
||||
}.collectAsState(false)
|
||||
val knockRequestsCount by produceState<Int?>(null) {
|
||||
room.knockRequestsFlow.collect { value = it.size }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
|||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomList
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.api.sync.isOnline
|
||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
|
||||
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
|
||||
|
|
@ -101,7 +100,7 @@ class RoomListPresenter @Inject constructor(
|
|||
val coroutineScope = rememberCoroutineScope()
|
||||
val leaveRoomState = leaveRoomPresenter.present()
|
||||
val matrixUser = client.userProfile.collectAsState()
|
||||
val isOnline by syncService.isOnline().collectAsState()
|
||||
val isOnline by syncService.isOnline.collectAsState()
|
||||
val filtersState = filtersPresenter.present()
|
||||
val searchState = searchPresenter.present()
|
||||
val acceptDeclineInviteState = acceptDeclineInvitePresenter.present()
|
||||
|
|
|
|||
|
|
@ -34,7 +34,9 @@ class SignedOutPresenter @AssistedInject constructor(
|
|||
|
||||
@Composable
|
||||
override fun present(): SignedOutState {
|
||||
val sessions by sessionStore.sessionsFlow().collectAsState(initial = emptyList())
|
||||
val sessions by remember {
|
||||
sessionStore.sessionsFlow()
|
||||
}.collectAsState(initial = emptyList())
|
||||
val signedOutSession by remember {
|
||||
derivedStateOf { sessions.firstOrNull { it.userId == sessionId } }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue