From a58bb776f3db777f83c8e7840ee5ed6d4af8f11d Mon Sep 17 00:00:00 2001
From: Benoit Marty <benoitm@matrix.org>
Date: Fri, 10 Jul 2020 10:14:02 +0200
Subject: [PATCH] Display threePid invite along with the other invite (code is
 a bit dirty)

---
 .../vector/riotx/core/extensions/Iterable.kt  |  6 +-
 .../members/RoomMemberListController.kt       | 83 +++++++++++++------
 vector/src/main/res/values/strings.xml        |  1 -
 3 files changed, 61 insertions(+), 29 deletions(-)

diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Iterable.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Iterable.kt
index 987194ea2f..b9907f8789 100644
--- a/vector/src/main/java/im/vector/riotx/core/extensions/Iterable.kt
+++ b/vector/src/main/java/im/vector/riotx/core/extensions/Iterable.kt
@@ -38,13 +38,13 @@ inline fun <T, R : Comparable<R>> Iterable<T>.lastMinBy(selector: (T) -> R): T?
 /**
  * Call each for each item, and between between each items
  */
-inline fun <T> Collection<T>.join(each: (T) -> Unit, between: (T) -> Unit) {
+inline fun <T> Collection<T>.join(each: (Int, T) -> Unit, between: (Int, T) -> Unit) {
     val lastIndex = size - 1
     forEachIndexed { idx, t ->
-        each(t)
+        each(idx, t)
 
         if (idx != lastIndex) {
-            between(t)
+            between(idx, t)
         }
     }
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/roomprofile/members/RoomMemberListController.kt b/vector/src/main/java/im/vector/riotx/features/roomprofile/members/RoomMemberListController.kt
index 495d1164a5..8cf93e8589 100644
--- a/vector/src/main/java/im/vector/riotx/features/roomprofile/members/RoomMemberListController.kt
+++ b/vector/src/main/java/im/vector/riotx/features/roomprofile/members/RoomMemberListController.kt
@@ -54,15 +54,29 @@ class RoomMemberListController @Inject constructor(
 
     override fun buildModels(data: RoomMemberListViewState?) {
         val roomMembersByPowerLevel = data?.roomMemberSummaries?.invoke() ?: return
+        val threePidInvites = data.threePidInvites().orEmpty()
+        var threePidInvitesDone = threePidInvites.isEmpty()
+
         for ((powerLevelCategory, roomMemberList) in roomMembersByPowerLevel) {
             if (roomMemberList.isEmpty()) {
                 continue
             }
+
+            if (powerLevelCategory == RoomMemberListCategories.USER && !threePidInvitesDone) {
+                // If there is not regular invite, display threepid invite before the regular user
+                buildProfileSection(
+                        stringProvider.getString(RoomMemberListCategories.INVITE.titleRes)
+                )
+
+                buildThreePidInvites(data)
+                threePidInvitesDone = true
+            }
+
             buildProfileSection(
                     stringProvider.getString(powerLevelCategory.titleRes)
             )
             roomMemberList.join(
-                    each = { roomMember ->
+                    each = { _, roomMember ->
                         profileMatrixItem {
                             id(roomMember.userId)
                             matrixItem(roomMember.toMatrixItem())
@@ -73,40 +87,59 @@ class RoomMemberListController @Inject constructor(
                             }
                         }
                     },
-                    between = { roomMemberBefore ->
+                    between = { _, roomMemberBefore ->
                         dividerItem {
                             id("divider_${roomMemberBefore.userId}")
                             color(dividerColor)
                         }
                     }
             )
+            if (powerLevelCategory == RoomMemberListCategories.INVITE) {
+                // Display the threepid invite after the regular invite
+                dividerItem {
+                    id("divider_threepidinvites")
+                    color(dividerColor)
+                }
+                buildThreePidInvites(data)
+                threePidInvitesDone = true
+            }
+        }
+
+        if (!threePidInvitesDone) {
+            // If there is not regular invite and no regular user, finally display threepid invite here
+            buildProfileSection(
+                    stringProvider.getString(RoomMemberListCategories.INVITE.titleRes)
+            )
+
+            buildThreePidInvites(data)
         }
-        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)
-                editable(data.actionsPermissions.canRevokeThreePidInvite)
-                clickListener { _ ->
-                    callback?.onThreePidInvites(event)
-                }
-            }
-
-        }
+        data.threePidInvites()
+                ?.filter { it.content.toModel<RoomThirdPartyInviteContent>() != null }
+                ?.join(
+                        each = { idx, event ->
+                            event.content.toModel<RoomThirdPartyInviteContent>()
+                                    ?.let { content ->
+                                        profileMatrixItem {
+                                            id("3pid_$idx")
+                                            matrixItem(content.toMatrixItem())
+                                            avatarRenderer(avatarRenderer)
+                                            editable(data.actionsPermissions.canRevokeThreePidInvite)
+                                            clickListener { _ ->
+                                                callback?.onThreePidInvites(event)
+                                            }
+                                        }
+                                    }
+                        },
+                        between = { idx, _ ->
+                            dividerItem {
+                                id("divider3_$idx")
+                                color(dividerColor)
+                            }
+                        }
+                )
     }
 
     private fun RoomThirdPartyInviteContent.toMatrixItem(): MatrixItem {
diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml
index 15b658caeb..be7602af51 100644
--- a/vector/src/main/res/values/strings.xml
+++ b/vector/src/main/res/values/strings.xml
@@ -2148,7 +2148,6 @@ 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_invites">Invites</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_moderator_in">Moderator in %1$s</string>