Display three pid invites in the room members list (#548)

This commit is contained in:
Benoit Marty 2020-07-09 17:28:12 +02:00
parent 3142442e5c
commit 863c09142f
8 changed files with 62 additions and 1 deletions

View file

@ -13,6 +13,7 @@ Improvements 🙌:
- Set up SSSS from security settings (#1567) - Set up SSSS from security settings (#1567)
- New lab setting to add 'unread notifications' tab to main screen - New lab setting to add 'unread notifications' tab to main screen
- Render third party invite event (#548) - Render third party invite event (#548)
- Display three pid invites in the room members list (#548)
Bugfix 🐛: Bugfix 🐛:
- Integration Manager: Wrong URL to review terms if URL in config contains path (#1606) - Integration Manager: Wrong URL to review terms if URL in config contains path (#1606)

View file

@ -72,6 +72,13 @@ class RxRoom(private val room: Room) {
} }
} }
fun liveStateEvents(eventTypes: Set<String>): Observable<List<Event>> {
return room.getStateEventsLive(eventTypes).asObservable()
.startWithCallable {
room.getStateEvents(eventTypes)
}
}
fun liveReadMarker(): Observable<Optional<String>> { fun liveReadMarker(): Observable<Optional<String>> {
return room.getReadMarkerLive().asObservable() return room.getReadMarkerLive().asObservable()
} }

View file

@ -42,7 +42,10 @@ abstract class ProfileMatrixItem : VectorEpoxyModel<ProfileMatrixItem.Holder>()
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
val bestName = matrixItem.getBestName() val bestName = matrixItem.getBestName()
val matrixId = matrixItem.id.takeIf { it != bestName } val matrixId = matrixItem.id
.takeIf { it != bestName }
// Special case for ThreePid fake matrix item
.takeIf { it != "@" }
holder.view.setOnClickListener(clickListener) holder.view.setOnClickListener(clickListener)
holder.titleView.text = bestName holder.titleView.text = bestName
holder.subtitleView.setTextOrHide(matrixId) holder.subtitleView.setTextOrHide(matrixId)

View file

@ -17,7 +17,11 @@
package im.vector.riotx.features.roomprofile.members package im.vector.riotx.features.roomprofile.members
import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.epoxy.TypedEpoxyController
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.RoomMemberSummary import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
import im.vector.matrix.android.api.session.room.model.RoomThirdPartyInviteContent
import im.vector.matrix.android.api.util.MatrixItem
import im.vector.matrix.android.api.util.toMatrixItem import im.vector.matrix.android.api.util.toMatrixItem
import im.vector.riotx.R import im.vector.riotx.R
import im.vector.riotx.core.epoxy.dividerItem import im.vector.riotx.core.epoxy.dividerItem
@ -37,6 +41,7 @@ class RoomMemberListController @Inject constructor(
interface Callback { interface Callback {
fun onRoomMemberClicked(roomMember: RoomMemberSummary) fun onRoomMemberClicked(roomMember: RoomMemberSummary)
fun onThreePidInvites(event: Event)
} }
private val dividerColor = colorProvider.getColorFromAttribute(R.attr.vctr_list_divider_color) private val dividerColor = colorProvider.getColorFromAttribute(R.attr.vctr_list_divider_color)
@ -76,5 +81,34 @@ class RoomMemberListController @Inject constructor(
} }
) )
} }
buildThreePidInvites(data)
}
private fun buildThreePidInvites(data: RoomMemberListViewState) {
if (data.threePidInvites().isNullOrEmpty()) {
return
}
buildProfileSection(
stringProvider.getString(R.string.room_member_power_level_three_pid_invites)
)
data.threePidInvites()?.forEachIndexed { idx, event ->
val content = event.content.toModel<RoomThirdPartyInviteContent>() ?: return@forEachIndexed
profileMatrixItem {
id("3pid_$idx")
matrixItem(content.toMatrixItem())
avatarRenderer(avatarRenderer)
clickListener { _ ->
callback?.onThreePidInvites(event)
}
}
}
}
private fun RoomThirdPartyInviteContent.toMatrixItem(): MatrixItem {
return MatrixItem.UserItem("@", displayName = displayName)
} }
} }

View file

@ -23,6 +23,7 @@ import android.view.View
import com.airbnb.mvrx.args import com.airbnb.mvrx.args
import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState import com.airbnb.mvrx.withState
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.room.model.RoomMemberSummary import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
import im.vector.matrix.android.api.util.toMatrixItem import im.vector.matrix.android.api.util.toMatrixItem
import im.vector.riotx.R import im.vector.riotx.R
@ -88,6 +89,10 @@ class RoomMemberListFragment @Inject constructor(
navigator.openRoomMemberProfile(roomMember.userId, roomId = roomProfileArgs.roomId, context = requireActivity()) navigator.openRoomMemberProfile(roomMember.userId, roomId = roomProfileArgs.roomId, context = requireActivity())
} }
override fun onThreePidInvites(event: Event) {
// TODO Display a bottom sheet to revoke invite if power level is high enough
}
private fun renderRoomSummary(state: RoomMemberListViewState) { private fun renderRoomSummary(state: RoomMemberListViewState) {
state.roomSummary()?.let { state.roomSummary()?.let {
roomSettingsToolbarTitleView.text = it.displayName roomSettingsToolbarTitleView.text = it.displayName

View file

@ -68,6 +68,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
init { init {
observeRoomMemberSummaries() observeRoomMemberSummaries()
observeThirdPartyInvites()
observeRoomSummary() observeRoomSummary()
observePowerLevel() observePowerLevel()
} }
@ -140,6 +141,13 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
} }
} }
private fun observeThirdPartyInvites() {
room.rx().liveStateEvents(setOf(EventType.STATE_ROOM_THIRD_PARTY_INVITE))
.execute { async ->
copy(threePidInvites = async)
}
}
private fun buildRoomMemberSummaries(powerLevelsContent: PowerLevelsContent, roomMembers: List<RoomMemberSummary>): RoomMemberSummaries { private fun buildRoomMemberSummaries(powerLevelsContent: PowerLevelsContent, roomMembers: List<RoomMemberSummary>): RoomMemberSummaries {
val admins = ArrayList<RoomMemberSummary>() val admins = ArrayList<RoomMemberSummary>()
val moderators = ArrayList<RoomMemberSummary>() val moderators = ArrayList<RoomMemberSummary>()

View file

@ -21,6 +21,7 @@ import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.MvRxState
import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.Uninitialized
import im.vector.matrix.android.api.crypto.RoomEncryptionTrustLevel import im.vector.matrix.android.api.crypto.RoomEncryptionTrustLevel
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.room.model.RoomMemberSummary import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.riotx.R import im.vector.riotx.R
@ -30,6 +31,7 @@ data class RoomMemberListViewState(
val roomId: String, val roomId: String,
val roomSummary: Async<RoomSummary> = Uninitialized, val roomSummary: Async<RoomSummary> = Uninitialized,
val roomMemberSummaries: Async<RoomMemberSummaries> = Uninitialized, val roomMemberSummaries: Async<RoomMemberSummaries> = Uninitialized,
val threePidInvites: Async<List<Event>> = Uninitialized,
val trustLevelMap: Async<Map<String, RoomEncryptionTrustLevel?>> = Uninitialized, val trustLevelMap: Async<Map<String, RoomEncryptionTrustLevel?>> = Uninitialized,
val actionsPermissions: ActionPermissions = ActionPermissions() val actionsPermissions: ActionPermissions = ActionPermissions()
) : MvRxState { ) : MvRxState {

View file

@ -2148,6 +2148,7 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming
<string name="room_member_power_level_custom">Custom</string> <string name="room_member_power_level_custom">Custom</string>
<string name="room_member_power_level_invites">Invites</string> <string name="room_member_power_level_invites">Invites</string>
<string name="room_member_power_level_users">Users</string> <string name="room_member_power_level_users">Users</string>
<string name="room_member_power_level_three_pid_invites">Other invites</string>
<string name="room_member_power_level_admin_in">Admin in %1$s</string> <string name="room_member_power_level_admin_in">Admin in %1$s</string>
<string name="room_member_power_level_moderator_in">Moderator in %1$s</string> <string name="room_member_power_level_moderator_in">Moderator in %1$s</string>