From 38fdfb27e4bb495f0f99ad5ec50c0d81f7917bfe Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 10 Feb 2022 14:20:47 +0100 Subject: [PATCH] Creating sealed wrapper class for member items --- .../matrix/android/sdk/api/util/MatrixItem.kt | 1 + .../autocomplete/AutocompleteMatrixItem.kt | 2 +- .../member/AutocompleteMemberController.kt | 37 +++++++++++++------ .../member/AutocompleteMemberItem.kt | 26 +++++++++++++ .../member/AutocompleteMemberPresenter.kt | 10 ++--- .../home/room/detail/AutoCompleter.kt | 14 ++++--- .../app/features/html/PillsPostProcessor.kt | 1 + 7 files changed, 69 insertions(+), 22 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt index 3396c4a6c9..31dcd007a2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt @@ -27,6 +27,7 @@ import org.matrix.android.sdk.api.session.room.sender.SenderInfo import org.matrix.android.sdk.api.session.user.model.User import java.util.Locale +// TODO how to represent the notify everyone @room item? EveryoneItem ?? sealed class MatrixItem( open val id: String, open val displayName: String?, diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt index 54d809d948..d0e2c81b56 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt @@ -30,7 +30,7 @@ import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.MatrixItem -// TODO create a new item for sections +// TODO create a new item for sections: AutocompleteSection @EpoxyModelClass(layout = R.layout.item_autocomplete_matrix_item) abstract class AutocompleteMatrixItem : VectorEpoxyModel() { diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt index 9b4bd78504..5bbd4a3996 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt @@ -20,28 +20,43 @@ import com.airbnb.epoxy.TypedEpoxyController import im.vector.app.features.autocomplete.AutocompleteClickListener import im.vector.app.features.autocomplete.autocompleteMatrixItem import im.vector.app.features.home.AvatarRenderer -import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject -class AutocompleteMemberController @Inject constructor() : TypedEpoxyController>() { +class AutocompleteMemberController @Inject constructor() : TypedEpoxyController>() { - var listener: AutocompleteClickListener? = null + var listener: AutocompleteClickListener? = null @Inject lateinit var avatarRenderer: AvatarRenderer - override fun buildModels(data: List?) { + override fun buildModels(data: List?) { if (data.isNullOrEmpty()) { return } - val host = this - data.forEach { user -> - autocompleteMatrixItem { - id(user.userId) - matrixItem(user.toMatrixItem()) - avatarRenderer(host.avatarRenderer) - clickListener { host.listener?.onItemClick(user) } + data.forEach { item -> + when (item) { + is AutocompleteMemberItem.RoomMember -> buildRoomMemberItem(item) + is AutocompleteMemberItem.Everyone -> buildEveryoneItem(item) } } } + + /////////////////////////////////////////////////////////////////////////// + // HELPER METHODS + /////////////////////////////////////////////////////////////////////////// + + private fun buildRoomMemberItem(roomMember: AutocompleteMemberItem.RoomMember) { + autocompleteMatrixItem { + roomMember.roomMemberSummary.let { user -> + id(user.userId) + matrixItem(user.toMatrixItem()) + avatarRenderer(this@AutocompleteMemberController.avatarRenderer) + clickListener { this@AutocompleteMemberController.listener?.onItemClick(roomMember) } + } + } + } + + private fun buildEveryoneItem(everyone: AutocompleteMemberItem.Everyone) { + // TODO + } } diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt new file mode 100644 index 0000000000..fa9693895f --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 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.autocomplete.member + +import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary +import org.matrix.android.sdk.api.session.room.model.RoomSummary + +sealed class AutocompleteMemberItem { + // TODO add section class + data class RoomMember(val roomMemberSummary: RoomMemberSummary) : AutocompleteMemberItem() + data class Everyone(val roomSummary: RoomSummary) : AutocompleteMemberItem() +} diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt index 6624a15916..bb7d41cc46 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt @@ -33,7 +33,7 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, @Assisted val roomId: String, session: Session, private val controller: AutocompleteMemberController -) : RecyclerViewPresenter(context), AutocompleteClickListener { +) : RecyclerViewPresenter(context), AutocompleteClickListener { private val room by lazy { session.getRoom(roomId)!! } @@ -54,7 +54,7 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, return controller.adapter } - override fun onItemClick(t: RoomMemberSummary) { + override fun onItemClick(t: AutocompleteMemberItem) { dispatchClick(t) } @@ -72,10 +72,10 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, .asSequence() .sortedBy { it.displayName } .disambiguate() - // TODO check if user can notify everyone => compare user role to room permission setting - // TODO if user can notify everyone, add entry "@room" + // TODO check if user can notify everyone => compare user role to room permission setting: PowerLevelsContent + // TODO if user can notify everyone, add entry AutocompleteMemberItem.Everyone // TODO add header sections to separate members and notification - controller.setData(members.toList()) + controller.setData(members.map { AutocompleteMemberItem.RoomMember(it) }.toList()) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt index 9f85d4015b..88e49f7062 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt @@ -33,6 +33,7 @@ import im.vector.app.features.autocomplete.command.AutocompleteCommandPresenter import im.vector.app.features.autocomplete.command.CommandAutocompletePolicy import im.vector.app.features.autocomplete.emoji.AutocompleteEmojiPresenter import im.vector.app.features.autocomplete.group.AutocompleteGroupPresenter +import im.vector.app.features.autocomplete.member.AutocompleteMemberItem import im.vector.app.features.autocomplete.member.AutocompleteMemberPresenter import im.vector.app.features.autocomplete.room.AutocompleteRoomPresenter import im.vector.app.features.command.Command @@ -41,7 +42,6 @@ import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.html.PillImageSpan import im.vector.app.features.themes.ThemeUtils import org.matrix.android.sdk.api.session.group.model.GroupSummary -import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem @@ -125,14 +125,18 @@ class AutoCompleter @AssistedInject constructor( private fun setupMembers(backgroundDrawable: ColorDrawable, editText: EditText) { autocompleteMemberPresenter = autocompleteMemberPresenterFactory.create(roomId) - Autocomplete.on(editText) + Autocomplete.on(editText) .with(CharPolicy('@', true)) .with(autocompleteMemberPresenter) .with(ELEVATION) .with(backgroundDrawable) - .with(object : AutocompleteCallback { - override fun onPopupItemClicked(editable: Editable, item: RoomMemberSummary): Boolean { - insertMatrixItem(editText, editable, "@", item.toMatrixItem()) + .with(object : AutocompleteCallback { + override fun onPopupItemClicked(editable: Editable, item: AutocompleteMemberItem): Boolean { + when (item) { + is AutocompleteMemberItem.RoomMember -> + insertMatrixItem(editText, editable, "@", item.roomMemberSummary.toMatrixItem()) + is AutocompleteMemberItem.Everyone -> Unit // TODO + } return true } diff --git a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt index f8a2ee5137..8376d25065 100644 --- a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt @@ -59,6 +59,7 @@ class PillsPostProcessor @AssistedInject constructor(@Assisted private val roomI } private fun LinkSpan.createPillSpan(roomId: String?): PillImageSpan? { + // TODO handle @room text to create associated chip val permalinkData = PermalinkParser.parse(url) val matrixItem = when (permalinkData) { is PermalinkData.UserLink -> {