Ugrade unstable room notice in settings

default update parent, clean migrate bottomsheet layout
This commit is contained in:
Valere 2021-06-24 09:38:20 +02:00
parent 171793d190
commit 57c75f8039
17 changed files with 239 additions and 192 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 New Vector Ltd * Copyright 2021 The Matrix.org Foundation C.I.C.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,7 +26,8 @@ interface RoomVersionService {
*/ */
suspend fun upgradeToVersion(version: String): String suspend fun upgradeToVersion(version: String): String
suspend fun getRecommendedVersion() : String fun getRecommendedVersion() : String
fun userMayUpgradeRoom(userId: String): Boolean fun userMayUpgradeRoom(userId: String): Boolean
fun isUsingUnstableRoomVersion(): Boolean
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 New Vector Ltd * Copyright 2021 The Matrix.org Foundation C.I.C.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 New Vector Ltd * Copyright 2021 The Matrix.org Foundation C.I.C.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 New Vector Ltd * Copyright 2021 The Matrix.org Foundation C.I.C.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,6 +24,7 @@ import io.realm.Realm
import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.homeserver.RoomVersionStatus
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
@ -63,7 +64,7 @@ internal class DefaultRoomVersionService @AssistedInject constructor(
) )
} }
override suspend fun getRecommendedVersion(): String { override fun getRecommendedVersion(): String {
return Realm.getInstance(monarchy.realmConfiguration).use { realm -> return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
HomeServerCapabilitiesEntity.get(realm)?.let { HomeServerCapabilitiesEntity.get(realm)?.let {
HomeServerCapabilitiesMapper.map(it) HomeServerCapabilitiesMapper.map(it)
@ -71,6 +72,18 @@ internal class DefaultRoomVersionService @AssistedInject constructor(
} }
} }
override fun isUsingUnstableRoomVersion(): Boolean {
var isUsingUnstable: Boolean
Realm.getInstance(monarchy.realmConfiguration).use { realm ->
val versionCaps = HomeServerCapabilitiesEntity.get(realm)?.let {
HomeServerCapabilitiesMapper.map(it)
}?.roomVersions
val currentVersion = getRoomVersion()
isUsingUnstable = versionCaps?.supportedVersion?.firstOrNull { it.version == currentVersion }?.status == RoomVersionStatus.UNSTABLE
}
return isUsingUnstable
}
override fun userMayUpgradeRoom(userId: String): Boolean { override fun userMayUpgradeRoom(userId: String): Boolean {
val powerLevelsHelper = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition) val powerLevelsHelper = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition)
?.content?.toModel<PowerLevelsContent>() ?.content?.toModel<PowerLevelsContent>()

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 New Vector Ltd * Copyright 2021 The Matrix.org Foundation C.I.C.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -162,7 +162,7 @@ Formatter\.formatShortFileSize===1
# android\.text\.TextUtils # 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 ### 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===101 enum class===102
### Do not import temporary legacy classes ### Do not import temporary legacy classes
import org.matrix.android.sdk.internal.legacy.riot===3 import org.matrix.android.sdk.internal.legacy.riot===3

View File

@ -332,7 +332,11 @@ object CommandParser {
} }
Command.UPGRADE_ROOM.command -> { Command.UPGRADE_ROOM.command -> {
val newVersion = textMessage.substring(Command.UPGRADE_ROOM.command.length).trim() val newVersion = textMessage.substring(Command.UPGRADE_ROOM.command.length).trim()
ParsedCommand.UpgradeRoom(newVersion) if (newVersion.isEmpty()) {
ParsedCommand.ErrorSyntax(Command.UPGRADE_ROOM)
} else {
ParsedCommand.UpgradeRoom(newVersion)
}
} }
else -> { else -> {
// Unknown command // Unknown command

View File

@ -21,22 +21,24 @@ import android.os.Parcelable
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.fragment.app.setFragmentResult import androidx.fragment.app.setFragmentResult
import com.airbnb.epoxy.OnModelBuildFinishedListener import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success import com.airbnb.mvrx.Success
import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState import com.airbnb.mvrx.withState
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.cleanup import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.databinding.BottomSheetGenericListBinding import im.vector.app.databinding.BottomSheetRoomUpgradeBinding
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import javax.inject.Inject import javax.inject.Inject
class MigrateRoomBottomSheet : class MigrateRoomBottomSheet :
VectorBaseBottomSheetDialogFragment<BottomSheetGenericListBinding>(), VectorBaseBottomSheetDialogFragment<BottomSheetRoomUpgradeBinding>(),
MigrateRoomViewModel.Factory, MigrateRoomController.InteractionListener { MigrateRoomViewModel.Factory {
@Parcelize @Parcelize
data class Args( data class Args(
@ -50,7 +52,7 @@ class MigrateRoomBottomSheet :
override val showExpanded = true override val showExpanded = true
@Inject @Inject
lateinit var epoxyController: MigrateRoomController lateinit var errorFormatter: ErrorFormatter
val viewModel: MigrateRoomViewModel by fragmentViewModel() val viewModel: MigrateRoomViewModel by fragmentViewModel()
@ -58,41 +60,79 @@ class MigrateRoomBottomSheet :
injector.inject(this) injector.inject(this)
} }
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) =
BottomSheetGenericListBinding.inflate(inflater, container, false)
override fun invalidate() = withState(viewModel) { state -> override fun invalidate() = withState(viewModel) { state ->
epoxyController.setData(state)
super.invalidate()
when (val result = state.upgradingStatus) { views.headerText.setText(if (state.isPublic) R.string.upgrade_public_room else R.string.upgrade_private_room)
views.upgradeFromTo.text = getString(R.string.upgrade_public_room_from_to, state.currentVersion, state.newVersion)
views.autoInviteSwitch.isVisible = !state.isPublic && state.otherMemberCount > 0
views.autoUpdateParent.isVisible = state.knownParents.isNotEmpty()
when (state.upgradingStatus) {
is Loading -> {
views.progressBar.isVisible = true
views.progressBar.isIndeterminate = state.upgradingProgressIndeterminate
views.progressBar.progress = state.upgradingProgress
views.progressBar.max = state.upgradingProgressTotal
views.inlineError.setTextOrHide(null)
views.button.isVisible = false
}
is Success -> { is Success -> {
val result = result.invoke() views.progressBar.isVisible = false
if (result is UpgradeRoomViewModelTask.Result.Success) { when (val result = state.upgradingStatus.invoke()) {
setFragmentResult(REQUEST_KEY, Bundle().apply { is UpgradeRoomViewModelTask.Result.Failure -> {
putString(BUNDLE_KEY_REPLACEMENT_ROOM, result.replacementRoomId) val errorText = when (result) {
}) is UpgradeRoomViewModelTask.Result.UnknownRoom -> {
dismiss() // should not happen
getString(R.string.unknown_error)
}
is UpgradeRoomViewModelTask.Result.NotAllowed -> {
getString(R.string.upgrade_room_no_power_to_manage)
}
is UpgradeRoomViewModelTask.Result.ErrorFailure -> {
errorFormatter.toHumanReadable(result.throwable)
}
else -> null
}
views.inlineError.setTextOrHide(errorText)
views.button.isVisible = true
views.button.text = getString(R.string.global_retry)
}
is UpgradeRoomViewModelTask.Result.Success -> {
setFragmentResult(REQUEST_KEY, Bundle().apply {
putString(BUNDLE_KEY_REPLACEMENT_ROOM, result.replacementRoomId)
})
dismiss()
}
} }
} }
else -> {
views.button.isVisible = true
views.button.text = getString(R.string.upgrade)
}
} }
super.invalidate()
} }
val postBuild = OnModelBuildFinishedListener { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) =
view?.post { forceExpandState() } BottomSheetRoomUpgradeBinding.inflate(inflater, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
epoxyController.callback = this
views.bottomSheetRecyclerView.configureWith(epoxyController)
epoxyController.addModelBuildListener(postBuild)
}
override fun onDestroyView() { views.button.debouncedClicks {
views.bottomSheetRecyclerView.cleanup() viewModel.handle(MigrateRoomAction.UpgradeRoom)
epoxyController.removeModelBuildListener(postBuild) }
super.onDestroyView()
views.autoInviteSwitch.setOnCheckedChangeListener { _, isChecked ->
viewModel.handle(MigrateRoomAction.SetAutoInvite(isChecked))
}
views.autoUpdateParent.setOnCheckedChangeListener { _, isChecked ->
viewModel.handle(MigrateRoomAction.SetUpdateKnownParentSpace(isChecked))
}
} }
override fun create(initialState: MigrateRoomViewState): MigrateRoomViewModel { override fun create(initialState: MigrateRoomViewState): MigrateRoomViewModel {
@ -111,16 +151,4 @@ class MigrateRoomBottomSheet :
} }
} }
} }
override fun onAutoInvite(autoInvite: Boolean) {
viewModel.handle(MigrateRoomAction.SetAutoInvite(autoInvite))
}
override fun onAutoUpdateParent(update: Boolean) {
viewModel.handle(MigrateRoomAction.SetUpdateKnownParentSpace(update))
}
override fun onConfirmUpgrade() {
viewModel.handle(MigrateRoomAction.UpgradeRoom)
}
} }

View File

@ -1,135 +0,0 @@
/*
* 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.home.room.detail.upgrade
import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import im.vector.app.R
import im.vector.app.core.epoxy.errorWithRetryItem
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.resources.StringProvider
import im.vector.app.core.ui.bottomsheet.bottomSheetTitleItem
import im.vector.app.core.ui.list.ItemStyle
import im.vector.app.core.ui.list.genericFooterItem
import im.vector.app.core.ui.list.genericProgressBarItem
import im.vector.app.features.form.formSubmitButtonItem
import im.vector.app.features.form.formSwitchItem
import javax.inject.Inject
class MigrateRoomController @Inject constructor(
private val stringProvider: StringProvider,
private val errorFormatter: ErrorFormatter
) : TypedEpoxyController<MigrateRoomViewState>() {
interface InteractionListener {
fun onAutoInvite(autoInvite: Boolean)
fun onAutoUpdateParent(update: Boolean)
fun onConfirmUpgrade()
}
var callback: InteractionListener? = null
override fun buildModels(data: MigrateRoomViewState?) {
data ?: return
val host = this@MigrateRoomController
bottomSheetTitleItem {
id("title")
title(
host.stringProvider.getString(if (data.isPublic) R.string.upgrade_public_room else R.string.upgrade_private_room)
)
}
genericFooterItem {
id("warning_text")
centered(false)
style(ItemStyle.NORMAL_TEXT)
text(host.stringProvider.getString(R.string.upgrade_room_warning))
}
genericFooterItem {
id("from_to_room")
centered(false)
style(ItemStyle.NORMAL_TEXT)
text(host.stringProvider.getString(R.string.upgrade_public_room_from_to, data.currentVersion, data.newVersion))
}
if (!data.isPublic && data.otherMemberCount > 0) {
formSwitchItem {
id("auto_invite")
switchChecked(data.shouldIssueInvites)
title(host.stringProvider.getString(R.string.upgrade_room_auto_invite))
listener { switch -> host.callback?.onAutoInvite(switch) }
}
}
if (data.knownParents.isNotEmpty()) {
formSwitchItem {
id("update_parent")
switchChecked(data.shouldUpdateKnownParents)
title(host.stringProvider.getString(R.string.upgrade_room_update_parent))
listener { switch -> host.callback?.onAutoUpdateParent(switch) }
}
}
when (data.upgradingStatus) {
is Loading -> {
genericProgressBarItem {
id("upgrade_progress")
indeterminate(data.upgradingProgressIndeterminate)
progress(data.upgradingProgress)
total(data.upgradingProgressTotal)
}
}
is Success -> {
when (val result = data.upgradingStatus.invoke()) {
is UpgradeRoomViewModelTask.Result.Failure -> {
val errorText = when (result) {
is UpgradeRoomViewModelTask.Result.UnknownRoom -> {
// should not happen
host.stringProvider.getString(R.string.unknown_error)
}
is UpgradeRoomViewModelTask.Result.NotAllowed -> {
host.stringProvider.getString(R.string.upgrade_room_no_power_to_manage)
}
is UpgradeRoomViewModelTask.Result.ErrorFailure -> {
host.errorFormatter.toHumanReadable(result.throwable)
}
else -> null
}
errorWithRetryItem {
id("error")
text(errorText)
listener { host.callback?.onConfirmUpgrade() }
}
}
is UpgradeRoomViewModelTask.Result.Success -> {
// nop, dismisses
}
}
}
else -> {
formSubmitButtonItem {
id("migrate")
buttonTitleId(R.string.upgrade)
buttonClickListener { host.callback?.onConfirmUpgrade() }
}
}
}
}
}

View File

@ -26,7 +26,7 @@ data class MigrateRoomViewState(
val currentVersion: String? = null, val currentVersion: String? = null,
val isPublic: Boolean = false, val isPublic: Boolean = false,
val shouldIssueInvites: Boolean = false, val shouldIssueInvites: Boolean = false,
val shouldUpdateKnownParents: Boolean = false, val shouldUpdateKnownParents: Boolean = true,
val otherMemberCount: Int = 0, val otherMemberCount: Int = 0,
val knownParents: List<String> = emptyList(), val knownParents: List<String> = emptyList(),
val upgradingStatus: Async<UpgradeRoomViewModelTask.Result> = Uninitialized, val upgradingStatus: Async<UpgradeRoomViewModelTask.Result> = Uninitialized,

View File

@ -22,8 +22,10 @@ import im.vector.app.R
import im.vector.app.core.epoxy.expandableTextItem import im.vector.app.core.epoxy.expandableTextItem
import im.vector.app.core.epoxy.profiles.buildProfileAction import im.vector.app.core.epoxy.profiles.buildProfileAction
import im.vector.app.core.epoxy.profiles.buildProfileSection import im.vector.app.core.epoxy.profiles.buildProfileSection
import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.core.ui.list.genericFooterItem import im.vector.app.core.ui.list.genericFooterItem
import im.vector.app.core.ui.list.genericPositiveButtonItem
import im.vector.app.features.home.ShortcutCreator import im.vector.app.features.home.ShortcutCreator
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
import im.vector.app.features.home.room.detail.timeline.tools.createLinkMovementMethod import im.vector.app.features.home.room.detail.timeline.tools.createLinkMovementMethod
@ -34,6 +36,7 @@ import javax.inject.Inject
class RoomProfileController @Inject constructor( class RoomProfileController @Inject constructor(
private val stringProvider: StringProvider, private val stringProvider: StringProvider,
private val colorProvider: ColorProvider,
private val vectorPreferences: VectorPreferences, private val vectorPreferences: VectorPreferences,
private val shortcutCreator: ShortcutCreator private val shortcutCreator: ShortcutCreator
) : TypedEpoxyController<RoomProfileViewState>() { ) : TypedEpoxyController<RoomProfileViewState>() {
@ -55,6 +58,7 @@ class RoomProfileController @Inject constructor(
fun onRoomIdClicked() fun onRoomIdClicked()
fun onRoomDevToolsClicked() fun onRoomDevToolsClicked()
fun onUrlInTopicLongClicked(url: String) fun onUrlInTopicLongClicked(url: String)
fun doMigrateToVersion(newVersion: String)
} }
override fun buildModels(data: RoomProfileViewState?) { override fun buildModels(data: RoomProfileViewState?) {
@ -87,6 +91,28 @@ class RoomProfileController @Inject constructor(
// Security // Security
buildProfileSection(stringProvider.getString(R.string.room_profile_section_security)) buildProfileSection(stringProvider.getString(R.string.room_profile_section_security))
// Upgrade warning
val roomVersion = data.roomCreateContent()?.roomVersion
if (data.canUpgradeRoom
&& !data.isTombstoned
&& roomVersion != null
&& data.isUsingUnstableRoomVersion
&& data.recommendedRoomVersion != null) {
genericFooterItem {
id("version_warning")
text(host.stringProvider.getString(R.string.room_using_unstable_room_version, roomVersion))
textColor(host.colorProvider.getColorFromAttribute(R.attr.colorError))
centered(false)
}
genericPositiveButtonItem {
id("migrate_button")
text(host.stringProvider.getString(R.string.room_upgrade_to_recommened_version))
buttonClickAction { host.callback?.doMigrateToVersion(data.recommendedRoomVersion) }
}
}
val learnMoreSubtitle = if (roomSummary.isEncrypted) { val learnMoreSubtitle = if (roomSummary.isEncrypted) {
if (roomSummary.isDirect) R.string.direct_room_profile_encrypted_subtitle else R.string.room_profile_encrypted_subtitle if (roomSummary.isDirect) R.string.direct_room_profile_encrypted_subtitle else R.string.room_profile_encrypted_subtitle
} else { } else {
@ -194,7 +220,7 @@ class RoomProfileController @Inject constructor(
editable = false, editable = false,
action = { callback?.onRoomIdClicked() } action = { callback?.onRoomIdClicked() }
) )
data.roomCreateContent()?.roomVersion?.let { roomVersion?.let {
buildProfileAction( buildProfileAction(
id = "roomVersion", id = "roomVersion",
title = stringProvider.getString(R.string.room_settings_room_version_title), title = stringProvider.getString(R.string.room_settings_room_version_title),

View File

@ -45,6 +45,7 @@ import im.vector.app.core.utils.startSharePlainTextIntent
import im.vector.app.databinding.FragmentMatrixProfileBinding import im.vector.app.databinding.FragmentMatrixProfileBinding
import im.vector.app.databinding.ViewStubRoomProfileHeaderBinding import im.vector.app.databinding.ViewStubRoomProfileHeaderBinding
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet
import im.vector.app.features.home.room.list.actions.RoomListActionsArgs import im.vector.app.features.home.room.list.actions.RoomListActionsArgs
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction
@ -303,6 +304,11 @@ class RoomProfileFragment @Inject constructor(
copyToClipboard(requireContext(), url, true) copyToClipboard(requireContext(), url, true)
} }
override fun doMigrateToVersion(newVersion: String) {
MigrateRoomBottomSheet.newInstance(roomProfileArgs.roomId, newVersion)
.show(parentFragmentManager, "migrate")
}
private fun onShareRoomProfile(permalink: String) { private fun onShareRoomProfile(permalink: String) {
startSharePlainTextIntent( startSharePlainTextIntent(
fragment = this, fragment = this,

View File

@ -22,8 +22,8 @@ import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext import com.airbnb.mvrx.ViewModelContext
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
@ -81,8 +81,14 @@ class RoomProfileViewModel @AssistedInject constructor(
rxRoom.liveStateEvent(EventType.STATE_ROOM_CREATE, QueryStringValue.NoCondition) rxRoom.liveStateEvent(EventType.STATE_ROOM_CREATE, QueryStringValue.NoCondition)
.mapOptional { it.content.toModel<RoomCreateContent>() } .mapOptional { it.content.toModel<RoomCreateContent>() }
.unwrap() .unwrap()
.execute { .execute { async ->
copy(roomCreateContent = it) copy(
roomCreateContent = async,
recommendedRoomVersion = room.getRecommendedVersion(),
isUsingUnstableRoomVersion = room.isUsingUnstableRoomVersion(),
canUpgradeRoom = room.userMayUpgradeRoom(session.myUserId),
isTombstoned = room.getStateEvent(EventType.STATE_ROOM_TOMBSTONE) != null
)
} }
} }

View File

@ -30,7 +30,11 @@ data class RoomProfileViewState(
val roomCreateContent: Async<RoomCreateContent> = Uninitialized, val roomCreateContent: Async<RoomCreateContent> = Uninitialized,
val bannedMembership: Async<List<RoomMemberSummary>> = Uninitialized, val bannedMembership: Async<List<RoomMemberSummary>> = Uninitialized,
val actionPermissions: ActionPermissions = ActionPermissions(), val actionPermissions: ActionPermissions = ActionPermissions(),
val isLoading: Boolean = false val isLoading: Boolean = false,
val isUsingUnstableRoomVersion: Boolean = false,
val recommendedRoomVersion: String? = null,
val canUpgradeRoom: Boolean = false,
val isTombstoned: Boolean = false
) : MvRxState { ) : MvRxState {
constructor(args: RoomProfileArgs) : this(roomId = args.roomId) constructor(args: RoomProfileArgs) : this(roomId = args.roomId)

View File

@ -6,6 +6,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?colorSurface" android:background="?colorSurface"
android:fadeScrollbars="false" android:fadeScrollbars="false"
android:nestedScrollingEnabled="false"
android:scrollbars="vertical" android:scrollbars="vertical"
tools:itemCount="5" tools:itemCount="5"
tools:listitem="@layout/item_bottom_sheet_action" /> tools:listitem="@layout/item_bottom_sheet_action" />

View File

@ -0,0 +1,90 @@
<?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"
android:padding="16dp">
<TextView
android:id="@+id/headerText"
style="@style/Widget.Vector.TextView.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="12dp"
android:gravity="start"
android:textColor="?vctr_content_primary"
android:textStyle="bold"
tools:text="@string/upgrade_public_room" />
<TextView
android:id="@+id/descriptionText"
style="@style/Widget.Vector.TextView.Body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:gravity="start"
android:textColor="?vctr_content_secondary"
android:text="@string/upgrade_room_warning" />
<TextView
android:id="@+id/upgradeFromTo"
style="@style/Widget.Vector.TextView.Body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:gravity="start"
android:textColor="?vctr_content_secondary"
tools:text="@string/upgrade_public_room_from_to" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/autoInviteSwitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:checked="true"
android:layout_marginBottom="8dp"
android:text="@string/upgrade_room_auto_invite"
tools:visibility="visible" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/autoUpdateParent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="@string/upgrade_room_update_parent_sapce"
tools:visibility="visible" />
<Button
android:id="@+id/button"
style="@style/Widget.Vector.Button.Outlined"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_vertical_margin"
android:text="@string/upgrade"
android:textAllCaps="true"
android:textColor="?colorSecondary" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/inlineError"
style="@style/Widget.Vector.TextView.Body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:gravity="start"
android:textColor="?colorError"
android:visibility="gone"
tools:text="@string/unknown_error"
tools:visibility="visible" />
</LinearLayout>

View File

@ -3427,4 +3427,7 @@
<string name="upgrade_room_update_parent">Automatically update parent space</string> <string name="upgrade_room_update_parent">Automatically update parent space</string>
<string name="upgrade_room_no_power_to_manage">You need permission to upgrade a room</string> <string name="upgrade_room_no_power_to_manage">You need permission to upgrade a room</string>
<string name="room_using_unstable_room_version">This room is running room version %s, which this homeserver has marked as unstable.</string>
<string name="room_upgrade_to_recommened_version">Upgrade to the recommended room version</string>
</resources> </resources>