From a4d7e0bd13c707b0ea0a1bbc5af1941d80b41a3d Mon Sep 17 00:00:00 2001
From: Taras Smakula <tarassmakula@gmail.com>
Date: Mon, 30 Oct 2023 14:46:59 +0200
Subject: [PATCH] Add knock request message for profile knock request

---
 .../feature/people/PeopleDataSource.kt        | 22 ++++++-------
 .../feature/people/list/PeopleViewHolder.kt   | 12 +++++--
 .../org/futo/circles/model/PeopleListItem.kt  | 11 +++++++
 .../res/layout/list_item_people_request.xml   | 32 +++++++++++++++----
 4 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt b/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt
index 607b6b9b4..73333a296 100644
--- a/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt
+++ b/app/src/main/java/org/futo/circles/feature/people/PeopleDataSource.kt
@@ -1,7 +1,6 @@
 package org.futo.circles.feature.people
 
 import androidx.lifecycle.asFlow
-import androidx.lifecycle.map
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
@@ -9,22 +8,24 @@ import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.withContext
 import org.futo.circles.core.extensions.createResult
-import org.futo.circles.core.provider.MatrixSessionProvider
+import org.futo.circles.core.feature.room.knoks.KnockRequestsDataSource
 import org.futo.circles.core.feature.select_users.SearchUserDataSource
 import org.futo.circles.core.feature.workspace.SharedCircleDataSource
+import org.futo.circles.core.model.KnockRequestListItem
+import org.futo.circles.core.provider.MatrixSessionProvider
 import org.futo.circles.mapping.toPeopleUserListItem
 import org.futo.circles.model.PeopleHeaderItem
 import org.futo.circles.model.PeopleItemType
 import org.futo.circles.model.PeopleListItem
+import org.futo.circles.model.toPeopleRequestListItem
 import org.matrix.android.sdk.api.session.getRoom
-import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
-import org.matrix.android.sdk.api.session.room.model.Membership
 import org.matrix.android.sdk.api.session.user.model.User
 import javax.inject.Inject
 
 class PeopleDataSource @Inject constructor(
     private val searchUserDataSource: SearchUserDataSource,
-    private val sharedCircleDataSource: SharedCircleDataSource
+    private val sharedCircleDataSource: SharedCircleDataSource,
+    private val knockRequestsDataSource: KnockRequestsDataSource
 ) {
 
     private val session = MatrixSessionProvider.currentSession
@@ -37,10 +38,9 @@ class PeopleDataSource @Inject constructor(
     suspend fun declineFollowRequest(userId: String) =
         createResult { session?.getRoom(profileRoomId)?.membershipService()?.remove(userId) }
 
-    private fun getProfileRoomMembersKnockFlow(): Flow<List<User>> =
-        session?.getRoom(profileRoomId)?.membershipService()
-            ?.getRoomMembersLive(roomMemberQueryParams { memberships = listOf(Membership.KNOCK) })
-            ?.map { it.map { User(it.userId, it.displayName, it.avatarUrl) } }?.asFlow() ?: flowOf()
+    private fun getProfileRoomMembersKnockFlow(): Flow<List<KnockRequestListItem>> =
+        knockRequestsDataSource.getKnockRequestsListItemsLiveData(profileRoomId)?.asFlow()
+            ?: flowOf()
 
     suspend fun getPeopleList(query: String) = combine(
         searchUserDataSource.searchKnownUsers(query),
@@ -62,11 +62,11 @@ class PeopleDataSource @Inject constructor(
         knowUsers: List<User>,
         suggestions: List<User>,
         ignoredUsers: List<User>,
-        requests: List<User>
+        requests: List<KnockRequestListItem>
     ): List<PeopleListItem> {
         val uniqueItemsList = mutableListOf<PeopleListItem>().apply {
             addAll(ignoredUsers.map { it.toPeopleUserListItem(PeopleItemType.Ignored) })
-            addAll(requests.map { it.toPeopleUserListItem(PeopleItemType.Request) })
+            addAll(requests.map { it.toPeopleRequestListItem() })
             addAll(knowUsers.map { it.toPeopleUserListItem(getKnownUserItemType(it.userId)) })
             addAll(suggestions.map { it.toPeopleUserListItem(PeopleItemType.Suggestion) })
         }.distinctBy { it.id }.filterNot { it.id == session?.myUserId }
diff --git a/app/src/main/java/org/futo/circles/feature/people/list/PeopleViewHolder.kt b/app/src/main/java/org/futo/circles/feature/people/list/PeopleViewHolder.kt
index aedaebf89..22a0645f6 100644
--- a/app/src/main/java/org/futo/circles/feature/people/list/PeopleViewHolder.kt
+++ b/app/src/main/java/org/futo/circles/feature/people/list/PeopleViewHolder.kt
@@ -3,17 +3,19 @@ package org.futo.circles.feature.people.list
 import android.view.View
 import android.view.ViewGroup
 import androidx.recyclerview.widget.RecyclerView
+import org.futo.circles.core.base.list.ViewBindingHolder
+import org.futo.circles.core.base.list.context
 import org.futo.circles.core.databinding.ListItemInviteHeaderBinding
 import org.futo.circles.core.extensions.loadProfileIcon
 import org.futo.circles.core.extensions.onClick
-import org.futo.circles.core.base.list.ViewBindingHolder
-import org.futo.circles.core.base.list.context
+import org.futo.circles.core.extensions.setIsVisible
 import org.futo.circles.core.model.CirclesUserSummary
 import org.futo.circles.databinding.ListItemPeopleDefaultBinding
 import org.futo.circles.databinding.ListItemPeopleIgnoredBinding
 import org.futo.circles.databinding.ListItemPeopleRequestBinding
 import org.futo.circles.model.PeopleHeaderItem
 import org.futo.circles.model.PeopleListItem
+import org.futo.circles.model.PeopleRequestListItem
 import org.futo.circles.model.PeopleUserListItem
 import org.futo.circles.model.PeopleUserListItemPayload
 
@@ -81,8 +83,12 @@ class PeopleRequestUserViewHolder(
     }
 
     override fun bind(data: PeopleListItem) {
-        val user = (data as? PeopleUserListItem)?.user ?: return
+        val user = (data as? PeopleRequestListItem)?.user ?: return
         bindUser(user)
+        binding.tvReasonMessage.apply {
+            setIsVisible(data.reasonMessage != null)
+            text = data.reasonMessage
+        }
     }
 
     override fun bindPayload(data: PeopleUserListItemPayload) {
diff --git a/app/src/main/java/org/futo/circles/model/PeopleListItem.kt b/app/src/main/java/org/futo/circles/model/PeopleListItem.kt
index 87b0b0276..fc79e221d 100644
--- a/app/src/main/java/org/futo/circles/model/PeopleListItem.kt
+++ b/app/src/main/java/org/futo/circles/model/PeopleListItem.kt
@@ -3,6 +3,8 @@ package org.futo.circles.model
 import org.futo.circles.R
 import org.futo.circles.core.base.list.IdEntity
 import org.futo.circles.core.model.CirclesUserSummary
+import org.futo.circles.core.model.KnockRequestListItem
+import org.futo.circles.core.model.toCircleUser
 
 enum class PeopleItemType { Header, Friend, Following, Follower, Request, Known, Suggestion, Ignored }
 sealed class PeopleListItem(
@@ -31,3 +33,12 @@ class PeopleUserListItem(
 ) : PeopleListItem(type) {
     override val id: String = user.id
 }
+
+class PeopleRequestListItem(
+    val user: CirclesUserSummary,
+    val reasonMessage: String?
+) : PeopleListItem(PeopleItemType.Request) {
+    override val id: String = user.id
+}
+
+fun KnockRequestListItem.toPeopleRequestListItem() = PeopleRequestListItem(toCircleUser(), message)
diff --git a/app/src/main/res/layout/list_item_people_request.xml b/app/src/main/res/layout/list_item_people_request.xml
index 3363d3702..e6a90d02a 100644
--- a/app/src/main/res/layout/list_item_people_request.xml
+++ b/app/src/main/res/layout/list_item_people_request.xml
@@ -13,7 +13,6 @@
         android:layout_width="72dp"
         android:layout_height="0dp"
         android:scaleType="centerCrop"
-        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintDimensionRatio="w,1:1"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
@@ -26,10 +25,11 @@
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_marginStart="8dp"
+        android:layout_marginEnd="8dp"
         android:ellipsize="end"
         android:lines="1"
         app:layout_constraintBottom_toTopOf="@id/tvFollowText"
-        app:layout_constraintEnd_toStartOf="@id/btnAccept"
+        app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toEndOf="@id/ivUserImage"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintVertical_chainStyle="packed"
@@ -44,23 +44,42 @@
         android:lines="1"
         android:text="@string/wants_to_follow_you"
         android:textSize="13sp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/btnAccept"
+        app:layout_constraintEnd_toEndOf="@id/tvUserName"
         app:layout_constraintStart_toStartOf="@id/tvUserName"
         app:layout_constraintTop_toBottomOf="@id/tvUserName" />
 
+    <TextView
+        android:id="@+id/tvReasonMessage"
+        style="@style/subheadline"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="4dp"
+        android:ellipsize="end"
+        android:maxLines="3"
+        android:textSize="13sp"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="@id/tvUserName"
+        app:layout_constraintStart_toStartOf="@id/tvUserName"
+        app:layout_constraintTop_toBottomOf="@id/tvFollowText"
+        tools:text="Reason message messagemessagemessagemessagemessagemessagemessagemessagemessagemessagemessage"
+        tools:visibility="visible" />
+
     <com.google.android.material.button.MaterialButton
         android:id="@+id/btnAccept"
         style="@style/AccentButtonStyle"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginTop="4dp"
         android:layout_marginEnd="8dp"
         android:padding="0dp"
         android:text="@string/accept"
         android:textSize="14sp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toStartOf="@id/btnDecline"
-        app:layout_constraintTop_toTopOf="parent" />
+        app:layout_constraintStart_toEndOf="@id/ivUserImage"
+        app:layout_constraintTop_toBottomOf="@id/tvReasonMessage"
+
+        />
 
     <com.google.android.material.button.MaterialButton
         android:id="@+id/btnDecline"
@@ -72,6 +91,7 @@
         android:textSize="14sp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
+        app:layout_constraintStart_toEndOf="@id/btnAccept"
+        app:layout_constraintTop_toTopOf="@id/btnAccept" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
-- 
GitLab