mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-12-22 23:58:47 +01:00
Improve leave space (all + none)
This commit is contained in:
parent
bb459a6e5e
commit
8fd784e275
@ -162,7 +162,7 @@ Formatter\.formatShortFileSize===1
|
||||
# android\.text\.TextUtils
|
||||
|
||||
### This is not a rule, but a warning: the number of "enum class" has changed. For Json classes, it is mandatory that they have `@JsonClass(generateAdapter = false)`. If the enum is not used as a Json class, change the value in file forbidden_strings_in_code.txt
|
||||
enum class===105
|
||||
enum class===106
|
||||
|
||||
### Do not import temporary legacy classes
|
||||
import org.matrix.android.sdk.internal.legacy.riot===3
|
||||
|
@ -84,6 +84,7 @@ import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheet
|
||||
import im.vector.app.features.share.IncomingShareActivity
|
||||
import im.vector.app.features.signout.soft.SoftLogoutActivity
|
||||
import im.vector.app.features.spaces.InviteRoomSpaceChooserBottomSheet
|
||||
import im.vector.app.features.spaces.LeaveSpaceBottomSheet
|
||||
import im.vector.app.features.spaces.SpaceCreationActivity
|
||||
import im.vector.app.features.spaces.SpaceExploreActivity
|
||||
import im.vector.app.features.spaces.SpaceSettingsMenuBottomSheet
|
||||
@ -199,6 +200,7 @@ interface ScreenComponent {
|
||||
fun inject(bottomSheet: SpaceInviteBottomSheet)
|
||||
fun inject(bottomSheet: JoinReplacementRoomBottomSheet)
|
||||
fun inject(bottomSheet: MigrateRoomBottomSheet)
|
||||
fun inject(bottomSheet: LeaveSpaceBottomSheet)
|
||||
|
||||
/* ==========================================================================================
|
||||
* Others
|
||||
|
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 im.vector.app.features.spaces
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.text.toSpannable
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.Loading
|
||||
import com.airbnb.mvrx.args
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import com.jakewharton.rxbinding3.widget.checkedChanges
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.utils.styleMatchingText
|
||||
import im.vector.app.databinding.BottomSheetLeaveSpaceBinding
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import me.gujun.android.span.span
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import javax.inject.Inject
|
||||
|
||||
class LeaveSpaceBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetLeaveSpaceBinding>() {
|
||||
|
||||
val settingsViewModel: SpaceMenuViewModel by parentFragmentViewModel()
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetLeaveSpaceBinding {
|
||||
return BottomSheetLeaveSpaceBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
@Inject lateinit var colorProvider: ColorProvider
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class Args(
|
||||
val spaceId: String
|
||||
) : Parcelable
|
||||
|
||||
override val showExpanded = true
|
||||
|
||||
private val spaceArgs: SpaceBottomSheetSettingsArgs by args()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
views.autoLeaveRadioGroup.checkedChanges()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
when (it) {
|
||||
views.leaveAll.id -> {
|
||||
settingsViewModel.handle(SpaceMenuViewAction.SetAutoLeaveAll)
|
||||
}
|
||||
views.leaveNone.id -> {
|
||||
settingsViewModel.handle(SpaceMenuViewAction.SetAutoLeaveNone)
|
||||
}
|
||||
views.leaveSelected.id -> {
|
||||
settingsViewModel.handle(SpaceMenuViewAction.SetAutoLeaveSelected)
|
||||
}
|
||||
}
|
||||
}
|
||||
.disposeOnDestroyView()
|
||||
|
||||
views.leaveButton.debouncedClicks {
|
||||
settingsViewModel.handle(SpaceMenuViewAction.LeaveSpace)
|
||||
}
|
||||
|
||||
views.cancelButton.debouncedClicks {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(settingsViewModel) { state ->
|
||||
super.invalidate()
|
||||
|
||||
val spaceSummary = state.spaceSummary ?: return@withState
|
||||
val bestName = spaceSummary.toMatrixItem().getBestName()
|
||||
val commonText = getString(R.string.space_leave_prompt_msg, bestName)
|
||||
.toSpannable().styleMatchingText(bestName, Typeface.BOLD)
|
||||
|
||||
val warningMessage: CharSequence = if (spaceSummary.otherMemberIds.isEmpty()) {
|
||||
span {
|
||||
+commonText
|
||||
+"\n\n"
|
||||
span(getString(R.string.space_leave_prompt_msg_only_you)) {
|
||||
textColor = colorProvider.getColorFromAttribute(R.attr.colorError)
|
||||
}
|
||||
}
|
||||
} else if (state.isLastAdmin) {
|
||||
span {
|
||||
+commonText
|
||||
+"\n\n"
|
||||
span(getString(R.string.space_leave_prompt_msg_as_admin)) {
|
||||
textColor = colorProvider.getColorFromAttribute(R.attr.colorError)
|
||||
}
|
||||
}
|
||||
} else if (!spaceSummary.isPublic) {
|
||||
span {
|
||||
+commonText
|
||||
+"\n\n"
|
||||
span(getString(R.string.space_leave_prompt_msg_private)) {
|
||||
textColor = colorProvider.getColorFromAttribute(R.attr.colorError)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
commonText
|
||||
}
|
||||
|
||||
views.bottomLeaveSpaceWarningText.setTextOrHide(warningMessage)
|
||||
|
||||
if (state.leavingState is Loading) {
|
||||
views.leaveButton.isInvisible = true
|
||||
views.cancelButton.isInvisible = true
|
||||
views.leaveProgress.isVisible = true
|
||||
} else {
|
||||
views.leaveButton.isInvisible = false
|
||||
views.cancelButton.isInvisible = false
|
||||
views.leaveProgress.isVisible = false
|
||||
}
|
||||
|
||||
when (state.leaveMode) {
|
||||
SpaceMenuState.LeaveMode.LEAVE_ALL -> {
|
||||
views.autoLeaveRadioGroup.check(views.leaveAll.id)
|
||||
}
|
||||
SpaceMenuState.LeaveMode.LEAVE_NONE -> {
|
||||
views.autoLeaveRadioGroup.check(views.leaveNone.id)
|
||||
}
|
||||
SpaceMenuState.LeaveMode.LEAVE_SELECTED -> {
|
||||
views.autoLeaveRadioGroup.check(views.leaveSelected.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(spaceId: String)
|
||||
: LeaveSpaceBottomSheet {
|
||||
return LeaveSpaceBottomSheet().apply {
|
||||
setArguments(SpaceBottomSheetSettingsArgs(spaceId))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 im.vector.app.features.spaces
|
||||
|
||||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.MvRxState
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
|
||||
data class SpaceMenuState(
|
||||
val spaceId: String,
|
||||
val spaceSummary: RoomSummary? = null,
|
||||
val canEditSettings: Boolean = false,
|
||||
val canInvite: Boolean = false,
|
||||
val canAddChild: Boolean = false,
|
||||
val isLastAdmin: Boolean = false,
|
||||
val leaveMode: LeaveMode = LeaveMode.LEAVE_ALL,
|
||||
val leavingState: Async<Unit> = Uninitialized
|
||||
) : MvRxState {
|
||||
constructor(args: SpaceBottomSheetSettingsArgs) : this(spaceId = args.spaceId)
|
||||
|
||||
enum class LeaveMode {
|
||||
LEAVE_ALL, LEAVE_NONE, LEAVE_SELECTED
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 im.vector.app.features.spaces
|
||||
|
||||
import im.vector.app.core.platform.VectorViewModelAction
|
||||
|
||||
sealed class SpaceMenuViewAction : VectorViewModelAction {
|
||||
object SetAutoLeaveAll : SpaceMenuViewAction()
|
||||
object SetAutoLeaveNone : SpaceMenuViewAction()
|
||||
object SetAutoLeaveSelected : SpaceMenuViewAction()
|
||||
object LeaveSpace : SpaceMenuViewAction()
|
||||
}
|
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 im.vector.app.features.spaces
|
||||
|
||||
import com.airbnb.mvrx.ActivityViewModelContext
|
||||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
import com.airbnb.mvrx.Loading
|
||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import im.vector.app.AppStateHandler
|
||||
import im.vector.app.core.platform.EmptyViewEvents
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.query.ActiveSpaceFilter
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.Role
|
||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import timber.log.Timber
|
||||
|
||||
class SpaceMenuViewModel @AssistedInject constructor(
|
||||
@Assisted val initialState: SpaceMenuState,
|
||||
val session: Session,
|
||||
val appStateHandler: AppStateHandler
|
||||
) : VectorViewModel<SpaceMenuState, SpaceMenuViewAction, EmptyViewEvents>(initialState) {
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(initialState: SpaceMenuState): SpaceMenuViewModel
|
||||
}
|
||||
|
||||
companion object : MvRxViewModelFactory<SpaceMenuViewModel, SpaceMenuState> {
|
||||
|
||||
@JvmStatic
|
||||
override fun create(viewModelContext: ViewModelContext, state: SpaceMenuState): SpaceMenuViewModel? {
|
||||
val factory = when (viewModelContext) {
|
||||
is FragmentViewModelContext -> viewModelContext.fragment as? Factory
|
||||
is ActivityViewModelContext -> viewModelContext.activity as? Factory
|
||||
}
|
||||
return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface")
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
val roomSummary = session.getRoomSummary(initialState.spaceId)
|
||||
|
||||
setState {
|
||||
copy(spaceSummary = roomSummary)
|
||||
}
|
||||
|
||||
session.getRoom(initialState.spaceId)?.let { room ->
|
||||
|
||||
room.rx().liveRoomSummary().subscribe {
|
||||
it.getOrNull()?.let {
|
||||
if (it.membership == Membership.LEAVE) {
|
||||
setState { copy(leavingState = Success(Unit)) }
|
||||
// switch to home?
|
||||
appStateHandler.setCurrentSpace(null, session)
|
||||
}
|
||||
}
|
||||
}
|
||||
PowerLevelsObservableFactory(room)
|
||||
.createObservable()
|
||||
.subscribe {
|
||||
val powerLevelsHelper = PowerLevelsHelper(it)
|
||||
|
||||
val canInvite = powerLevelsHelper.isUserAbleToInvite(session.myUserId)
|
||||
val canAddChild = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_SPACE_CHILD)
|
||||
|
||||
val canChangeAvatar = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR)
|
||||
val canChangeName = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_NAME)
|
||||
val canChangeTopic = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_TOPIC)
|
||||
|
||||
val isAdmin = powerLevelsHelper.getUserRole(session.myUserId) is Role.Admin
|
||||
val otherAdminCount = roomSummary?.otherMemberIds
|
||||
?.map { powerLevelsHelper.getUserRole(it) }
|
||||
?.count { it is Role.Admin }
|
||||
?: 0
|
||||
val isLastAdmin = isAdmin && otherAdminCount == 0
|
||||
|
||||
setState {
|
||||
copy(
|
||||
canEditSettings = canChangeAvatar || canChangeName || canChangeTopic,
|
||||
canInvite = canInvite,
|
||||
canAddChild = canAddChild,
|
||||
isLastAdmin = isLastAdmin
|
||||
)
|
||||
}
|
||||
}
|
||||
.disposeOnClear()
|
||||
}
|
||||
}
|
||||
|
||||
override fun handle(action: SpaceMenuViewAction) {
|
||||
when (action) {
|
||||
SpaceMenuViewAction.SetAutoLeaveAll -> setState { copy(leaveMode = SpaceMenuState.LeaveMode.LEAVE_ALL) }
|
||||
SpaceMenuViewAction.SetAutoLeaveNone -> setState { copy(leaveMode = SpaceMenuState.LeaveMode.LEAVE_NONE) }
|
||||
SpaceMenuViewAction.SetAutoLeaveSelected -> setState { copy(leaveMode = SpaceMenuState.LeaveMode.LEAVE_SELECTED) }
|
||||
SpaceMenuViewAction.LeaveSpace -> handleLeaveSpace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleLeaveSpace() = withState { state ->
|
||||
|
||||
setState { copy(leavingState = Loading()) }
|
||||
|
||||
session.coroutineScope.launch {
|
||||
try {
|
||||
if (state.leaveMode == SpaceMenuState.LeaveMode.LEAVE_NONE) {
|
||||
session.getRoom(initialState.spaceId)?.leave(null)
|
||||
} else if (state.leaveMode == SpaceMenuState.LeaveMode.LEAVE_ALL) {
|
||||
// need to find all child rooms that i have joined
|
||||
try {
|
||||
session.getRoomSummaries(
|
||||
roomSummaryQueryParams {
|
||||
excludeType = null
|
||||
activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(initialState.spaceId)
|
||||
memberships = listOf(Membership.JOIN)
|
||||
}
|
||||
).forEach {
|
||||
session.getRoom(it.roomId)?.leave(null)
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
// silently ignore?
|
||||
Timber.e(failure, "Fail to leave sub rooms/spaces")
|
||||
}
|
||||
session.getRoom(initialState.spaceId)?.leave(null)
|
||||
}
|
||||
|
||||
// We observe the membership and to dismiss when we have remote echo of leaving
|
||||
} catch (failure: Throwable) {
|
||||
setState { copy(leavingState = Fail(failure)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -22,35 +22,24 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.args
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.databinding.BottomSheetSpaceSettingsBinding
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.navigation.Navigator
|
||||
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
||||
import im.vector.app.features.rageshake.BugReporter
|
||||
import im.vector.app.features.rageshake.ReportType
|
||||
import im.vector.app.features.roomprofile.RoomProfileActivity
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.features.spaces.manage.ManageType
|
||||
import im.vector.app.features.spaces.manage.SpaceManageActivity
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import me.gujun.android.span.span
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.Role
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@Parcelize
|
||||
@ -58,15 +47,12 @@ data class SpaceBottomSheetSettingsArgs(
|
||||
val spaceId: String
|
||||
) : Parcelable
|
||||
|
||||
// XXX make proper view model before leaving beta
|
||||
class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetSpaceSettingsBinding>() {
|
||||
class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetSpaceSettingsBinding>(), SpaceMenuViewModel.Factory {
|
||||
|
||||
@Inject lateinit var navigator: Navigator
|
||||
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
||||
@Inject lateinit var avatarRenderer: AvatarRenderer
|
||||
@Inject lateinit var vectorPreferences: VectorPreferences
|
||||
@Inject lateinit var bugReporter: BugReporter
|
||||
@Inject lateinit var colorProvider: ColorProvider
|
||||
@Inject lateinit var viewModelFactory: SpaceMenuViewModel.Factory
|
||||
|
||||
private val spaceArgs: SpaceBottomSheetSettingsArgs by args()
|
||||
|
||||
@ -74,6 +60,8 @@ class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment<BottomS
|
||||
fun onShareSpaceSelected(spaceId: String)
|
||||
}
|
||||
|
||||
val settingsViewModel: SpaceMenuViewModel by fragmentViewModel()
|
||||
|
||||
var interactionListener: InteractionListener? = null
|
||||
|
||||
override val showExpanded = true
|
||||
@ -91,41 +79,6 @@ class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment<BottomS
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||
val roomSummary = session.getRoomSummary(spaceArgs.spaceId)
|
||||
roomSummary?.toMatrixItem()?.let {
|
||||
avatarRenderer.render(it, views.spaceAvatarImageView)
|
||||
}
|
||||
views.spaceNameView.text = roomSummary?.displayName
|
||||
views.spaceDescription.setTextOrHide(roomSummary?.topic?.takeIf { it.isNotEmpty() })
|
||||
|
||||
val room = session.getRoom(spaceArgs.spaceId) ?: return
|
||||
|
||||
PowerLevelsObservableFactory(room)
|
||||
.createObservable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { powerLevelContent ->
|
||||
val powerLevelsHelper = PowerLevelsHelper(powerLevelContent)
|
||||
val canInvite = powerLevelsHelper.isUserAbleToInvite(session.myUserId)
|
||||
val canAddChild = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_SPACE_CHILD)
|
||||
|
||||
val canChangeAvatar = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR)
|
||||
val canChangeName = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_NAME)
|
||||
val canChangeTopic = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_TOPIC)
|
||||
|
||||
views.spaceSettings.isVisible = canChangeAvatar || canChangeName || canChangeTopic
|
||||
|
||||
views.invitePeople.isVisible = canInvite || roomSummary?.isPublic.orFalse()
|
||||
views.addRooms.isVisible = canAddChild
|
||||
|
||||
val isAdmin = powerLevelsHelper.getUserRole(session.myUserId) is Role.Admin
|
||||
val otherAdminCount = roomSummary?.otherMemberIds
|
||||
?.map { powerLevelsHelper.getUserRole(it) }
|
||||
?.count { it is Role.Admin }
|
||||
?: 0
|
||||
isLastAdmin = isAdmin && otherAdminCount == 0
|
||||
}.disposeOnDestroyView()
|
||||
|
||||
views.spaceBetaTag.debouncedClicks {
|
||||
bugReporter.openBugReportScreen(requireActivity(), ReportType.SPACE_BETA_FEEDBACK)
|
||||
}
|
||||
@ -154,42 +107,29 @@ class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment<BottomS
|
||||
}
|
||||
|
||||
views.leaveSpace.views.bottomSheetActionClickableZone.debouncedClicks {
|
||||
val spaceSummary = activeSessionHolder.getSafeActiveSession()?.getRoomSummary(spaceArgs.spaceId)
|
||||
?: return@debouncedClicks
|
||||
val warningMessage: CharSequence? = if (spaceSummary.otherMemberIds.isEmpty()) {
|
||||
span(getString(R.string.space_leave_prompt_msg_only_you)) {
|
||||
textColor = colorProvider.getColorFromAttribute(R.attr.colorError)
|
||||
}
|
||||
} else if (isLastAdmin) {
|
||||
span(getString(R.string.space_leave_prompt_msg_as_admin)) {
|
||||
textColor = colorProvider.getColorFromAttribute(R.attr.colorError)
|
||||
}
|
||||
} else if (!spaceSummary.isPublic) {
|
||||
span(getString(R.string.space_leave_prompt_msg_private)) {
|
||||
textColor = colorProvider.getColorFromAttribute(R.attr.colorError)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
MaterialAlertDialogBuilder(requireContext(), R.style.ThemeOverlay_Vector_MaterialAlertDialog_Destructive)
|
||||
.setMessage(warningMessage)
|
||||
.setTitle(getString(R.string.space_leave_prompt_msg))
|
||||
.setPositiveButton(R.string.leave) { _, _ ->
|
||||
session.coroutineScope.launch {
|
||||
try {
|
||||
session.getRoom(spaceArgs.spaceId)?.leave(null)
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e(failure, "Failed to leave space")
|
||||
}
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show()
|
||||
LeaveSpaceBottomSheet.newInstance(spaceArgs.spaceId).show(childFragmentManager, "LOGOUT")
|
||||
}
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(settingsViewModel) { state ->
|
||||
super.invalidate()
|
||||
|
||||
if (state.leavingState is Success) {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
state.spaceSummary?.toMatrixItem()?.let {
|
||||
avatarRenderer.render(it, views.spaceAvatarImageView)
|
||||
}
|
||||
views.spaceNameView.text = state.spaceSummary?.displayName
|
||||
views.spaceDescription.setTextOrHide(state.spaceSummary?.topic?.takeIf { it.isNotEmpty() })
|
||||
|
||||
views.spaceSettings.isVisible = state.canEditSettings
|
||||
|
||||
views.invitePeople.isVisible = state.canInvite || state.spaceSummary?.isPublic.orFalse()
|
||||
views.addRooms.isVisible = state.canAddChild
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(spaceId: String, interactionListener: InteractionListener): SpaceSettingsMenuBottomSheet {
|
||||
return SpaceSettingsMenuBottomSheet().apply {
|
||||
@ -198,4 +138,8 @@ class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment<BottomS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun create(initialState: SpaceMenuState): SpaceMenuViewModel {
|
||||
return viewModelFactory.create(initialState)
|
||||
}
|
||||
}
|
||||
|
105
vector/src/main/res/layout/bottom_sheet_leave_space.xml
Normal file
105
vector/src/main/res/layout/bottom_sheet_leave_space.xml
Normal file
@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorSurface"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_leave_space_warning_text"
|
||||
style="@style/Widget.Vector.TextView.Subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:textColor="?vctr_content_primary"
|
||||
tools:text="@string/space_leave_prompt_msg" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/autoLeaveRadioGroup"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="?dialogPreferredPadding"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingEnd="?dialogPreferredPadding"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/leave_all"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/leave_all_rooms_and_spaces"
|
||||
tools:checked="true" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/leave_none"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="180dp"
|
||||
android:text="@string/dont_leave_any" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/leave_selected"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="180dp"
|
||||
android:text="@string/leave_specific_ones" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/inlineErrorText"
|
||||
style="@style/Widget.Vector.TextView.Body"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||
android:textColor="?vctr_content_secondary"
|
||||
android:visibility="gone" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="16dp">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/leaveProgress"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/leaveButton"
|
||||
style="@style/Widget.Vector.Button.Destructive"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/leave_space" />
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/cancelButton"
|
||||
style="@style/Widget.Vector.Button.Text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
|
||||
</LinearLayout>
|
@ -3479,11 +3479,14 @@
|
||||
<string name="space_explore_activity_title">Explore rooms</string>
|
||||
<string name="space_add_child_title">Add rooms</string>
|
||||
<string name="leave_space">Leave Space</string>
|
||||
<string name="space_leave_prompt_msg">Are you sure you want to leave the space?</string>
|
||||
<string name="space_leave_prompt_msg">Are you sure you want to leave %s?</string>
|
||||
<string name="space_leave_prompt_msg_only_you">You are the only person here. If you leave, no one will be able to join in the future, including you.</string>
|
||||
<string name="space_leave_prompt_msg_private">This space is not public. You will not be able to rejoin without an invite.</string>
|
||||
<string name="space_leave_prompt_msg_as_admin">You are admin of this space, ensure that you have transferred admin right to another member before leaving.</string>
|
||||
|
||||
<string name="space_leave_prompt_msg_private">You won\'t be able to rejoin unless you are re-invited.</string>
|
||||
<string name="space_leave_prompt_msg_as_admin">You\'re the only admin of this space. Leaving it will mean no one has control over it.</string>
|
||||
<string name="leave_all_rooms_and_spaces">Leave all rooms and spaces</string>
|
||||
<string name="you_will_leave_all_in">You will leave all rooms and spaces in %s.</string>
|
||||
<string name="dont_leave_any">Don’t leave any rooms and spaces</string>
|
||||
<string name="leave_specific_ones">Leave specific rooms and spaces</string>
|
||||
|
||||
<string name="space_add_existing_rooms">Add existing rooms and space</string>
|
||||
<string name="space_add_rooms">Add rooms</string>
|
||||
|
Loading…
Reference in New Issue
Block a user