mirror of
https://github.com/vector-im/riotX-android
synced 2025-10-05 15:52:47 +02:00
change (leave room) : warn on last admin when leaving rooms
This commit is contained in:
@@ -25,7 +25,6 @@ import com.airbnb.epoxy.OnModelBuildFinishedListener
|
||||
import com.airbnb.mvrx.args
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.LayoutManagerStateRestorer
|
||||
@@ -45,6 +44,7 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA
|
||||
import im.vector.app.features.home.room.list.widget.NotifsFabMenuView
|
||||
import im.vector.app.features.matrixto.OriginOfMatrixTo
|
||||
import im.vector.app.features.notifications.NotificationDrawerManager
|
||||
import im.vector.app.features.room.LeaveRoomPrompt
|
||||
import im.vector.lib.strings.CommonStrings
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
@@ -422,7 +422,7 @@ class RoomListFragment :
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleQuickActions(quickAction: RoomListQuickActionsSharedAction) {
|
||||
private suspend fun handleQuickActions(quickAction: RoomListQuickActionsSharedAction) {
|
||||
when (quickAction) {
|
||||
is RoomListQuickActionsSharedAction.NotificationsAllNoisy -> {
|
||||
roomListViewModel.handle(RoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY))
|
||||
@@ -451,26 +451,11 @@ class RoomListFragment :
|
||||
}
|
||||
}
|
||||
|
||||
private fun promptLeaveRoom(roomId: String) {
|
||||
val isPublicRoom = roomListViewModel.isPublicRoom(roomId)
|
||||
val message = buildString {
|
||||
append(getString(CommonStrings.room_participants_leave_prompt_msg))
|
||||
if (!isPublicRoom) {
|
||||
append("\n\n")
|
||||
append(getString(CommonStrings.room_participants_leave_private_warning))
|
||||
}
|
||||
private suspend fun promptLeaveRoom(roomId: String) {
|
||||
val warning = roomListViewModel.getLeaveRoomWarning(roomId)
|
||||
LeaveRoomPrompt.show(requireContext(), warning) {
|
||||
roomListViewModel.handle(RoomListAction.LeaveRoom(roomId))
|
||||
}
|
||||
MaterialAlertDialogBuilder(
|
||||
requireContext(),
|
||||
if (isPublicRoom) 0 else im.vector.lib.ui.styles.R.style.ThemeOverlay_Vector_MaterialAlertDialog_Destructive
|
||||
)
|
||||
.setTitle(CommonStrings.room_participants_leave_prompt_title)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(CommonStrings.action_leave) { _, _ ->
|
||||
roomListViewModel.handle(RoomListAction.LeaveRoom(roomId))
|
||||
}
|
||||
.setNegativeButton(CommonStrings.action_cancel, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(roomListViewModel) { state ->
|
||||
|
@@ -26,6 +26,8 @@ import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom
|
||||
import im.vector.app.features.analytics.plan.JoinedRoom
|
||||
import im.vector.app.features.displayname.getBestName
|
||||
import im.vector.app.features.invite.AutoAcceptInvites
|
||||
import im.vector.app.features.room.LeaveRoomPrompt
|
||||
import im.vector.app.features.room.getLeaveRoomWarning
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
@@ -41,7 +43,6 @@ import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
||||
import org.matrix.android.sdk.api.session.room.model.localecho.RoomLocalEcho
|
||||
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
|
||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
import org.matrix.android.sdk.api.session.room.state.isPublic
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import timber.log.Timber
|
||||
@@ -150,10 +151,11 @@ class RoomListViewModel @AssistedInject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun isPublicRoom(roomId: String): Boolean {
|
||||
return session.getRoom(roomId)?.stateService()?.isPublic().orFalse()
|
||||
suspend fun getLeaveRoomWarning(roomId: String): LeaveRoomPrompt.Warning {
|
||||
return session.getLeaveRoomWarning(roomId)
|
||||
}
|
||||
|
||||
|
||||
// PRIVATE METHODS *****************************************************************************
|
||||
|
||||
private fun handleSelectRoom(action: RoomListAction.SelectRoom) = withState {
|
||||
|
@@ -18,7 +18,6 @@ import androidx.recyclerview.widget.ConcatAdapter.Config.StableIdMode
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.airbnb.epoxy.OnModelBuildFinishedListener
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.core.epoxy.LayoutManagerStateRestorer
|
||||
import im.vector.app.core.extensions.cleanup
|
||||
@@ -36,7 +35,7 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA
|
||||
import im.vector.app.features.home.room.list.home.header.HomeRoomFilter
|
||||
import im.vector.app.features.home.room.list.home.header.HomeRoomsHeadersController
|
||||
import im.vector.app.features.home.room.list.home.invites.InvitesActivity
|
||||
import im.vector.lib.strings.CommonStrings
|
||||
import im.vector.app.features.room.LeaveRoomPrompt
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
@@ -103,7 +102,7 @@ class HomeRoomListFragment :
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleQuickActions(quickAction: RoomListQuickActionsSharedAction) {
|
||||
private suspend fun handleQuickActions(quickAction: RoomListQuickActionsSharedAction) {
|
||||
when (quickAction) {
|
||||
is RoomListQuickActionsSharedAction.NotificationsAllNoisy -> {
|
||||
roomListViewModel.handle(HomeRoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY))
|
||||
@@ -185,26 +184,11 @@ class HomeRoomListFragment :
|
||||
concatAdapter.addAdapter(roomsAdapter)
|
||||
}
|
||||
|
||||
private fun promptLeaveRoom(roomId: String) {
|
||||
val isPublicRoom = roomListViewModel.isPublicRoom(roomId)
|
||||
val message = buildString {
|
||||
append(getString(CommonStrings.room_participants_leave_prompt_msg))
|
||||
if (!isPublicRoom) {
|
||||
append("\n\n")
|
||||
append(getString(CommonStrings.room_participants_leave_private_warning))
|
||||
}
|
||||
private suspend fun promptLeaveRoom(roomId: String) {
|
||||
val warning = roomListViewModel.getLeaveRoomWarning(roomId)
|
||||
LeaveRoomPrompt.show(requireContext(), warning) {
|
||||
roomListViewModel.handle(HomeRoomListAction.LeaveRoom(roomId))
|
||||
}
|
||||
MaterialAlertDialogBuilder(
|
||||
requireContext(),
|
||||
if (isPublicRoom) 0 else im.vector.lib.ui.styles.R.style.ThemeOverlay_Vector_MaterialAlertDialog_Destructive
|
||||
)
|
||||
.setTitle(CommonStrings.room_participants_leave_prompt_title)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(CommonStrings.action_leave) { _, _ ->
|
||||
roomListViewModel.handle(HomeRoomListAction.LeaveRoom(roomId))
|
||||
}
|
||||
.setNegativeButton(CommonStrings.action_cancel, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun onInvitesCounterClicked() {
|
||||
|
@@ -26,6 +26,8 @@ import im.vector.app.features.analytics.extensions.toTrackingValue
|
||||
import im.vector.app.features.analytics.plan.UserProperties
|
||||
import im.vector.app.features.displayname.getBestName
|
||||
import im.vector.app.features.home.room.list.home.header.HomeRoomFilter
|
||||
import im.vector.app.features.room.LeaveRoomPrompt
|
||||
import im.vector.app.features.room.getLeaveRoomWarning
|
||||
import im.vector.lib.strings.CommonStrings
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@@ -331,8 +333,8 @@ class HomeRoomListViewModel @AssistedInject constructor(
|
||||
filteredPagedRoomSummariesLive.queryParams = getFilteredQueryParams(newFilter, filteredPagedRoomSummariesLive.queryParams)
|
||||
}
|
||||
|
||||
fun isPublicRoom(roomId: String): Boolean {
|
||||
return session.getRoom(roomId)?.stateService()?.isPublic().orFalse()
|
||||
suspend fun getLeaveRoomWarning(roomId: String): LeaveRoomPrompt.Warning {
|
||||
return session.getLeaveRoomWarning(roomId)
|
||||
}
|
||||
|
||||
private fun handleSelectRoom(action: HomeRoomListAction.SelectRoom) = withState {
|
||||
|
@@ -7,6 +7,37 @@
|
||||
|
||||
package im.vector.app.features.powerlevel
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.matrix.android.sdk.api.session.room.Room
|
||||
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.Role
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
|
||||
fun Role.isOwner() = this == Role.Creator || this == Role.SuperAdmin
|
||||
|
||||
fun Room.membersByRoleFlow(): Flow<Map<Role, List<RoomMemberSummary>>> {
|
||||
val roomMembersFlow = flow().liveRoomMembers(roomMemberQueryParams())
|
||||
val roomPowerLevelsFlow = PowerLevelsFlowFactory(this).createFlow()
|
||||
return combine(roomMembersFlow, roomPowerLevelsFlow) { roomMembers, roomPowerLevels ->
|
||||
roomMembers.groupBy { roomPowerLevels.getSuggestedRole(it.userId) }
|
||||
}.distinctUntilChanged()
|
||||
}
|
||||
|
||||
fun Room.isLastAdminFlow(userId: String): Flow<Boolean> {
|
||||
return membersByRoleFlow().map { membersByRole ->
|
||||
val creatorMembers = membersByRole[Role.Creator].orEmpty()
|
||||
val superAdminMembers = membersByRole[Role.SuperAdmin].orEmpty()
|
||||
val adminMembers = membersByRole[Role.Admin].orEmpty()
|
||||
val joinedAdmins = (adminMembers + creatorMembers + superAdminMembers).filter { it.membership == Membership.JOIN }
|
||||
if (joinedAdmins.size == 1) {
|
||||
joinedAdmins.first().userId == userId
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package im.vector.app.features.room
|
||||
|
||||
import android.content.Context
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import im.vector.app.features.powerlevel.isLastAdminFlow
|
||||
import im.vector.app.features.room.LeaveRoomPrompt.Warning
|
||||
import im.vector.lib.strings.CommonStrings
|
||||
import im.vector.lib.ui.styles.R
|
||||
import kotlinx.coroutines.flow.first
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.getRoom
|
||||
import org.matrix.android.sdk.api.session.room.state.isPublic
|
||||
|
||||
object LeaveRoomPrompt {
|
||||
|
||||
enum class Warning {
|
||||
LAST_ADMIN,
|
||||
PRIVATE_ROOM,
|
||||
NONE
|
||||
};
|
||||
|
||||
fun show(
|
||||
context: Context,
|
||||
warning: Warning,
|
||||
onLeaveClick: () -> Unit
|
||||
) {
|
||||
val hasWarning = warning != Warning.NONE
|
||||
val message = buildString {
|
||||
append(context.getString(CommonStrings.room_participants_leave_prompt_msg))
|
||||
if (hasWarning) append("\n\n")
|
||||
when (warning) {
|
||||
Warning.LAST_ADMIN -> append(context.getString(CommonStrings.room_participants_leave_last_admin))
|
||||
Warning.PRIVATE_ROOM -> append(context.getString(CommonStrings.room_participants_leave_private_warning))
|
||||
Warning.NONE -> Unit
|
||||
}
|
||||
}
|
||||
MaterialAlertDialogBuilder(
|
||||
context,
|
||||
if (hasWarning) R.style.ThemeOverlay_Vector_MaterialAlertDialog_Destructive else 0
|
||||
)
|
||||
.setTitle(CommonStrings.room_participants_leave_prompt_title)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(CommonStrings.action_leave) { _, _ ->
|
||||
onLeaveClick()
|
||||
}
|
||||
.setNegativeButton(CommonStrings.action_cancel, null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun Session.getLeaveRoomWarning(roomId: String): Warning {
|
||||
val room = getRoom(roomId) ?: return Warning.NONE
|
||||
val isLastAdmin = room.isLastAdminFlow(myUserId).first()
|
||||
return when {
|
||||
isLastAdmin -> Warning.LAST_ADMIN
|
||||
!room.stateService().isPublic() -> Warning.PRIVATE_ROOM
|
||||
else -> Warning.NONE
|
||||
}
|
||||
}
|
||||
|
@@ -45,6 +45,7 @@ import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet
|
||||
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction
|
||||
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel
|
||||
import im.vector.app.features.navigation.SettingsActivityPayload
|
||||
import im.vector.app.features.room.LeaveRoomPrompt
|
||||
import im.vector.lib.strings.CommonStrings
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@@ -320,25 +321,16 @@ class RoomProfileFragment :
|
||||
}
|
||||
|
||||
override fun onLeaveRoomClicked() {
|
||||
val isPublicRoom = roomProfileViewModel.isPublicRoom()
|
||||
val message = buildString {
|
||||
append(getString(CommonStrings.room_participants_leave_prompt_msg))
|
||||
if (!isPublicRoom) {
|
||||
append("\n\n")
|
||||
append(getString(CommonStrings.room_participants_leave_private_warning))
|
||||
withState(roomProfileViewModel){ state ->
|
||||
val warning = when {
|
||||
state.isLastAdmin -> LeaveRoomPrompt.Warning.LAST_ADMIN
|
||||
state.roomSummary()?.isPublic == false -> LeaveRoomPrompt.Warning.PRIVATE_ROOM
|
||||
else -> LeaveRoomPrompt.Warning.NONE
|
||||
}
|
||||
LeaveRoomPrompt.show(requireContext(), warning){
|
||||
roomProfileViewModel.handle(RoomProfileAction.LeaveRoom)
|
||||
}
|
||||
}
|
||||
MaterialAlertDialogBuilder(
|
||||
requireContext(),
|
||||
if (isPublicRoom) 0 else im.vector.lib.ui.styles.R.style.ThemeOverlay_Vector_MaterialAlertDialog_Destructive
|
||||
)
|
||||
.setTitle(CommonStrings.room_participants_leave_prompt_title)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(CommonStrings.action_leave) { _, _ ->
|
||||
roomProfileViewModel.handle(RoomProfileAction.LeaveRoom)
|
||||
}
|
||||
.setNegativeButton(CommonStrings.action_cancel, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onRoomAliasesClicked() {
|
||||
|
@@ -20,6 +20,7 @@ import im.vector.app.features.analytics.AnalyticsTracker
|
||||
import im.vector.app.features.analytics.plan.Interaction
|
||||
import im.vector.app.features.home.ShortcutCreator
|
||||
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
|
||||
import im.vector.app.features.powerlevel.isLastAdminFlow
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import im.vector.lib.strings.CommonStrings
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -72,6 +73,14 @@ class RoomProfileViewModel @AssistedInject constructor(
|
||||
observePermissions()
|
||||
observePowerLevels()
|
||||
observeCryptoSettings(flowRoom)
|
||||
observeIsLastAdmin()
|
||||
}
|
||||
|
||||
private fun observeIsLastAdmin() {
|
||||
room.isLastAdminFlow(session.myUserId)
|
||||
.onEach { isLastAdmin ->
|
||||
setState { copy(isLastAdmin = isLastAdmin) }
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
private fun observeCryptoSettings(flowRoom: FlowRoom) {
|
||||
|
@@ -30,6 +30,7 @@ data class RoomProfileViewState(
|
||||
val encryptToVerifiedDeviceOnly: Async<Boolean> = Uninitialized,
|
||||
val globalCryptoConfig: Async<GlobalCryptoConfig> = Uninitialized,
|
||||
val unverifiedDevicesInTheRoom: Async<Boolean> = Uninitialized,
|
||||
val isLastAdmin: Boolean = false
|
||||
) : MavericksState {
|
||||
|
||||
constructor(args: RoomProfileArgs) : this(roomId = args.roomId)
|
||||
|
@@ -21,7 +21,7 @@ data class SpaceLeaveAdvanceViewState(
|
||||
val currentFilter: String = "",
|
||||
val leaveState: Async<Unit> = Uninitialized,
|
||||
val isFilteringEnabled: Boolean = false,
|
||||
val isLastOwner: Boolean = false
|
||||
val isLastAdmin: Boolean = false
|
||||
) : MavericksState {
|
||||
|
||||
constructor(args: SpaceBottomSheetSettingsArgs) : this(
|
||||
|
@@ -50,27 +50,12 @@ class SpaceLeaveAdvancedFragment :
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
controller.listener = this
|
||||
|
||||
withState(viewModel) { state ->
|
||||
setupToolbar(views.toolbar)
|
||||
.setSubtitle(state.spaceSummary?.name)
|
||||
.allowBack()
|
||||
|
||||
state.spaceSummary?.let { summary ->
|
||||
val warningMessage: CharSequence? = when {
|
||||
summary.otherMemberIds.isEmpty() -> getString(CommonStrings.space_leave_prompt_msg_only_you)
|
||||
state.isLastOwner -> getString(CommonStrings.space_leave_prompt_msg_as_admin)
|
||||
!summary.isPublic -> getString(CommonStrings.space_leave_prompt_msg_private)
|
||||
else -> null
|
||||
}
|
||||
|
||||
views.spaceLeavePromptDescription.isVisible = warningMessage != null
|
||||
views.spaceLeavePromptDescription.text = warningMessage
|
||||
}
|
||||
|
||||
views.spaceLeavePromptTitle.text = getString(CommonStrings.space_leave_prompt_msg_with_name, state.spaceSummary?.name ?: "")
|
||||
}
|
||||
|
||||
views.roomList.configureWith(controller)
|
||||
@@ -107,6 +92,19 @@ class SpaceLeaveAdvancedFragment :
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
super.invalidate()
|
||||
|
||||
state.spaceSummary?.let { summary ->
|
||||
val warningMessage: CharSequence? = when {
|
||||
summary.otherMemberIds.isEmpty() -> getString(CommonStrings.space_leave_prompt_msg_only_you)
|
||||
state.isLastAdmin -> getString(CommonStrings.space_leave_prompt_msg_as_admin)
|
||||
!summary.isPublic -> getString(CommonStrings.space_leave_prompt_msg_private)
|
||||
else -> null
|
||||
}
|
||||
views.spaceLeavePromptDescription.isVisible = warningMessage != null
|
||||
views.spaceLeavePromptDescription.text = warningMessage
|
||||
}
|
||||
|
||||
views.spaceLeavePromptTitle.text = getString(CommonStrings.space_leave_prompt_msg_with_name, state.spaceSummary?.name ?: "")
|
||||
|
||||
if (state.isFilteringEnabled) {
|
||||
views.appBarLayout.setExpanded(false)
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||
import im.vector.app.core.platform.EmptyViewEvents
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.features.powerlevel.isOwner
|
||||
import im.vector.app.features.powerlevel.isLastAdminFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -29,7 +29,6 @@ import org.matrix.android.sdk.api.query.RoomCategoryFilter
|
||||
import org.matrix.android.sdk.api.query.SpaceFilter
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.getRoom
|
||||
import org.matrix.android.sdk.api.session.room.getRoomPowerLevels
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
@@ -44,20 +43,13 @@ class SpaceLeaveAdvancedViewModel @AssistedInject constructor(
|
||||
|
||||
init {
|
||||
val space = session.getRoom(initialState.spaceId)
|
||||
val spaceSummary = space?.roomSummary()
|
||||
val roomPowerLevels = space?.getRoomPowerLevels()
|
||||
roomPowerLevels?.let {
|
||||
val isOwner = roomPowerLevels.getSuggestedRole(session.myUserId).isOwner()
|
||||
val otherOwnersCount = spaceSummary?.otherMemberIds
|
||||
?.map { roomPowerLevels.getSuggestedRole(it) }
|
||||
?.count { it.isOwner() }
|
||||
?: 0
|
||||
val isLastOwner = isOwner && otherOwnersCount == 0
|
||||
setState {
|
||||
copy(isLastOwner = isLastOwner)
|
||||
}
|
||||
}
|
||||
|
||||
space?.isLastAdminFlow(session.myUserId)
|
||||
?.onEach { isLastAdmin ->
|
||||
setState { copy(isLastAdmin = isLastAdmin) }
|
||||
}?.launchIn(viewModelScope)
|
||||
|
||||
val spaceSummary = space?.roomSummary()
|
||||
setState { copy(spaceSummary = spaceSummary) }
|
||||
session.getRoom(initialState.spaceId)
|
||||
?.flow()
|
||||
|
Reference in New Issue
Block a user