Room alias detail

This commit is contained in:
Benoit Marty 2020-11-24 07:59:57 +01:00 committed by Benoit Marty
parent d9c209aa87
commit c5e6e004dd
15 changed files with 479 additions and 61 deletions

View file

@ -31,6 +31,7 @@
<w>ssss</w>
<w>sygnal</w>
<w>threepid</w>
<w>unpublish</w>
<w>unwedging</w>
</words>
</dictionary>

View file

@ -67,6 +67,7 @@ import im.vector.app.features.roomdirectory.createroom.CreateRoomActivity
import im.vector.app.features.roommemberprofile.RoomMemberProfileActivity
import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheet
import im.vector.app.features.roomprofile.RoomProfileActivity
import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheet
import im.vector.app.features.settings.VectorSettingsActivity
import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheet
import im.vector.app.features.share.IncomingShareActivity
@ -153,6 +154,7 @@ interface ScreenComponent {
fun inject(bottomSheet: ViewEditHistoryBottomSheet)
fun inject(bottomSheet: DisplayReadReceiptsBottomSheet)
fun inject(bottomSheet: RoomListQuickActionsBottomSheet)
fun inject(bottomSheet: RoomAliasBottomSheet)
fun inject(bottomSheet: VerificationBottomSheet)
fun inject(bottomSheet: DeviceVerificationInfoBottomSheet)
fun inject(bottomSheet: DeviceListBottomSheet)

View file

@ -35,6 +35,7 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA
import im.vector.app.features.reactions.EmojiChooserViewModel
import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel
import im.vector.app.features.roomprofile.RoomProfileSharedActionViewModel
import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedActionViewModel
import im.vector.app.features.userdirectory.UserListSharedActionViewModel
@Module
@ -105,6 +106,11 @@ interface ViewModelModule {
@ViewModelKey(RoomListQuickActionsSharedActionViewModel::class)
fun bindRoomListQuickActionsSharedActionViewModel(viewModel: RoomListQuickActionsSharedActionViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(RoomAliasBottomSheetSharedActionViewModel::class)
fun bindRoomAliasBottomSheetSharedActionViewModel(viewModel: RoomAliasBottomSheetSharedActionViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(RoomDirectorySharedActionViewModel::class)

View file

@ -22,8 +22,9 @@ sealed class RoomAliasAction : VectorViewModelAction {
// Canonical
object ToggleManualPublishForm : RoomAliasAction()
data class SetNewAlias(val alias: String) : RoomAliasAction()
object AddAlias : RoomAliasAction()
data class RemoveAlias(val alias: String) : RoomAliasAction()
object ManualPublishAlias : RoomAliasAction()
data class PublishAlias(val alias: String) : RoomAliasAction()
data class UnpublishAlias(val alias: String) : RoomAliasAction()
data class SetCanonicalAlias(val canonicalAlias: String?) : RoomAliasAction()
// Local

View file

@ -48,10 +48,6 @@ class RoomAliasController @Inject constructor(
fun toggleManualPublishForm()
fun setNewAlias(value: String)
fun addAlias()
// TODO Delete some methods below
fun removeAlias(altAlias: String)
fun setCanonicalAlias(alias: String?)
fun removeLocalAlias(alias: String)
fun toggleLocalAliasForm()
fun setNewLocalAliasLocalPart(value: String)
fun addLocalAlias()

View file

@ -30,9 +30,13 @@ import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.shareText
import im.vector.app.core.utils.toast
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.roomprofile.RoomProfileArgs
import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheet
import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedAction
import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedActionViewModel
import kotlinx.android.synthetic.main.fragment_room_setting_generic.*
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
@ -48,12 +52,16 @@ class RoomAliasFragment @Inject constructor(
RoomAliasController.Callback {
private val viewModel: RoomAliasViewModel by fragmentViewModel()
private lateinit var sharedActionViewModel: RoomAliasBottomSheetSharedActionViewModel
private val roomProfileArgs: RoomProfileArgs by args()
override fun getLayoutResId() = R.layout.fragment_room_setting_generic
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
sharedActionViewModel = activityViewModelProvider.get(RoomAliasBottomSheetSharedActionViewModel::class.java)
controller.callback = this
setupToolbar(roomSettingsToolbar)
roomSettingsRecyclerView.configureWith(controller, hasFixedSize = true)
@ -63,9 +71,30 @@ class RoomAliasFragment @Inject constructor(
viewModel.observeViewEvents {
when (it) {
is RoomAliasViewEvents.Failure -> showFailure(it.throwable)
RoomAliasViewEvents.Success -> showSuccess()
RoomAliasViewEvents.Success -> showSuccess()
}.exhaustive
}
sharedActionViewModel
.observe()
.subscribe { handleAliasAction(it) }
.disposeOnDestroyView()
}
private fun handleAliasAction(action: RoomAliasBottomSheetSharedAction?) {
when (action) {
is RoomAliasBottomSheetSharedAction.ShareAlias -> shareAlias(action.matrixTo)
is RoomAliasBottomSheetSharedAction.PublishAlias -> viewModel.handle(RoomAliasAction.PublishAlias(action.alias))
is RoomAliasBottomSheetSharedAction.UnPublishAlias -> unpublishAlias(action.alias)
is RoomAliasBottomSheetSharedAction.DeleteAlias -> removeLocalAlias(action.alias)
is RoomAliasBottomSheetSharedAction.SetMainAlias -> viewModel.handle(RoomAliasAction.SetCanonicalAlias(action.alias))
RoomAliasBottomSheetSharedAction.UnsetMainAlias -> viewModel.handle(RoomAliasAction.SetCanonicalAlias(canonicalAlias = null))
null -> Unit
}
}
private fun shareAlias(matrixTo: String) {
shareText(requireContext(), matrixTo)
}
override fun showFailure(throwable: Throwable) {
@ -100,22 +129,18 @@ class RoomAliasFragment @Inject constructor(
invalidateOptionsMenu()
}
override fun removeAlias(altAlias: String) {
private fun unpublishAlias(altAlias: String) {
AlertDialog.Builder(requireContext())
.setTitle(R.string.dialog_title_confirmation)
.setMessage(getString(R.string.room_alias_delete_confirmation, altAlias))
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.delete) { _, _ ->
viewModel.handle(RoomAliasAction.RemoveAlias(altAlias))
viewModel.handle(RoomAliasAction.UnpublishAlias(altAlias))
}
.show()
.withColoredButton(DialogInterface.BUTTON_POSITIVE)
}
override fun setCanonicalAlias(alias: String?) {
viewModel.handle(RoomAliasAction.SetCanonicalAlias(alias))
}
override fun toggleManualPublishForm() {
viewModel.handle(RoomAliasAction.ToggleManualPublishForm)
}
@ -125,7 +150,7 @@ class RoomAliasFragment @Inject constructor(
}
override fun addAlias() {
viewModel.handle(RoomAliasAction.AddAlias)
viewModel.handle(RoomAliasAction.ManualPublishAlias)
}
override fun toggleLocalAliasForm() {
@ -140,11 +165,18 @@ class RoomAliasFragment @Inject constructor(
viewModel.handle(RoomAliasAction.AddLocalAlias)
}
override fun openAlias(alias: String, isPublished: Boolean) {
TODO()
override fun openAlias(alias: String, isPublished: Boolean) = withState(viewModel) { state ->
RoomAliasBottomSheet
.newInstance(
alias = alias,
isPublished = isPublished,
isMainAlias = alias == state.canonicalAlias,
canEditCanonicalAlias = state.actionPermissions.canChangeCanonicalAlias
)
.show(childFragmentManager, "ROOM_ALIAS_ACTIONS")
}
override fun removeLocalAlias(alias: String) {
private fun removeLocalAlias(alias: String) {
AlertDialog.Builder(requireContext())
.setTitle(R.string.dialog_title_confirmation)
.setMessage(getString(R.string.room_alias_delete_confirmation, alias))

View file

@ -157,13 +157,14 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo
when (action) {
RoomAliasAction.ToggleManualPublishForm -> handleToggleManualPublishForm()
is RoomAliasAction.SetNewAlias -> handleSetNewAlias(action)
is RoomAliasAction.AddAlias -> handleAddAlias()
is RoomAliasAction.RemoveAlias -> handleRemoveAlias(action)
is RoomAliasAction.ManualPublishAlias -> handleAddAlias()
is RoomAliasAction.UnpublishAlias -> handleRemoveAlias(action)
is RoomAliasAction.SetCanonicalAlias -> handleSetCanonicalAlias(action)
RoomAliasAction.ToggleAddLocalAliasForm -> handleToggleAddLocalAliasForm()
is RoomAliasAction.SetNewLocalAliasLocalPart -> handleSetNewLocalAliasLocalPart(action)
RoomAliasAction.AddLocalAlias -> handleAddLocalAlias()
is RoomAliasAction.RemoveLocalAlias -> handleRemoveLocalAlias(action)
is RoomAliasAction.PublishAlias -> handleAddAliasManually(action)
}.exhaustive
}
@ -210,22 +211,29 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo
private fun handleAddAlias() = withState { state ->
val newAlias = (state.publishManuallyState as? RoomAliasViewState.AddAliasState.Editing)?.value ?: return@withState
updateCanonicalAlias(
state.canonicalAlias,
state.alternativeAliases + newAlias
canonicalAlias = state.canonicalAlias,
alternativeAliases = state.alternativeAliases + newAlias
)
}
private fun handleRemoveAlias(action: RoomAliasAction.RemoveAlias) = withState { state ->
private fun handleAddAliasManually(action: RoomAliasAction.PublishAlias) = withState { state ->
updateCanonicalAlias(
state.canonicalAlias,
state.alternativeAliases - action.alias
canonicalAlias = state.canonicalAlias,
alternativeAliases = state.alternativeAliases + action.alias
)
}
private fun handleRemoveAlias(action: RoomAliasAction.UnpublishAlias) = withState { state ->
updateCanonicalAlias(
canonicalAlias = state.canonicalAlias,
alternativeAliases = state.alternativeAliases - action.alias
)
}
private fun handleSetCanonicalAlias(action: RoomAliasAction.SetCanonicalAlias) = withState { state ->
updateCanonicalAlias(
action.canonicalAlias,
state.alternativeAliases
canonicalAlias = action.canonicalAlias,
alternativeAliases = state.alternativeAliases
)
}

View file

@ -0,0 +1,104 @@
/*
* 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.roomprofile.alias.detail
import android.os.Bundle
import android.os.Parcelable
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import kotlinx.android.parcel.Parcelize
import javax.inject.Inject
@Parcelize
data class RoomAliasBottomSheetArgs(
val alias: String,
val isPublished: Boolean,
val isMainAlias: Boolean,
val canEditCanonicalAlias: Boolean
) : Parcelable
/**
* Bottom sheet fragment that shows room alias information with list of contextual actions
*/
class RoomAliasBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomAliasBottomSheetController.Listener {
private lateinit var sharedActionViewModel: RoomAliasBottomSheetSharedActionViewModel
@Inject lateinit var sharedViewPool: RecyclerView.RecycledViewPool
@Inject lateinit var roomAliasBottomSheetViewModelFactory: RoomAliasBottomSheetViewModel.Factory
@Inject lateinit var controller: RoomAliasBottomSheetController
private val viewModel: RoomAliasBottomSheetViewModel by fragmentViewModel(RoomAliasBottomSheetViewModel::class)
@BindView(R.id.bottomSheetRecyclerView)
lateinit var recyclerView: RecyclerView
override val showExpanded = true
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun getLayoutResId() = R.layout.bottom_sheet_generic_list
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
sharedActionViewModel = activityViewModelProvider.get(RoomAliasBottomSheetSharedActionViewModel::class.java)
recyclerView.configureWith(controller, viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true)
controller.listener = this
}
override fun onDestroyView() {
recyclerView.cleanup()
controller.listener = null
super.onDestroyView()
}
override fun invalidate() = withState(viewModel) {
controller.setData(it)
super.invalidate()
}
override fun didSelectMenuAction(quickAction: RoomAliasBottomSheetSharedAction) {
sharedActionViewModel.post(quickAction)
dismiss()
}
companion object {
fun newInstance(alias: String,
isPublished: Boolean,
isMainAlias: Boolean,
canEditCanonicalAlias: Boolean): RoomAliasBottomSheet {
return RoomAliasBottomSheet().apply {
setArguments(RoomAliasBottomSheetArgs(
alias = alias,
isPublished = isPublished,
isMainAlias = isMainAlias,
canEditCanonicalAlias = canEditCanonicalAlias
))
}
}
}
}

View file

@ -0,0 +1,85 @@
/*
* 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.roomprofile.alias.detail
import android.view.View
import com.airbnb.epoxy.TypedEpoxyController
import im.vector.app.core.epoxy.bottomsheet.bottomSheetActionItem
import im.vector.app.core.epoxy.dividerItem
import im.vector.app.core.epoxy.profiles.profileActionItem
import javax.inject.Inject
/**
* Epoxy controller for room alias actions
*/
class RoomAliasBottomSheetController @Inject constructor() : TypedEpoxyController<RoomAliasBottomSheetState>() {
var listener: Listener? = null
override fun buildModels(state: RoomAliasBottomSheetState) {
profileActionItem {
id("alias")
title(state.alias)
subtitle(state.matrixToLink)
}
// Notifications
dividerItem {
id("aliasSeparator")
}
var idx = 0
// Share
state.matrixToLink?.let {
RoomAliasBottomSheetSharedAction.ShareAlias(it).toBottomSheetItem(++idx)
}
// Action on published alias
if (state.isPublished) {
// Published address
if (state.canEditCanonicalAlias) {
if (state.isMainAlias) {
RoomAliasBottomSheetSharedAction.UnsetMainAlias.toBottomSheetItem(++idx)
} else {
RoomAliasBottomSheetSharedAction.SetMainAlias(state.alias).toBottomSheetItem(++idx)
}
RoomAliasBottomSheetSharedAction.UnPublishAlias(state.alias).toBottomSheetItem(++idx)
}
} else {
// Local address
if (state.canEditCanonicalAlias) {
// Publish
RoomAliasBottomSheetSharedAction.PublishAlias(state.alias).toBottomSheetItem(++idx)
}
// Delete
RoomAliasBottomSheetSharedAction.DeleteAlias(state.alias).toBottomSheetItem(++idx)
}
}
private fun RoomAliasBottomSheetSharedAction.toBottomSheetItem(index: Int) {
return bottomSheetActionItem {
id("action_$index")
iconRes(iconResId)
textRes(titleRes)
destructive(this@toBottomSheetItem.destructive)
listener(View.OnClickListener { listener?.didSelectMenuAction(this@toBottomSheetItem) })
}
}
interface Listener {
fun didSelectMenuAction(quickAction: RoomAliasBottomSheetSharedAction)
}
}

View file

@ -0,0 +1,56 @@
/*
* 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.roomprofile.alias.detail
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import im.vector.app.R
import im.vector.app.core.platform.VectorSharedAction
sealed class RoomAliasBottomSheetSharedAction(
@StringRes val titleRes: Int,
@DrawableRes val iconResId: Int = 0,
val destructive: Boolean = false)
: VectorSharedAction {
data class ShareAlias(val matrixTo: String) : RoomAliasBottomSheetSharedAction(
R.string.share,
R.drawable.ic_material_share
)
data class PublishAlias(val alias: String) : RoomAliasBottomSheetSharedAction(
R.string.room_alias_action_publish
)
data class UnPublishAlias(val alias: String) : RoomAliasBottomSheetSharedAction(
R.string.room_alias_action_unpublish
)
data class DeleteAlias(val alias: String) : RoomAliasBottomSheetSharedAction(
R.string.delete,
R.drawable.ic_trash_24,
true
)
data class SetMainAlias(val alias: String) : RoomAliasBottomSheetSharedAction(
R.string.room_settings_set_main_address
)
object UnsetMainAlias : RoomAliasBottomSheetSharedAction(
R.string.room_settings_unset_main_address
)
}

View file

@ -0,0 +1,25 @@
/*
* 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.roomprofile.alias.detail
import im.vector.app.core.platform.VectorSharedActionViewModel
import javax.inject.Inject
/**
* Activity shared view model to handle room alias quick actions
*/
class RoomAliasBottomSheetSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel<RoomAliasBottomSheetSharedAction>()

View file

@ -0,0 +1,35 @@
/*
* 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.roomprofile.alias.detail
import com.airbnb.mvrx.MvRxState
data class RoomAliasBottomSheetState(
val alias: String,
val matrixToLink: String? = null,
val isPublished: Boolean,
val isMainAlias: Boolean,
val canEditCanonicalAlias: Boolean
) : MvRxState {
constructor(args: RoomAliasBottomSheetArgs) : this(
alias = args.alias,
isPublished = args.isPublished,
isMainAlias = args.isMainAlias,
canEditCanonicalAlias = args.canEditCanonicalAlias
)
}

View file

@ -0,0 +1,58 @@
/*
* 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.roomprofile.alias.detail
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.app.core.platform.EmptyAction
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import org.matrix.android.sdk.api.session.Session
class RoomAliasBottomSheetViewModel @AssistedInject constructor(
@Assisted initialState: RoomAliasBottomSheetState,
session: Session
) : VectorViewModel<RoomAliasBottomSheetState, EmptyAction, EmptyViewEvents>(initialState) {
@AssistedInject.Factory
interface Factory {
fun create(initialState: RoomAliasBottomSheetState): RoomAliasBottomSheetViewModel
}
companion object : MvRxViewModelFactory<RoomAliasBottomSheetViewModel, RoomAliasBottomSheetState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: RoomAliasBottomSheetState): RoomAliasBottomSheetViewModel? {
val fragment: RoomAliasBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.roomAliasBottomSheetViewModelFactory.create(state)
}
}
init {
setState {
copy(
matrixToLink = session.permalinkService().createPermalink(alias)
)
}
}
override fun handle(action: EmptyAction) {
// No op
}
}

View file

@ -1,41 +1,47 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M2.25,5.5H5.1667H21.75"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"/>
<path
android:pathData="M16.5,5.5L15,1H9L7.5,5.5"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"/>
<path
android:pathData="M5.25,9.25V20.75C5.25,21.8546 6.1454,22.75 7.25,22.75H16.75C17.8546,22.75 18.75,21.8546 18.75,20.75V9.25"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"/>
<path
android:pathData="M9.75,9.25V18.25"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"/>
<path
android:pathData="M14.25,9.25V18.25"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"/>
<path
android:fillColor="#00000000"
android:pathData="M2.25,5.5H5.1667H21.75"
android:strokeWidth="2"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"
android:strokeLineJoin="round"
tools:strokeColor="@color/riotx_destructive_accent" />
<path
android:fillColor="#00000000"
android:pathData="M16.5,5.5L15,1H9L7.5,5.5"
android:strokeWidth="2"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"
android:strokeLineJoin="round"
tools:strokeColor="@color/riotx_destructive_accent" />
<path
android:fillColor="#00000000"
android:pathData="M5.25,9.25V20.75C5.25,21.8546 6.1454,22.75 7.25,22.75H16.75C17.8546,22.75 18.75,21.8546 18.75,20.75V9.25"
android:strokeWidth="2"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"
android:strokeLineJoin="round"
tools:strokeColor="@color/riotx_destructive_accent" />
<path
android:fillColor="#00000000"
android:pathData="M9.75,9.25V18.25"
android:strokeWidth="2"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"
android:strokeLineJoin="round"
tools:strokeColor="@color/riotx_destructive_accent" />
<path
android:fillColor="#00000000"
android:pathData="M14.25,9.25V18.25"
android:strokeWidth="2"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"
android:strokeLineJoin="round"
tools:strokeColor="@color/riotx_destructive_accent" />
</vector>

View file

@ -1047,6 +1047,9 @@
<string name="room_alias_local_address_empty">This room has no local addresses</string>
<string name="room_alias_local_address_add">Add a local address</string>
<string name="room_alias_action_publish">Publish this address</string>
<string name="room_alias_action_unpublish">Unpublish this address</string>
<!-- Room settings, access and visibility : WHO CAN READ HISTORY? (read rule) -->
<string name="room_settings_read_history_entry_anyone">Anyone</string>
<string name="room_settings_read_history_entry_members_only_option_time_shared">Members only (since the point in time of selecting this option)</string>