Room creation form: add advanced section to disable federation (#1314)
This commit is contained in:
parent
2b1b9d35a2
commit
579efb016a
|
@ -8,6 +8,7 @@ Improvements 🙌:
|
|||
- Open an existing DM instead of creating a new one (#2319)
|
||||
- Ask for explicit user consent to send their contact details to the identity server (#2375)
|
||||
- Handle events of type "m.room.server_acl" (#890)
|
||||
- Room creation form: add advanced section to disable federation (#1314)
|
||||
|
||||
Bugfix 🐛:
|
||||
- Fix issue when restoring draft after sharing (#2287)
|
||||
|
|
|
@ -94,7 +94,22 @@ class CreateRoomParams {
|
|||
* The server will clobber the following keys: creator.
|
||||
* Future versions of the specification may allow the server to clobber other keys.
|
||||
*/
|
||||
var creationContent: Any? = null
|
||||
val creationContent = mutableMapOf<String, Any>()
|
||||
|
||||
/**
|
||||
* Set to true to disable federation of this room.
|
||||
* Default: false
|
||||
*/
|
||||
var disableFederation = false
|
||||
set(value) {
|
||||
field = value
|
||||
if (value) {
|
||||
creationContent[CREATION_CONTENT_KEY_M_FEDERATE] = false
|
||||
} else {
|
||||
// This is the default value, we remove the field
|
||||
creationContent.remove(CREATION_CONTENT_KEY_M_FEDERATE)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The power level content to override in the default power level event
|
||||
|
@ -120,4 +135,8 @@ class CreateRoomParams {
|
|||
fun enableEncryption() {
|
||||
algorithm = MXCRYPTO_ALGORITHM_MEGOLM
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val CREATION_CONTENT_KEY_M_FEDERATE = "m.federate"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,8 +74,8 @@ internal data class CreateRoomBody(
|
|||
val invite3pids: List<ThreePidInviteBody>?,
|
||||
|
||||
/**
|
||||
* Extra keys to be added to the content of the m.room.create.
|
||||
* The server will clobber the following keys: creator.
|
||||
* Extra keys, such as m.federate, to be added to the content of the m.room.create event.
|
||||
* The server will clobber the following keys: creator, room_version.
|
||||
* Future versions of the specification may allow the server to clobber other keys.
|
||||
*/
|
||||
@Json(name = "creation_content")
|
||||
|
|
|
@ -81,7 +81,7 @@ internal class CreateRoomBodyBuilder @Inject constructor(
|
|||
topic = params.topic,
|
||||
invitedUserIds = params.invitedUserIds,
|
||||
invite3pids = invite3pids,
|
||||
creationContent = params.creationContent,
|
||||
creationContent = params.creationContent.takeIf { it.isNotEmpty() },
|
||||
initialStates = initialStates,
|
||||
preset = params.preset,
|
||||
isDirect = params.isDirect,
|
||||
|
|
|
@ -26,12 +26,12 @@ import javax.inject.Inject
|
|||
|
||||
class DrawableProvider @Inject constructor(private val context: Context) {
|
||||
|
||||
fun getDrawable(@DrawableRes colorRes: Int): Drawable? {
|
||||
return ContextCompat.getDrawable(context, colorRes)
|
||||
fun getDrawable(@DrawableRes drawableRes: Int): Drawable? {
|
||||
return ContextCompat.getDrawable(context, drawableRes)
|
||||
}
|
||||
|
||||
fun getDrawable(@DrawableRes colorRes: Int, @ColorInt color: Int): Drawable? {
|
||||
return ContextCompat.getDrawable(context, colorRes)?.let {
|
||||
fun getDrawable(@DrawableRes drawableRes: Int, @ColorInt color: Int): Drawable? {
|
||||
return ContextCompat.getDrawable(context, drawableRes)?.let {
|
||||
ThemeUtils.tintDrawableWithColor(it, color)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2019 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.form
|
||||
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_form_advanced_toggle)
|
||||
abstract class FormAdvancedToggleItem : VectorEpoxyModel<FormAdvancedToggleItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var title: CharSequence
|
||||
@EpoxyAttribute var expanded: Boolean = false
|
||||
@EpoxyAttribute var listener: (() -> Unit)? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
val tintColor = ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_secondary)
|
||||
val expandedArrowDrawableRes = if (expanded) R.drawable.ic_expand_more_white else R.drawable.ic_expand_less_white
|
||||
val expandedArrowDrawable = ContextCompat.getDrawable(holder.view.context, expandedArrowDrawableRes)?.also {
|
||||
DrawableCompat.setTint(it, tintColor)
|
||||
}
|
||||
holder.titleView.setCompoundDrawablesWithIntrinsicBounds(null, null, expandedArrowDrawable, null)
|
||||
holder.titleView.text = title
|
||||
holder.view.setOnClickListener { listener?.invoke() }
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
val titleView by bind<TextView>(R.id.itemFormAdvancedToggleTitleView)
|
||||
}
|
||||
}
|
|
@ -27,6 +27,9 @@ sealed class CreateRoomAction : VectorViewModelAction {
|
|||
data class SetIsInRoomDirectory(val isInRoomDirectory: Boolean) : CreateRoomAction()
|
||||
data class SetIsEncrypted(val isEncrypted: Boolean) : CreateRoomAction()
|
||||
|
||||
object ToggleShowAdvanced : CreateRoomAction()
|
||||
data class DisableFederation(val disableFederation: Boolean) : CreateRoomAction()
|
||||
|
||||
object Create : CreateRoomAction()
|
||||
object Reset : CreateRoomAction()
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.app.core.epoxy.loadingItem
|
|||
import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.discovery.settingsSectionTitleItem
|
||||
import im.vector.app.features.form.formAdvancedToggleItem
|
||||
import im.vector.app.features.form.formEditTextItem
|
||||
import im.vector.app.features.form.formEditableAvatarItem
|
||||
import im.vector.app.features.form.formSubmitButtonItem
|
||||
|
@ -148,6 +149,22 @@ class CreateRoomController @Inject constructor(private val stringProvider: Strin
|
|||
listener?.setIsEncrypted(value)
|
||||
}
|
||||
}
|
||||
formAdvancedToggleItem {
|
||||
id("showAdvanced")
|
||||
title(stringProvider.getString(if (viewState.showAdvanced) R.string.hide_advanced else R.string.show_advanced))
|
||||
expanded(!viewState.showAdvanced)
|
||||
listener { listener?.toggleShowAdvanced() }
|
||||
}
|
||||
if (viewState.showAdvanced) {
|
||||
formSwitchItem {
|
||||
id("federation")
|
||||
enabled(enableFormElement)
|
||||
title(stringProvider.getString(R.string.create_room_disable_federation_title, viewState.homeServerName))
|
||||
summary(stringProvider.getString(R.string.create_room_disable_federation_description))
|
||||
switchChecked(viewState.disableFederation)
|
||||
listener { value -> listener?.setDisableFederation(value) }
|
||||
}
|
||||
}
|
||||
formSubmitButtonItem {
|
||||
id("submit")
|
||||
enabled(enableFormElement)
|
||||
|
@ -165,6 +182,8 @@ class CreateRoomController @Inject constructor(private val stringProvider: Strin
|
|||
fun setIsInRoomDirectory(isInRoomDirectory: Boolean)
|
||||
fun setIsEncrypted(isEncrypted: Boolean)
|
||||
fun retry()
|
||||
fun toggleShowAdvanced()
|
||||
fun setDisableFederation(disableFederation: Boolean)
|
||||
fun submit()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,14 @@ class CreateRoomFragment @Inject constructor(
|
|||
viewModel.handle(CreateRoomAction.SetIsEncrypted(isEncrypted))
|
||||
}
|
||||
|
||||
override fun toggleShowAdvanced() {
|
||||
viewModel.handle(CreateRoomAction.ToggleShowAdvanced)
|
||||
}
|
||||
|
||||
override fun setDisableFederation(disableFederation: Boolean) {
|
||||
viewModel.handle(CreateRoomAction.DisableFederation(disableFederation))
|
||||
}
|
||||
|
||||
override fun submit() {
|
||||
viewModel.handle(CreateRoomAction.Create)
|
||||
}
|
||||
|
|
|
@ -53,9 +53,18 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: Cr
|
|||
}
|
||||
|
||||
init {
|
||||
initHomeServerName()
|
||||
initAdminE2eByDefault()
|
||||
}
|
||||
|
||||
private fun initHomeServerName() {
|
||||
setState {
|
||||
copy(
|
||||
homeServerName = session.myUserId.substringAfter(":")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private var adminE2EByDefault = true
|
||||
|
||||
private fun initAdminE2eByDefault() {
|
||||
|
@ -99,9 +108,27 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: Cr
|
|||
is CreateRoomAction.SetIsEncrypted -> setIsEncrypted(action)
|
||||
is CreateRoomAction.Create -> doCreateRoom()
|
||||
CreateRoomAction.Reset -> doReset()
|
||||
CreateRoomAction.ToggleShowAdvanced -> toggleShowAdvanced()
|
||||
is CreateRoomAction.DisableFederation -> disableFederation(action)
|
||||
}.exhaustive
|
||||
}
|
||||
|
||||
private fun disableFederation(action: CreateRoomAction.DisableFederation) {
|
||||
setState {
|
||||
copy(disableFederation = action.disableFederation)
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleShowAdvanced() {
|
||||
setState {
|
||||
copy(
|
||||
showAdvanced = !showAdvanced,
|
||||
// Reset to false if advanced is hidden
|
||||
disableFederation = disableFederation && !showAdvanced
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun doReset() {
|
||||
setState {
|
||||
// Delete temporary file with the avatar
|
||||
|
@ -151,6 +178,8 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: Cr
|
|||
visibility = if (state.isInRoomDirectory) RoomDirectoryVisibility.PUBLIC else RoomDirectoryVisibility.PRIVATE
|
||||
// Public room
|
||||
preset = if (state.isPublic) CreateRoomPreset.PRESET_PUBLIC_CHAT else CreateRoomPreset.PRESET_PRIVATE_CHAT
|
||||
// Disabling federation
|
||||
disableFederation = state.disableFederation
|
||||
|
||||
// Encryption
|
||||
if (state.isEncrypted) {
|
||||
|
|
|
@ -28,6 +28,9 @@ data class CreateRoomViewState(
|
|||
val isPublic: Boolean = false,
|
||||
val isInRoomDirectory: Boolean = false,
|
||||
val isEncrypted: Boolean = false,
|
||||
val showAdvanced: Boolean = false,
|
||||
val disableFederation: Boolean = false,
|
||||
val homeServerName: String = "",
|
||||
val hsAdminHasDisabledE2E: Boolean = false,
|
||||
val asyncCreateRoomRequest: Async<String> = Uninitialized
|
||||
) : MvRxState {
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/itemFormAdvancedToggleRootView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?riotx_background"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/layout_horizontal_margin"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingEnd="@dimen/layout_horizontal_margin"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/itemFormAdvancedToggleTitleView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
app:drawableTint="?riotx_text_secondary"
|
||||
tools:drawableEnd="@drawable/ic_expand_more_white"
|
||||
tools:text="@string/show_advanced" />
|
||||
|
||||
</LinearLayout>
|
|
@ -15,8 +15,6 @@
|
|||
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||
android:duplicateParentState="true"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/formSwitchSummary"
|
||||
|
|
|
@ -2094,6 +2094,12 @@
|
|||
<string name="create_room_encryption_title">"Enable encryption"</string>
|
||||
<string name="create_room_encryption_description">"Once enabled, encryption cannot be disabled."</string>
|
||||
|
||||
<string name="show_advanced">Show advanced</string>
|
||||
<string name="hide_advanced">Hide advanced</string>
|
||||
|
||||
<string name="create_room_disable_federation_title">Block anyone not part of %s from ever joining this room</string>
|
||||
<string name="create_room_disable_federation_description">You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.</string>
|
||||
|
||||
<string name="login_error_threepid_denied">Your email domain is not authorized to register on this server</string>
|
||||
|
||||
<string name="verification_conclusion_warning">Untrusted sign in</string>
|
||||
|
|
Loading…
Reference in New Issue