Merge branch 'develop' of https://github.com/vector-im/element-x-android into dla/feature/custom_room_notification_settings_list
This commit is contained in:
commit
af4a1d3fd6
1981 changed files with 15504 additions and 5063 deletions
|
|
@ -17,7 +17,7 @@
|
|||
package io.element.android.features.roomdetails.impl
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomState
|
||||
import io.element.android.features.leaveroom.api.aLeaveRoomState
|
||||
import io.element.android.features.roomdetails.impl.members.details.aRoomMemberDetailsState
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
|
|
@ -80,7 +80,7 @@ fun aRoomDetailsState() = RoomDetailsState(
|
|||
canShowNotificationSettings = true,
|
||||
roomType = RoomDetailsType.Room,
|
||||
roomMemberDetailsState = null,
|
||||
leaveRoomState = LeaveRoomState(),
|
||||
leaveRoomState = aLeaveRoomState(),
|
||||
roomNotificationSettings = RoomNotificationSettings(mode = RoomNotificationMode.MUTE, isDefault = false),
|
||||
eventSink = {}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -33,12 +33,7 @@ import androidx.compose.foundation.verticalScroll
|
|||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.outlined.Add
|
||||
import androidx.compose.material.icons.outlined.Lock
|
||||
import androidx.compose.material.icons.outlined.Notifications
|
||||
import androidx.compose.material.icons.outlined.NotificationsOff
|
||||
import androidx.compose.material.icons.outlined.Person
|
||||
import androidx.compose.material.icons.outlined.PersonAddAlt
|
||||
import androidx.compose.material.icons.outlined.Share
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -48,9 +43,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
|
@ -69,7 +62,7 @@ import io.element.android.libraries.designsystem.components.preferences.Preferen
|
|||
import io.element.android.libraries.designsystem.components.preferences.PreferenceText
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.preview.LargeHeightPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight
|
||||
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
|
||||
|
|
@ -77,6 +70,7 @@ import io.element.android.libraries.designsystem.theme.components.IconButton
|
|||
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
|
@ -153,7 +147,8 @@ fun RoomDetailsView(
|
|||
if (state.canShowNotificationSettings && state.roomNotificationSettings != null) {
|
||||
NotificationSection(
|
||||
isDefaultMode = state.roomNotificationSettings.isDefault,
|
||||
openRoomNotificationSettings = openRoomNotificationSettings)
|
||||
openRoomNotificationSettings = openRoomNotificationSettings
|
||||
)
|
||||
}
|
||||
|
||||
if (state.roomType is RoomDetailsType.Room) {
|
||||
|
|
@ -188,7 +183,7 @@ fun RoomDetailsView(
|
|||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
internal fun RoomDetailsTopBar(
|
||||
private fun RoomDetailsTopBar(
|
||||
goBack: () -> Unit,
|
||||
onActionClicked: (RoomDetailsAction) -> Unit,
|
||||
showEdit: Boolean,
|
||||
|
|
@ -225,27 +220,39 @@ internal fun RoomDetailsTopBar(
|
|||
}
|
||||
|
||||
@Composable
|
||||
internal fun MainActionsSection(state: RoomDetailsState, onShareRoom: () -> Unit, modifier: Modifier = Modifier) {
|
||||
private fun MainActionsSection(state: RoomDetailsState, onShareRoom: () -> Unit, modifier: Modifier = Modifier) {
|
||||
Row(modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
|
||||
val roomNotificationSettings = state.roomNotificationSettings
|
||||
if (state.canShowNotificationSettings && roomNotificationSettings != null) {
|
||||
if (roomNotificationSettings.mode == RoomNotificationMode.MUTE) {
|
||||
MainActionButton(title = stringResource(CommonStrings.common_unmute), icon = Icons.Outlined.NotificationsOff, onClick = {
|
||||
state.eventSink(RoomDetailsEvent.UnmuteNotification)
|
||||
})
|
||||
MainActionButton(
|
||||
title = stringResource(CommonStrings.common_unmute),
|
||||
iconResourceId = CommonDrawables.ic_compound_notifications_off,
|
||||
onClick = {
|
||||
state.eventSink(RoomDetailsEvent.UnmuteNotification)
|
||||
},
|
||||
)
|
||||
} else {
|
||||
MainActionButton(title = stringResource(CommonStrings.common_mute), icon = Icons.Outlined.Notifications, onClick = {
|
||||
state.eventSink(RoomDetailsEvent.MuteNotification)
|
||||
})
|
||||
MainActionButton(
|
||||
title = stringResource(CommonStrings.common_mute),
|
||||
iconResourceId = CommonDrawables.ic_compound_notifications,
|
||||
onClick = {
|
||||
state.eventSink(RoomDetailsEvent.MuteNotification)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.width(20.dp))
|
||||
MainActionButton(title = stringResource(R.string.screen_room_details_share_room_title), icon = Icons.Outlined.Share, onClick = onShareRoom)
|
||||
MainActionButton(
|
||||
title = stringResource(R.string.screen_room_details_share_room_title),
|
||||
iconResourceId = CommonDrawables.ic_compound_share_android,
|
||||
onClick = onShareRoom
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun RoomHeaderSection(
|
||||
private fun RoomHeaderSection(
|
||||
avatarUrl: String?,
|
||||
roomId: String,
|
||||
roomName: String,
|
||||
|
|
@ -282,7 +289,7 @@ internal fun RoomHeaderSection(
|
|||
}
|
||||
|
||||
@Composable
|
||||
internal fun TopicSection(
|
||||
private fun TopicSection(
|
||||
roomTopic: RoomTopicState,
|
||||
onActionClicked: (RoomDetailsAction) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
|
|
@ -308,7 +315,7 @@ internal fun TopicSection(
|
|||
}
|
||||
|
||||
@Composable
|
||||
internal fun NotificationSection(
|
||||
private fun NotificationSection(
|
||||
isDefaultMode: Boolean,
|
||||
openRoomNotificationSettings: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
|
|
@ -322,21 +329,21 @@ internal fun NotificationSection(
|
|||
PreferenceText(
|
||||
title = stringResource(R.string.screen_room_details_notification_title),
|
||||
subtitle = subtitle,
|
||||
icon = Icons.Outlined.Notifications,
|
||||
iconResourceId = CommonDrawables.ic_compound_notifications,
|
||||
onClick = openRoomNotificationSettings,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun MembersSection(
|
||||
private fun MembersSection(
|
||||
memberCount: Long,
|
||||
openRoomMemberList: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
PreferenceCategory(modifier = modifier) {
|
||||
PreferenceText(
|
||||
title = stringResource(R.string.screen_room_details_people_title),
|
||||
title = stringResource(CommonStrings.common_people),
|
||||
icon = Icons.Outlined.Person,
|
||||
currentValue = memberCount.toString(),
|
||||
onClick = openRoomMemberList,
|
||||
|
|
@ -345,48 +352,48 @@ internal fun MembersSection(
|
|||
}
|
||||
|
||||
@Composable
|
||||
internal fun InviteSection(
|
||||
private fun InviteSection(
|
||||
invitePeople: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
PreferenceCategory(modifier = modifier) {
|
||||
PreferenceText(
|
||||
title = stringResource(R.string.screen_room_details_invite_people_title),
|
||||
icon = Icons.Outlined.PersonAddAlt,
|
||||
iconResourceId = CommonDrawables.ic_compound_user_add,
|
||||
onClick = invitePeople,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun SecuritySection(modifier: Modifier = Modifier) {
|
||||
private fun SecuritySection(modifier: Modifier = Modifier) {
|
||||
PreferenceCategory(title = stringResource(R.string.screen_room_details_security_title), modifier = modifier) {
|
||||
PreferenceText(
|
||||
title = stringResource(R.string.screen_room_details_encryption_enabled_title),
|
||||
subtitle = stringResource(R.string.screen_room_details_encryption_enabled_subtitle),
|
||||
icon = Icons.Outlined.Lock,
|
||||
iconResourceId = CommonDrawables.ic_compound_lock,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun OtherActionsSection(onLeaveRoom: () -> Unit, modifier: Modifier = Modifier) {
|
||||
private fun OtherActionsSection(onLeaveRoom: () -> Unit, modifier: Modifier = Modifier) {
|
||||
PreferenceCategory(showDivider = false, modifier = modifier) {
|
||||
PreferenceText(
|
||||
title = stringResource(R.string.screen_room_details_leave_room_title),
|
||||
icon = ImageVector.vectorResource(R.drawable.ic_door_open),
|
||||
iconResourceId = CommonDrawables.ic_compound_leave,
|
||||
tintColor = MaterialTheme.colorScheme.error,
|
||||
onClick = onLeaveRoom,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@LargeHeightPreview
|
||||
@PreviewWithLargeHeight
|
||||
@Composable
|
||||
internal fun RoomDetailsPreview(@PreviewParameter(RoomDetailsStateProvider::class) state: RoomDetailsState) =
|
||||
ElementPreviewLight { ContentToPreview(state) }
|
||||
|
||||
@LargeHeightPreview
|
||||
@PreviewWithLargeHeight
|
||||
@Composable
|
||||
internal fun RoomDetailsDarkPreview(@PreviewParameter(RoomDetailsStateProvider::class) state: RoomDetailsState) =
|
||||
ElementPreviewDark { ContentToPreview(state) }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.features.roomdetails.impl.blockuser
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import io.element.android.features.roomdetails.impl.R
|
||||
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsEvents
|
||||
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsState
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
|
||||
|
||||
@Composable
|
||||
fun BlockUserDialogs(state: RoomMemberDetailsState) {
|
||||
when (state.displayConfirmationDialog) {
|
||||
null -> Unit
|
||||
RoomMemberDetailsState.ConfirmationDialog.Block -> {
|
||||
BlockConfirmationDialog(
|
||||
onBlockAction = {
|
||||
state.eventSink(
|
||||
RoomMemberDetailsEvents.BlockUser(
|
||||
needsConfirmation = false
|
||||
)
|
||||
)
|
||||
},
|
||||
onDismiss = { state.eventSink(RoomMemberDetailsEvents.ClearConfirmationDialog) }
|
||||
)
|
||||
}
|
||||
RoomMemberDetailsState.ConfirmationDialog.Unblock -> {
|
||||
UnblockConfirmationDialog(
|
||||
onUnblockAction = {
|
||||
state.eventSink(
|
||||
RoomMemberDetailsEvents.UnblockUser(
|
||||
needsConfirmation = false
|
||||
)
|
||||
)
|
||||
},
|
||||
onDismiss = { state.eventSink(RoomMemberDetailsEvents.ClearConfirmationDialog) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BlockConfirmationDialog(onBlockAction: () -> Unit, onDismiss: () -> Unit) {
|
||||
ConfirmationDialog(
|
||||
title = stringResource(R.string.screen_dm_details_block_user),
|
||||
content = stringResource(R.string.screen_dm_details_block_alert_description),
|
||||
submitText = stringResource(R.string.screen_dm_details_block_alert_action),
|
||||
onSubmitClicked = onBlockAction,
|
||||
onDismiss = onDismiss
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UnblockConfirmationDialog(onUnblockAction: () -> Unit, onDismiss: () -> Unit) {
|
||||
ConfirmationDialog(
|
||||
title = stringResource(R.string.screen_dm_details_unblock_user),
|
||||
content = stringResource(R.string.screen_dm_details_unblock_alert_description),
|
||||
submitText = stringResource(R.string.screen_dm_details_unblock_alert_action),
|
||||
onSubmitClicked = onUnblockAction,
|
||||
onDismiss = onDismiss
|
||||
)
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@ import io.element.android.features.roomdetails.impl.members.details.RoomMemberDe
|
|||
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsState
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.core.bool.orFalse
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
|
||||
import io.element.android.libraries.designsystem.components.dialogs.RetryDialog
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceText
|
||||
|
|
@ -85,44 +84,3 @@ private fun PreferenceBlockUser(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun BlockUserDialogs(state: RoomMemberDetailsState) {
|
||||
when (state.displayConfirmationDialog) {
|
||||
null -> Unit
|
||||
RoomMemberDetailsState.ConfirmationDialog.Block -> {
|
||||
BlockConfirmationDialog(
|
||||
onBlockAction = { state.eventSink(RoomMemberDetailsEvents.BlockUser(needsConfirmation = false)) },
|
||||
onDismiss = { state.eventSink(RoomMemberDetailsEvents.ClearConfirmationDialog) }
|
||||
)
|
||||
}
|
||||
RoomMemberDetailsState.ConfirmationDialog.Unblock -> {
|
||||
UnblockConfirmationDialog(
|
||||
onUnblockAction = { state.eventSink(RoomMemberDetailsEvents.UnblockUser(needsConfirmation = false)) },
|
||||
onDismiss = { state.eventSink(RoomMemberDetailsEvents.ClearConfirmationDialog) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun BlockConfirmationDialog(onBlockAction: () -> Unit, onDismiss: () -> Unit) {
|
||||
ConfirmationDialog(
|
||||
title = stringResource(R.string.screen_dm_details_block_user),
|
||||
content = stringResource(R.string.screen_dm_details_block_alert_description),
|
||||
submitText = stringResource(R.string.screen_dm_details_block_alert_action),
|
||||
onSubmitClicked = onBlockAction,
|
||||
onDismiss = onDismiss
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun UnblockConfirmationDialog(onUnblockAction: () -> Unit, onDismiss: () -> Unit) {
|
||||
ConfirmationDialog(
|
||||
title = stringResource(R.string.screen_dm_details_unblock_user),
|
||||
content = stringResource(R.string.screen_dm_details_unblock_alert_description),
|
||||
submitText = stringResource(R.string.screen_dm_details_unblock_alert_action),
|
||||
onSubmitClicked = onUnblockAction,
|
||||
onDismiss = onDismiss
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ import io.element.android.libraries.matrix.api.room.powerlevels.canSendState
|
|||
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||
import io.element.android.libraries.mediapickers.api.PickerProvider
|
||||
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
|
||||
import io.element.android.libraries.permissions.api.PermissionsEvents
|
||||
import io.element.android.libraries.permissions.api.PermissionsPresenter
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -49,10 +51,15 @@ class RoomDetailsEditPresenter @Inject constructor(
|
|||
private val room: MatrixRoom,
|
||||
private val mediaPickerProvider: PickerProvider,
|
||||
private val mediaPreProcessor: MediaPreProcessor,
|
||||
permissionsPresenterFactory: PermissionsPresenter.Factory,
|
||||
) : Presenter<RoomDetailsEditState> {
|
||||
|
||||
private val cameraPermissionPresenter = permissionsPresenterFactory.create(android.Manifest.permission.CAMERA)
|
||||
private var pendingPermissionRequest = false
|
||||
|
||||
@Composable
|
||||
override fun present(): RoomDetailsEditState {
|
||||
val cameraPermissionState = cameraPermissionPresenter.present()
|
||||
val roomSyncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
||||
|
||||
// Since there is no way to obtain the new avatar uri after uploading a new avatar,
|
||||
|
|
@ -92,6 +99,13 @@ class RoomDetailsEditPresenter @Inject constructor(
|
|||
onResult = { uri -> if (uri != null) roomAvatarUri = uri }
|
||||
)
|
||||
|
||||
LaunchedEffect(cameraPermissionState.permissionGranted) {
|
||||
if (cameraPermissionState.permissionGranted && pendingPermissionRequest) {
|
||||
pendingPermissionRequest = false
|
||||
cameraPhotoPicker.launch()
|
||||
}
|
||||
}
|
||||
|
||||
val avatarActions by remember(roomAvatarUri) {
|
||||
derivedStateOf {
|
||||
listOfNotNull(
|
||||
|
|
@ -110,7 +124,12 @@ class RoomDetailsEditPresenter @Inject constructor(
|
|||
is RoomDetailsEditEvents.HandleAvatarAction -> {
|
||||
when (event.action) {
|
||||
AvatarAction.ChoosePhoto -> galleryImagePicker.launch()
|
||||
AvatarAction.TakePhoto -> cameraPhotoPicker.launch()
|
||||
AvatarAction.TakePhoto -> if (cameraPermissionState.permissionGranted) {
|
||||
cameraPhotoPicker.launch()
|
||||
} else {
|
||||
pendingPermissionRequest = true
|
||||
cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions)
|
||||
}
|
||||
AvatarAction.Remove -> roomAvatarUri = null
|
||||
}
|
||||
}
|
||||
|
|
@ -132,6 +151,7 @@ class RoomDetailsEditPresenter @Inject constructor(
|
|||
avatarActions = avatarActions,
|
||||
saveButtonEnabled = saveButtonEnabled,
|
||||
saveAction = saveAction.value,
|
||||
cameraPermissionState = cameraPermissionState,
|
||||
eventSink = ::handleEvents,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@
|
|||
package io.element.android.features.roomdetails.impl.edit
|
||||
|
||||
import android.net.Uri
|
||||
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||
import io.element.android.libraries.permissions.api.PermissionsState
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
data class RoomDetailsEditState(
|
||||
|
|
@ -32,5 +33,6 @@ data class RoomDetailsEditState(
|
|||
val avatarActions: ImmutableList<AvatarAction>,
|
||||
val saveButtonEnabled: Boolean,
|
||||
val saveAction: Async<Unit>,
|
||||
val cameraPermissionState: PermissionsState,
|
||||
val eventSink: (RoomDetailsEditEvents) -> Unit
|
||||
)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package io.element.android.features.roomdetails.impl.edit
|
|||
import android.net.Uri
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.permissions.api.aPermissionsState
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
open class RoomDetailsEditStateProvider : PreviewParameterProvider<RoomDetailsEditState> {
|
||||
|
|
@ -45,5 +46,6 @@ fun aRoomDetailsEditState() = RoomDetailsEditState(
|
|||
avatarActions = persistentListOf(),
|
||||
saveButtonEnabled = true,
|
||||
saveAction = Async.Uninitialized,
|
||||
cameraPermissionState = aPermissionsState(showDialog = false),
|
||||
eventSink = {}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ import io.element.android.libraries.designsystem.components.ProgressDialog
|
|||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
||||
import io.element.android.libraries.designsystem.preview.DayNightPreviews
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.theme.aliasScreenTitle
|
||||
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||
|
|
@ -62,6 +62,7 @@ import io.element.android.libraries.designsystem.theme.components.TextButton
|
|||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
|
||||
import io.element.android.libraries.matrix.ui.components.EditableAvatarView
|
||||
import io.element.android.libraries.permissions.api.PermissionsView
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -193,6 +194,10 @@ fun RoomDetailsEditView(
|
|||
|
||||
else -> Unit
|
||||
}
|
||||
|
||||
PermissionsView(
|
||||
state = state.cameraPermissionState,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -228,7 +233,7 @@ private fun Modifier.clearFocusOnTap(focusManager: FocusManager): Modifier =
|
|||
})
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun RoomDetailsEditViewPreview(@PreviewParameter(RoomDetailsEditStateProvider::class) state: RoomDetailsEditState) = ElementPreview {
|
||||
RoomDetailsEditView(
|
||||
|
|
|
|||
|
|
@ -19,15 +19,14 @@ package io.element.android.features.roomdetails.impl.invite
|
|||
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
data class RoomInviteMembersState(
|
||||
val canInvite: Boolean = false,
|
||||
val searchQuery: String = "",
|
||||
val searchResults: SearchBarResultState<ImmutableList<InvitableUser>> = SearchBarResultState.NotSearching(),
|
||||
val selectedUsers: ImmutableList<MatrixUser> = persistentListOf(),
|
||||
val isSearchActive: Boolean = false,
|
||||
val eventSink: (RoomInviteMembersEvents) -> Unit = {},
|
||||
val canInvite: Boolean,
|
||||
val searchQuery: String,
|
||||
val searchResults: SearchBarResultState<ImmutableList<InvitableUser>>,
|
||||
val selectedUsers: ImmutableList<MatrixUser>,
|
||||
val isSearchActive: Boolean,
|
||||
val eventSink: (RoomInviteMembersEvents) -> Unit,
|
||||
)
|
||||
|
||||
data class InvitableUser(
|
||||
|
|
|
|||
|
|
@ -18,20 +18,22 @@ package io.element.android.features.roomdetails.impl.invite
|
|||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import io.element.android.libraries.matrix.ui.components.aMatrixUser
|
||||
import io.element.android.libraries.matrix.ui.components.aMatrixUserList
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
internal class RoomInviteMembersStateProvider : PreviewParameterProvider<RoomInviteMembersState> {
|
||||
override val values: Sequence<RoomInviteMembersState>
|
||||
get() = sequenceOf(
|
||||
RoomInviteMembersState(),
|
||||
RoomInviteMembersState(canInvite = true, selectedUsers = aMatrixUserList().toImmutableList()),
|
||||
RoomInviteMembersState(isSearchActive = true, searchQuery = "some query"),
|
||||
RoomInviteMembersState(isSearchActive = true, searchQuery = "some query", selectedUsers = aMatrixUserList().toImmutableList()),
|
||||
RoomInviteMembersState(isSearchActive = true, searchQuery = "some query", searchResults = SearchBarResultState.NoResults()),
|
||||
RoomInviteMembersState(
|
||||
aRoomInviteMembersState(),
|
||||
aRoomInviteMembersState(canInvite = true, selectedUsers = aMatrixUserList().toImmutableList()),
|
||||
aRoomInviteMembersState(isSearchActive = true, searchQuery = "some query"),
|
||||
aRoomInviteMembersState(isSearchActive = true, searchQuery = "some query", selectedUsers = aMatrixUserList().toImmutableList()),
|
||||
aRoomInviteMembersState(isSearchActive = true, searchQuery = "some query", searchResults = SearchBarResultState.NoResults()),
|
||||
aRoomInviteMembersState(
|
||||
isSearchActive = true,
|
||||
canInvite = true,
|
||||
searchQuery = "some query",
|
||||
|
|
@ -48,7 +50,7 @@ internal class RoomInviteMembersStateProvider : PreviewParameterProvider<RoomInv
|
|||
)
|
||||
)
|
||||
),
|
||||
RoomInviteMembersState(
|
||||
aRoomInviteMembersState(
|
||||
isSearchActive = true,
|
||||
canInvite = true,
|
||||
searchQuery = "@alice:server.org",
|
||||
|
|
@ -64,3 +66,20 @@ internal class RoomInviteMembersStateProvider : PreviewParameterProvider<RoomInv
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun aRoomInviteMembersState(
|
||||
canInvite: Boolean = false,
|
||||
searchQuery: String = "",
|
||||
searchResults: SearchBarResultState<ImmutableList<InvitableUser>> = SearchBarResultState.NotSearching(),
|
||||
selectedUsers: ImmutableList<MatrixUser> = persistentListOf(),
|
||||
isSearchActive: Boolean = false,
|
||||
): RoomInviteMembersState {
|
||||
return RoomInviteMembersState(
|
||||
canInvite = canInvite,
|
||||
searchQuery = searchQuery,
|
||||
searchResults = searchResults,
|
||||
selectedUsers = selectedUsers,
|
||||
isSearchActive = isSearchActive,
|
||||
eventSink = {},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import androidx.compose.ui.unit.dp
|
|||
import io.element.android.features.roomdetails.impl.R
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||
import io.element.android.libraries.designsystem.preview.DayNightPreviews
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.theme.aliasScreenTitle
|
||||
import io.element.android.libraries.designsystem.theme.components.HorizontalDivider
|
||||
|
|
@ -111,7 +111,7 @@ fun RoomInviteMembersView(
|
|||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun RoomInviteMembersTopBar(
|
||||
private fun RoomInviteMembersTopBar(
|
||||
canSend: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
onBackPressed: () -> Unit = {},
|
||||
|
|
@ -216,7 +216,7 @@ private fun RoomInviteMembersSearchBar(
|
|||
)
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun RoomInviteMembersPreview(@PreviewParameter(RoomInviteMembersStateProvider::class) state: RoomInviteMembersState) = ElementPreview {
|
||||
RoomInviteMembersView(state)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import io.element.android.features.roomdetails.impl.R
|
|||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||
import io.element.android.libraries.designsystem.preview.DayNightPreviews
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.theme.aliasScreenTitle
|
||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||
|
|
@ -203,7 +203,7 @@ private fun RoomMemberListTopBar(
|
|||
modifier = modifier,
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(R.string.screen_room_details_people_title),
|
||||
text = stringResource(CommonStrings.common_people),
|
||||
style = ElementTheme.typography.aliasScreenTitle,
|
||||
)
|
||||
},
|
||||
|
|
@ -249,7 +249,7 @@ private fun RoomMemberSearchBar(
|
|||
)
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun RoomMemberListPreview(@PreviewParameter(RoomMemberListStateProvider::class) state: RoomMemberListState) = ElementPreview {
|
||||
RoomMemberListView(
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ data class RoomMemberDetailsState(
|
|||
val userName: String?,
|
||||
val avatarUrl: String?,
|
||||
val isBlocked: Async<Boolean>,
|
||||
val displayConfirmationDialog: ConfirmationDialog? = null,
|
||||
val displayConfirmationDialog: ConfirmationDialog?,
|
||||
val isCurrentUser: Boolean,
|
||||
val eventSink: (RoomMemberDetailsEvents) -> Unit
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ fun aRoomMemberDetailsState() = RoomMemberDetailsState(
|
|||
userName = "Daniel",
|
||||
avatarUrl = null,
|
||||
isBlocked = Async.Success(false),
|
||||
displayConfirmationDialog = null,
|
||||
isCurrentUser = false,
|
||||
eventSink = {},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,49 +16,27 @@
|
|||
|
||||
package io.element.android.features.roomdetails.impl.members.details
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.ChatBubbleOutline
|
||||
import androidx.compose.material.icons.outlined.Share
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.features.roomdetails.impl.blockuser.BlockUserDialogs
|
||||
import io.element.android.features.roomdetails.impl.blockuser.BlockUserSection
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||
import io.element.android.libraries.designsystem.components.button.MainActionButton
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceText
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.preview.LargeHeightPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight
|
||||
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
|
|
@ -103,45 +81,9 @@ fun RoomMemberDetailsView(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@Composable
|
||||
internal fun RoomMemberHeaderSection(
|
||||
avatarUrl: String?,
|
||||
userId: String,
|
||||
userName: String?,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Box(modifier = Modifier.size(70.dp)) {
|
||||
Avatar(
|
||||
avatarData = AvatarData(userId, userName, avatarUrl, AvatarSize.UserHeader),
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
if (userName != null) {
|
||||
Text(text = userName, style = ElementTheme.typography.fontHeadingLgBold)
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
}
|
||||
Text(
|
||||
text = userId,
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
Spacer(Modifier.height(40.dp))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun RoomMemberMainActionsSection(onShareUser: () -> Unit, modifier: Modifier = Modifier) {
|
||||
Row(modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
|
||||
MainActionButton(title = stringResource(CommonStrings.action_share), icon = Icons.Outlined.Share, onClick = onShareUser)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun SendMessageSection(onSendMessage: () -> Unit, modifier: Modifier = Modifier) {
|
||||
private fun SendMessageSection(onSendMessage: () -> Unit, modifier: Modifier = Modifier) {
|
||||
PreferenceCategory(modifier = modifier) {
|
||||
PreferenceText(
|
||||
title = stringResource(CommonStrings.action_send_message),
|
||||
|
|
@ -150,13 +92,14 @@ internal fun SendMessageSection(onSendMessage: () -> Unit, modifier: Modifier =
|
|||
)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@LargeHeightPreview
|
||||
@PreviewWithLargeHeight
|
||||
@Composable
|
||||
internal fun RoomMemberDetailsViewLightPreview(@PreviewParameter(RoomMemberDetailsStateProvider::class) state: RoomMemberDetailsState) =
|
||||
ElementPreviewLight { ContentToPreview(state) }
|
||||
|
||||
@LargeHeightPreview
|
||||
@PreviewWithLargeHeight
|
||||
@Composable
|
||||
internal fun RoomMemberDetailsViewDarkPreview(@PreviewParameter(RoomMemberDetailsStateProvider::class) state: RoomMemberDetailsState) =
|
||||
ElementPreviewDark { ContentToPreview(state) }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.features.roomdetails.impl.members.details
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
@Composable
|
||||
fun RoomMemberHeaderSection(
|
||||
avatarUrl: String?,
|
||||
userId: String,
|
||||
userName: String?,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Box(modifier = Modifier.size(70.dp)) {
|
||||
Avatar(
|
||||
avatarData = AvatarData(userId, userName, avatarUrl, AvatarSize.UserHeader),
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
if (userName != null) {
|
||||
Text(text = userName, style = ElementTheme.typography.fontHeadingLgBold)
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
}
|
||||
Text(
|
||||
text = userId,
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
Spacer(Modifier.height(40.dp))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.features.roomdetails.impl.members.details
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import io.element.android.libraries.designsystem.components.button.MainActionButton
|
||||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
fun RoomMemberMainActionsSection(onShareUser: () -> Unit, modifier: Modifier = Modifier) {
|
||||
Row(modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
|
||||
MainActionButton(
|
||||
title = stringResource(CommonStrings.action_share),
|
||||
iconResourceId = CommonDrawables.ic_compound_share_android,
|
||||
onClick = onShareUser
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.DayNightPreviews
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.theme.components.RadioButton
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
|
|
@ -77,7 +77,7 @@ fun RoomNotificationSettingsOption(
|
|||
}
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun RoomPrivacyOptionPreview() = ElementPreview {
|
||||
Column {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
|||
import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceText
|
||||
import io.element.android.libraries.designsystem.preview.DayNightPreviews
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.theme.aliasScreenTitle
|
||||
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||
|
|
@ -130,7 +130,7 @@ fun RoomNotificationSettingsView(
|
|||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun RoomNotificationSettingsTopBar(
|
||||
private fun RoomNotificationSettingsTopBar(
|
||||
modifier: Modifier = Modifier,
|
||||
onBackPressed: () -> Unit = {},
|
||||
) {
|
||||
|
|
@ -175,7 +175,7 @@ fun ShowChangeNotificationSettingError(state: RoomNotificationSettingsState, eve
|
|||
)
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun RoomNotificationSettingsPreview(
|
||||
@PreviewParameter(RoomNotificationSettingsStateProvider::class) state: RoomNotificationSettingsState
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M440,520Q457,520 468.5,508.5Q480,497 480,480Q480,463 468.5,451.5Q457,440 440,440Q423,440 411.5,451.5Q400,463 400,480Q400,497 411.5,508.5Q423,520 440,520ZM280,840L280,760L520,720Q520,720 520,720Q520,720 520,720L520,275Q520,260 511,248Q502,236 488,234L280,200L280,120L500,156Q544,164 572,197Q600,230 600,274L600,718Q600,747 581,769.5Q562,792 533,797L280,840ZM280,760L680,760L680,200Q680,200 680,200Q680,200 680,200L280,200Q280,200 280,200Q280,200 280,200L280,760ZM160,840Q143,840 131.5,828.5Q120,817 120,800Q120,783 131.5,771.5Q143,760 160,760L200,760L200,200Q200,166 223.5,143Q247,120 280,120L680,120Q714,120 737,143Q760,166 760,200L760,760L800,760Q817,760 828.5,771.5Q840,783 840,800Q840,817 828.5,828.5Q817,840 800,840L160,840Z"/>
|
||||
</vector>
|
||||
|
|
@ -45,7 +45,6 @@
|
|||
<string name="screen_dm_details_unblock_alert_description">"Znovu uvidíte všechny zprávy od nich."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Odblokovat uživatele"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Opustit místnost"</string>
|
||||
<string name="screen_room_details_people_title">"Lidé"</string>
|
||||
<string name="screen_room_details_security_title">"Zabezpečení"</string>
|
||||
<string name="screen_room_details_topic_title">"Téma"</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@
|
|||
<string name="screen_dm_details_unblock_alert_description">"Du kannst dann wieder alle Nachrichten von ihnen sehen."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Benutzer entsperren"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Raum verlassen"</string>
|
||||
<string name="screen_room_details_people_title">"Personen"</string>
|
||||
<string name="screen_room_details_security_title">"Sicherheit"</string>
|
||||
<string name="screen_room_details_topic_title">"Thema"</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
<string name="screen_dm_details_unblock_alert_description">"Al desbloquear al usuario, podrás volver a ver todos sus mensajes."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Desbloquear usuario"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Salir de la sala"</string>
|
||||
<string name="screen_room_details_people_title">"Personas"</string>
|
||||
<string name="screen_room_details_security_title">"Seguridad"</string>
|
||||
<string name="screen_room_details_topic_title">"Tema"</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@
|
|||
<string name="screen_dm_details_unblock_alert_description">"Vous pourrez à nouveau voir tous ses messages."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Débloquer l’utilisateur"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Quitter le salon"</string>
|
||||
<string name="screen_room_details_people_title">"Personnes"</string>
|
||||
<string name="screen_room_details_security_title">"Sécurité"</string>
|
||||
<string name="screen_room_details_topic_title">"Sujet"</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
<string name="screen_dm_details_unblock_alert_description">"Dopo aver sbloccato l\'utente, potrai vedere nuovamente tutti i suoi messaggi."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Sblocca utente"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Esci dalla stanza"</string>
|
||||
<string name="screen_room_details_people_title">"Persone"</string>
|
||||
<string name="screen_room_details_security_title">"Sicurezza"</string>
|
||||
<string name="screen_room_details_topic_title">"Oggetto"</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@
|
|||
<string name="screen_dm_details_unblock_alert_description">"La deblocarea utilizatorului, veți putea vedea din nou toate mesajele de la acesta."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Deblocați utilizatorul"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Părăsiți camera"</string>
|
||||
<string name="screen_room_details_people_title">"Persoane"</string>
|
||||
<string name="screen_room_details_security_title">"Securitate"</string>
|
||||
<string name="screen_room_details_topic_title">"Subiect"</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
<string name="screen_dm_details_unblock_alert_description">"Вы снова сможете увидеть все сообщения."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Разблокировать пользователя"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Покинуть комнату"</string>
|
||||
<string name="screen_room_details_people_title">"Пользователи"</string>
|
||||
<string name="screen_room_details_security_title">"Безопасность"</string>
|
||||
<string name="screen_room_details_topic_title">"Тема"</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
<string name="screen_dm_details_unblock_alert_description">"Všetky správy od nich budete môcť opäť vidieť."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Odblokovať používateľa"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Opustiť miestnosť"</string>
|
||||
<string name="screen_room_details_people_title">"Ľudia"</string>
|
||||
<string name="screen_room_details_security_title">"Bezpečnosť"</string>
|
||||
<string name="screen_room_details_topic_title">"Téma"</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@
|
|||
<string name="screen_room_details_edit_room_title">"編輯聊天室"</string>
|
||||
<string name="screen_room_details_edition_error_title">"無法更新聊天室"</string>
|
||||
<string name="screen_room_details_encryption_enabled_title">"訊息已加密"</string>
|
||||
<string name="screen_room_details_error_loading_notification_settings">"載入通知設定時發生錯誤。"</string>
|
||||
<string name="screen_room_details_error_muting">"無法關閉聊天室通知,請再試一次。"</string>
|
||||
<string name="screen_room_details_error_unmuting">"無法開啟聊天室通知,請再試一次。"</string>
|
||||
<string name="screen_room_details_invite_people_title">"邀請夥伴"</string>
|
||||
<string name="screen_room_details_notification_mode_custom">"自訂"</string>
|
||||
<string name="screen_room_details_notification_mode_default">"預設"</string>
|
||||
|
|
@ -23,12 +26,12 @@
|
|||
<string name="screen_room_notification_settings_error_restoring_default">"無法重設為預設模式,請再試一次。"</string>
|
||||
<string name="screen_room_notification_settings_error_setting_mode">"無法設定模式,請再試一次。"</string>
|
||||
<string name="screen_room_notification_settings_mode_all_messages">"所有訊息"</string>
|
||||
<string name="screen_room_notification_settings_mode_mentions_and_keywords">"只限提及與關鍵字"</string>
|
||||
<string name="screen_room_notification_settings_mode_mentions_and_keywords">"僅限提及與關鍵字"</string>
|
||||
<string name="screen_dm_details_block_alert_action">"封鎖"</string>
|
||||
<string name="screen_dm_details_block_user">"封鎖使用者"</string>
|
||||
<string name="screen_dm_details_unblock_alert_action">"解除封鎖"</string>
|
||||
<string name="screen_dm_details_unblock_user">"解除封鎖使用者"</string>
|
||||
<string name="screen_room_details_leave_room_title">"離開聊天室"</string>
|
||||
<string name="screen_room_details_people_title">"夥伴"</string>
|
||||
<string name="screen_room_details_security_title">"安全性"</string>
|
||||
<string name="screen_room_details_topic_title">"主題"</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@
|
|||
<string name="screen_dm_details_unblock_alert_description">"You\'ll be able to see all messages from them again."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Unblock user"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Leave room"</string>
|
||||
<string name="screen_room_details_people_title">"People"</string>
|
||||
<string name="screen_room_details_security_title">"Security"</string>
|
||||
<string name="screen_room_details_topic_title">"Topic"</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import app.cash.turbine.test
|
|||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomEvent
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomPresenter
|
||||
import io.element.android.features.leaveroom.fake.LeaveRoomPresenterFake
|
||||
import io.element.android.features.leaveroom.fake.FakeLeaveRoomPresenter
|
||||
import io.element.android.features.roomdetails.impl.RoomDetailsEvent
|
||||
import io.element.android.features.roomdetails.impl.RoomDetailsPresenter
|
||||
import io.element.android.features.roomdetails.impl.RoomDetailsType
|
||||
|
|
@ -59,9 +59,10 @@ class RoomDetailsPresenterTests {
|
|||
|
||||
@get:Rule
|
||||
val warmUpRule = WarmUpRule()
|
||||
private fun aRoomDetailsPresenter(
|
||||
|
||||
private fun createRoomDetailsPresenter(
|
||||
room: MatrixRoom,
|
||||
leaveRoomPresenter: LeaveRoomPresenter = LeaveRoomPresenterFake(),
|
||||
leaveRoomPresenter: LeaveRoomPresenter = FakeLeaveRoomPresenter(),
|
||||
dispatchers: CoroutineDispatchers,
|
||||
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService()
|
||||
): RoomDetailsPresenter {
|
||||
|
|
@ -88,7 +89,7 @@ class RoomDetailsPresenterTests {
|
|||
@Test
|
||||
fun `present - initial state is created from room info`() = runTest {
|
||||
val room = aMatrixRoom()
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -107,7 +108,7 @@ class RoomDetailsPresenterTests {
|
|||
@Test
|
||||
fun `present - initial state with no room name`() = runTest {
|
||||
val room = aMatrixRoom(name = null)
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -129,7 +130,7 @@ class RoomDetailsPresenterTests {
|
|||
val roomMembers = listOf(myRoomMember, otherRoomMember)
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
|
||||
}
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -145,7 +146,7 @@ class RoomDetailsPresenterTests {
|
|||
val room = aMatrixRoom().apply {
|
||||
givenCanInviteResult(Result.success(true))
|
||||
}
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -163,7 +164,7 @@ class RoomDetailsPresenterTests {
|
|||
val room = aMatrixRoom().apply {
|
||||
givenCanInviteResult(Result.success(false))
|
||||
}
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -178,7 +179,7 @@ class RoomDetailsPresenterTests {
|
|||
val room = aMatrixRoom().apply {
|
||||
givenCanInviteResult(Result.failure(Throwable("Whoops")))
|
||||
}
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -196,7 +197,7 @@ class RoomDetailsPresenterTests {
|
|||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.failure(Throwable("Whelp")))
|
||||
givenCanInviteResult(Result.success(false))
|
||||
}
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -225,7 +226,7 @@ class RoomDetailsPresenterTests {
|
|||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(true))
|
||||
givenCanInviteResult(Result.success(false))
|
||||
}
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -254,7 +255,7 @@ class RoomDetailsPresenterTests {
|
|||
|
||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
|
||||
}
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -275,7 +276,7 @@ class RoomDetailsPresenterTests {
|
|||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(true))
|
||||
givenCanInviteResult(Result.success(false))
|
||||
}
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -296,7 +297,7 @@ class RoomDetailsPresenterTests {
|
|||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(false))
|
||||
givenCanInviteResult(Result.success(false))
|
||||
}
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -314,7 +315,7 @@ class RoomDetailsPresenterTests {
|
|||
givenCanInviteResult(Result.success(false))
|
||||
}
|
||||
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -332,7 +333,7 @@ class RoomDetailsPresenterTests {
|
|||
givenCanInviteResult(Result.success(false))
|
||||
}
|
||||
|
||||
val presenter = aRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -348,9 +349,9 @@ class RoomDetailsPresenterTests {
|
|||
|
||||
@Test
|
||||
fun `present - leave room event is passed on to leave room presenter`() = runTest {
|
||||
val leaveRoomPresenter = LeaveRoomPresenterFake()
|
||||
val leaveRoomPresenter = FakeLeaveRoomPresenter()
|
||||
val room = aMatrixRoom()
|
||||
val presenter = aRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers())
|
||||
val presenter = createRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers())
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -364,10 +365,10 @@ class RoomDetailsPresenterTests {
|
|||
|
||||
@Test
|
||||
fun `present - notification mode changes`() = runTest {
|
||||
val leaveRoomPresenter = LeaveRoomPresenterFake()
|
||||
val leaveRoomPresenter = FakeLeaveRoomPresenter()
|
||||
val notificationSettingsService = FakeNotificationSettingsService()
|
||||
val room = aMatrixRoom(notificationSettingsService = notificationSettingsService)
|
||||
val presenter = aRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService)
|
||||
val presenter = createRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -383,10 +384,10 @@ class RoomDetailsPresenterTests {
|
|||
|
||||
@Test
|
||||
fun `present - mute room notifications`() = runTest {
|
||||
val leaveRoomPresenter = LeaveRoomPresenterFake()
|
||||
val leaveRoomPresenter = FakeLeaveRoomPresenter()
|
||||
val notificationSettingsService = FakeNotificationSettingsService(initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
|
||||
val room = aMatrixRoom(notificationSettingsService = notificationSettingsService)
|
||||
val presenter = aRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService)
|
||||
val presenter = createRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -401,13 +402,13 @@ class RoomDetailsPresenterTests {
|
|||
|
||||
@Test
|
||||
fun `present - unmute room notifications`() = runTest {
|
||||
val leaveRoomPresenter = LeaveRoomPresenterFake()
|
||||
val leaveRoomPresenter = FakeLeaveRoomPresenter()
|
||||
val notificationSettingsService = FakeNotificationSettingsService(
|
||||
initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
|
||||
initialEncryptedGroupDefaultMode = RoomNotificationMode.ALL_MESSAGES
|
||||
)
|
||||
val room = aMatrixRoom(notificationSettingsService = notificationSettingsService)
|
||||
val presenter = aRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService)
|
||||
val presenter = createRoomDetailsPresenter(room, leaveRoomPresenter, testCoroutineDispatchers(), notificationSettingsService)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ import io.element.android.libraries.matrix.ui.media.AvatarAction
|
|||
import io.element.android.libraries.mediapickers.test.FakePickerProvider
|
||||
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
|
||||
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||
import io.element.android.libraries.permissions.api.PermissionsPresenter
|
||||
import io.element.android.libraries.permissions.test.FakePermissionsPresenter
|
||||
import io.element.android.libraries.permissions.test.FakePermissionsPresenterFactory
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
|
|
@ -74,18 +77,22 @@ class RoomDetailsEditPresenterTest {
|
|||
unmockkAll()
|
||||
}
|
||||
|
||||
private fun aRoomDetailsEditPresenter(room: MatrixRoom): RoomDetailsEditPresenter {
|
||||
private fun createRoomDetailsEditPresenter(
|
||||
room: MatrixRoom,
|
||||
permissionsPresenter: PermissionsPresenter = FakePermissionsPresenter(),
|
||||
): RoomDetailsEditPresenter {
|
||||
return RoomDetailsEditPresenter(
|
||||
room = room,
|
||||
mediaPickerProvider = fakePickerProvider,
|
||||
mediaPreProcessor = fakeMediaPreProcessor,
|
||||
permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionsPresenter),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - initial state is created from room info`() = runTest {
|
||||
val room = aMatrixRoom(avatarUrl = AN_AVATAR_URL)
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -112,7 +119,7 @@ class RoomDetailsEditPresenterTest {
|
|||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(false))
|
||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.failure(Throwable("Oops")))
|
||||
}
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -138,7 +145,7 @@ class RoomDetailsEditPresenterTest {
|
|||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(true))
|
||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.failure(Throwable("Oops")))
|
||||
}
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -164,7 +171,7 @@ class RoomDetailsEditPresenterTest {
|
|||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.failure(Throwable("Oops")))
|
||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
|
||||
}
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -186,7 +193,7 @@ class RoomDetailsEditPresenterTest {
|
|||
@Test
|
||||
fun `present - updates state in response to changes`() = runTest {
|
||||
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -232,7 +239,7 @@ class RoomDetailsEditPresenterTest {
|
|||
|
||||
fakePickerProvider.givenResult(anotherAvatarUri)
|
||||
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -252,19 +259,31 @@ class RoomDetailsEditPresenterTest {
|
|||
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
|
||||
fakePickerProvider.givenResult(anotherAvatarUri)
|
||||
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val fakePermissionsPresenter = FakePermissionsPresenter()
|
||||
val presenter = createRoomDetailsEditPresenter(
|
||||
room = room,
|
||||
permissionsPresenter = fakePermissionsPresenter,
|
||||
)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.roomAvatarUrl).isEqualTo(roomAvatarUri)
|
||||
|
||||
assertThat(initialState.cameraPermissionState.permissionGranted).isFalse()
|
||||
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
||||
awaitItem().apply {
|
||||
assertThat(roomAvatarUrl).isEqualTo(anotherAvatarUri)
|
||||
}
|
||||
val stateWithAskingPermission = awaitItem()
|
||||
assertThat(stateWithAskingPermission.cameraPermissionState.showDialog).isTrue()
|
||||
fakePermissionsPresenter.setPermissionGranted()
|
||||
val stateWithPermission = awaitItem()
|
||||
assertThat(stateWithPermission.cameraPermissionState.permissionGranted).isTrue()
|
||||
val stateWithNewAvatar = awaitItem()
|
||||
assertThat(stateWithNewAvatar.roomAvatarUrl).isEqualTo(anotherAvatarUri)
|
||||
// Do it again, no permission is requested
|
||||
fakePickerProvider.givenResult(roomAvatarUri)
|
||||
stateWithNewAvatar.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
||||
val stateWithNewAvatar2 = awaitItem()
|
||||
assertThat(stateWithNewAvatar2.roomAvatarUrl).isEqualTo(roomAvatarUri)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -274,7 +293,7 @@ class RoomDetailsEditPresenterTest {
|
|||
|
||||
fakePickerProvider.givenResult(roomAvatarUri)
|
||||
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -326,7 +345,7 @@ class RoomDetailsEditPresenterTest {
|
|||
|
||||
fakePickerProvider.givenResult(roomAvatarUri)
|
||||
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -376,7 +395,7 @@ class RoomDetailsEditPresenterTest {
|
|||
fun `present - save changes room details if different`() = runTest {
|
||||
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -401,7 +420,7 @@ class RoomDetailsEditPresenterTest {
|
|||
fun `present - save doesn't change room details if they're the same trimmed`() = runTest {
|
||||
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -425,7 +444,7 @@ class RoomDetailsEditPresenterTest {
|
|||
fun `present - save doesn't change topic if it was unset and is now blank`() = runTest {
|
||||
val room = aMatrixRoom(topic = null, name = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -448,7 +467,7 @@ class RoomDetailsEditPresenterTest {
|
|||
fun `present - save doesn't change name if it's now empty`() = runTest {
|
||||
val room = aMatrixRoom(topic = "My topic", name = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -473,7 +492,7 @@ class RoomDetailsEditPresenterTest {
|
|||
|
||||
givenPickerReturnsFile()
|
||||
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -498,7 +517,7 @@ class RoomDetailsEditPresenterTest {
|
|||
fakePickerProvider.givenResult(anotherAvatarUri)
|
||||
fakeMediaPreProcessor.givenResult(Result.failure(Throwable("Oh no")))
|
||||
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -564,7 +583,7 @@ class RoomDetailsEditPresenterTest {
|
|||
givenSetTopicResult(Result.failure(Throwable("!")))
|
||||
}
|
||||
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -583,7 +602,7 @@ class RoomDetailsEditPresenterTest {
|
|||
}
|
||||
|
||||
private suspend fun saveAndAssertFailure(room: MatrixRoom, event: RoomDetailsEditEvents) {
|
||||
val presenter = aRoomDetailsEditPresenter(room)
|
||||
val presenter = createRoomDetailsEditPresenter(room)
|
||||
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue