Implementation of canonical alias.

This commit is contained in:
onurays 2020-06-23 10:01:04 +03:00 committed by Benoit Marty
parent f5790e5dc2
commit 762dd1d0a5
10 changed files with 184 additions and 0 deletions

View File

@ -111,6 +111,10 @@ class RxRoom(private val room: Room) {
room.updateName(name, it)
}
fun updateCanonicalAlias(alias: String): Completable = completableBuilder<Unit> {
room.updateCanonicalAlias(alias, it)
}
fun updateHistoryReadability(readability: String) = completableBuilder<Unit> {
room.updateHistoryReadability(readability, it)
}

View File

@ -37,6 +37,11 @@ interface StateService {
*/
fun updateName(name: String, callback: MatrixCallback<Unit>): Cancelable
/**
* Update the canonical alias of the room
*/
fun updateCanonicalAlias(alias: String, callback: MatrixCallback<Unit>): Cancelable
/**
* Update the history readability of the room
*/

View File

@ -111,6 +111,15 @@ internal class DefaultStateService @AssistedInject constructor(@Assisted private
)
}
override fun updateCanonicalAlias(alias: String, callback: MatrixCallback<Unit>): Cancelable {
return sendStateEvent(
eventType = EventType.STATE_ROOM_CANONICAL_ALIAS,
body = mapOf("alias" to alias),
callback = callback,
stateKey = null
)
}
override fun updateHistoryReadability(readability: String, callback: MatrixCallback<Unit>): Cancelable {
return sendStateEvent(
eventType = EventType.STATE_ROOM_HISTORY_VISIBILITY,

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2020 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.riotx.features.form
import android.text.Editable
import android.view.View
import androidx.appcompat.widget.AppCompatButton
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import im.vector.riotx.R
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
import im.vector.riotx.core.epoxy.VectorEpoxyModel
import im.vector.riotx.core.platform.SimpleTextWatcher
@EpoxyModelClass(layout = R.layout.item_form_text_input_with_button)
abstract class FormEditTextWithButtonItem : VectorEpoxyModel<FormEditTextWithButtonItem.Holder>() {
@EpoxyAttribute
var hint: String? = null
@EpoxyAttribute
var value: String? = null
@EpoxyAttribute
var enabled: Boolean = true
@EpoxyAttribute
var buttonText: String? = null
@EpoxyAttribute
var onTextChange: ((String) -> Unit)? = null
@EpoxyAttribute
var onButtonClicked: ((View) -> Unit)? = null
private val onTextChangeListener = object : SimpleTextWatcher() {
override fun afterTextChanged(s: Editable) {
onTextChange?.invoke(s.toString())
}
}
override fun bind(holder: Holder) {
holder.textInputLayout.isEnabled = enabled
holder.textInputLayout.hint = hint
// Update only if text is different
if (holder.textInputEditText.text.toString() != value) {
holder.textInputEditText.setText(value)
}
holder.textInputEditText.isEnabled = enabled
holder.textInputEditText.addTextChangedListener(onTextChangeListener)
holder.textInputButton.text = buttonText
holder.textInputButton.setOnClickListener(onButtonClicked)
}
override fun shouldSaveViewState(): Boolean {
return false
}
override fun unbind(holder: Holder) {
super.unbind(holder)
holder.textInputEditText.removeTextChangedListener(onTextChangeListener)
}
class Holder : VectorEpoxyHolder() {
val textInputLayout by bind<TextInputLayout>(R.id.formTextInputTextInputLayout)
val textInputEditText by bind<TextInputEditText>(R.id.formTextInputTextInputEditText)
val textInputButton by bind<AppCompatButton>(R.id.formTextInputButton)
}
}

View File

@ -25,6 +25,7 @@ sealed class RoomSettingsAction : VectorViewModelAction {
data class SetRoomTopic(val newTopic: String) : RoomSettingsAction()
data class SetRoomAvatar(val image: MultiPickerImageType) : RoomSettingsAction()
data class SetRoomHistoryVisibility(val visibility: RoomHistoryVisibility) : RoomSettingsAction()
data class SetRoomAlias(val alias: String) : RoomSettingsAction()
object EnableEncryption : RoomSettingsAction()
object Save : RoomSettingsAction()
}

View File

@ -44,6 +44,7 @@ class RoomSettingsController @Inject constructor(
fun onTopicChanged(topic: String)
fun onPhotoClicked()
fun onHistoryVisibilityClicked()
fun onAliasChanged(alias: String)
}
private val dividerColor = colorProvider.getColorFromAttribute(R.attr.vctr_list_divider_color)
@ -86,6 +87,17 @@ class RoomSettingsController @Inject constructor(
}
}
formEditTextItem {
id("alias")
/*enabled(enableFormElement)*/
value(data.newAlias ?: roomSummary.canonicalAlias)
hint(stringProvider.getString(R.string.room_settings_addresses_add_new_address))
onTextChange { text ->
callback?.onAliasChanged(text)
}
}
buildProfileAction(
id = "historyReadability",
title = stringProvider.getString(R.string.room_settings_room_read_history_rules_pref_title),

View File

@ -190,4 +190,8 @@ class RoomSettingsFragment @Inject constructor(
RoomHistoryVisibility.WORLD_READABLE -> stringProvider.getString(R.string.notice_room_visibility_world_readable)
}
}
override fun onAliasChanged(alias: String) {
viewModel.handle(RoomSettingsAction.SetRoomAlias(alias))
}
}

View File

@ -89,6 +89,10 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
setState { copy(newHistoryVisibility = action.visibility) }
setState { copy(showSaveAction = shouldShowSaveAction(this)) }
}
is RoomSettingsAction.SetRoomAlias -> {
setState { copy(newAlias = action.alias) }
setState { copy(showSaveAction = shouldShowSaveAction(this)) }
}
is RoomSettingsAction.Save -> saveSettings()
}
}
@ -97,6 +101,7 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
val summary = state.roomSummary.invoke()
return summary?.displayName != state.newName ||
summary?.topic != state.newTopic ||
summary?.canonicalAlias != state.newAlias ||
state.newHistoryVisibility != null ||
state.newAvatar != null
}
@ -115,6 +120,10 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
operationList.add(room.rx().updateTopic(state.newTopic ?: ""))
}
if (summary?.canonicalAlias != state.newAlias) {
operationList.add(room.rx().updateCanonicalAlias(state.newAlias ?: ""))
}
if (state.newHistoryVisibility != null) {
operationList.add(room.rx().updateHistoryReadability(state.newHistoryVisibility.name.toLowerCase(Locale.ROOT)))
}

View File

@ -34,6 +34,7 @@ data class RoomSettingsViewState(
val newTopic: String? = null,
val newAvatar: MultiPickerImageType? = null,
val newHistoryVisibility: RoomHistoryVisibility? = null,
val newAlias: String? = null,
val showSaveAction: Boolean = false
) : MvRxState {

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?riotx_background"
android:minHeight="@dimen/item_form_min_height">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/formTextInputTextInputLayout"
style="@style/VectorTextInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/layout_horizontal_margin"
android:layout_marginEnd="@dimen/layout_horizontal_margin"
app:layout_constraintBottom_toTopOf="@+id/formTextInputDivider"
app:layout_constraintEnd_toStartOf="@id/formTextInputButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/formTextInputTextInputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:hint="@string/create_room_name_hint" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/formTextInputButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/layout_horizontal_margin"
app:layout_constraintBottom_toBottomOf="@id/formTextInputTextInputLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/formTextInputTextInputLayout"
android:background="?attr/colorAccent"
tools:text="Add"/>
<View
android:id="@+id/formTextInputDivider"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="?riotx_header_panel_border_mobile"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>