From a3b33c7e89bc3859d4ea5489f5a6d7a6b16f9ef8 Mon Sep 17 00:00:00 2001
From: Taras Smakula <tarassmakula@gmail.com>
Date: Tue, 26 Dec 2023 16:19:04 +0200
Subject: [PATCH] Create new base view holder for invites

---
 .../feature/groups/list/GroupViewHolder.kt    |   2 +-
 .../org/futo/circles/view/PostHeaderView.kt   |   2 +-
 .../room/invites/list/InvitesViewHolder.kt    | 161 ++++++++++++++++++
 .../res/layout/list_item_invited_circle.xml   |   0
 .../res/layout/list_item_invited_group.xml    |   0
 .../res/layout/list_item_people_request.xml   |  96 +++++++++++
 6 files changed, 259 insertions(+), 2 deletions(-)
 create mode 100644 core/src/main/java/org/futo/circles/core/feature/room/invites/list/InvitesViewHolder.kt
 rename {app => core}/src/main/res/layout/list_item_invited_circle.xml (100%)
 rename {app => core}/src/main/res/layout/list_item_invited_group.xml (100%)
 create mode 100644 core/src/main/res/layout/list_item_people_request.xml

diff --git a/app/src/main/java/org/futo/circles/feature/groups/list/GroupViewHolder.kt b/app/src/main/java/org/futo/circles/feature/groups/list/GroupViewHolder.kt
index 19ce4ece1..5d1a0e4b6 100644
--- a/app/src/main/java/org/futo/circles/feature/groups/list/GroupViewHolder.kt
+++ b/app/src/main/java/org/futo/circles/feature/groups/list/GroupViewHolder.kt
@@ -12,9 +12,9 @@ import org.futo.circles.core.base.list.context
 import org.futo.circles.core.databinding.ListItemInviteNotificationBinding
 import org.futo.circles.core.extensions.loadRoomProfileIcon
 import org.futo.circles.core.extensions.onClick
+import org.futo.circles.core.extensions.setIsEncryptedIcon
 import org.futo.circles.core.extensions.setIsVisible
 import org.futo.circles.databinding.ListItemJoinedGroupBinding
-import org.futo.circles.extensions.setIsEncryptedIcon
 import org.futo.circles.model.GroupInvitesNotificationListItem
 import org.futo.circles.model.GroupListItem
 import org.futo.circles.model.GroupListItemPayload
diff --git a/app/src/main/java/org/futo/circles/view/PostHeaderView.kt b/app/src/main/java/org/futo/circles/view/PostHeaderView.kt
index c6d3f16bc..90d4d4dc2 100644
--- a/app/src/main/java/org/futo/circles/view/PostHeaderView.kt
+++ b/app/src/main/java/org/futo/circles/view/PostHeaderView.kt
@@ -9,12 +9,12 @@ import org.futo.circles.R
 import org.futo.circles.core.extensions.getAttributes
 import org.futo.circles.core.extensions.loadUserProfileIcon
 import org.futo.circles.core.extensions.notEmptyDisplayName
+import org.futo.circles.core.extensions.setIsEncryptedIcon
 import org.futo.circles.core.extensions.setIsVisible
 import org.futo.circles.core.model.Post
 import org.futo.circles.core.provider.MatrixSessionProvider
 import org.futo.circles.core.utils.UserUtils
 import org.futo.circles.databinding.ViewPostHeaderBinding
-import org.futo.circles.extensions.setIsEncryptedIcon
 import java.util.Date
 
 class PostHeaderView(
diff --git a/core/src/main/java/org/futo/circles/core/feature/room/invites/list/InvitesViewHolder.kt b/core/src/main/java/org/futo/circles/core/feature/room/invites/list/InvitesViewHolder.kt
new file mode 100644
index 000000000..a82827046
--- /dev/null
+++ b/core/src/main/java/org/futo/circles/core/feature/room/invites/list/InvitesViewHolder.kt
@@ -0,0 +1,161 @@
+package org.futo.circles.core.feature.room.invites.list
+
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import org.futo.circles.core.R
+import org.futo.circles.core.base.list.ViewBindingHolder
+import org.futo.circles.core.base.list.context
+import org.futo.circles.core.databinding.ListItemInvitedCircleBinding
+import org.futo.circles.core.databinding.ListItemInvitedGalleryBinding
+import org.futo.circles.core.databinding.ListItemInvitedGroupBinding
+import org.futo.circles.core.databinding.ListItemPeopleRequestBinding
+import org.futo.circles.core.extensions.loadRoomProfileIcon
+import org.futo.circles.core.extensions.loadUserProfileIcon
+import org.futo.circles.core.extensions.onClick
+import org.futo.circles.core.extensions.setIsEncryptedIcon
+import org.futo.circles.core.extensions.setIsVisible
+import org.futo.circles.core.model.CirclesUserSummary
+import org.futo.circles.core.model.FollowRequestListItem
+import org.futo.circles.core.model.InviteListItem
+import org.futo.circles.core.model.RoomInviteListItem
+
+abstract class InviteViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+    abstract fun bind(data: InviteListItem)
+}
+
+
+class InvitedGroupViewHolder(
+    parent: ViewGroup,
+    onInviteClicked: (Int, Boolean) -> Unit,
+    onShowProfileIconClicked: (Int) -> Unit
+) : InviteViewHolder(inflate(parent, ListItemInvitedGroupBinding::inflate)) {
+
+    private companion object : ViewBindingHolder
+
+    private val binding = baseBinding as ListItemInvitedGroupBinding
+
+    init {
+        onClick(binding.btnAccept) { position -> onInviteClicked(position, true) }
+        onClick(binding.btnDecline) { position -> onInviteClicked(position, false) }
+        onClick(binding.ivGroup) { position -> onShowProfileIconClicked(position) }
+    }
+
+    override fun bind(data: InviteListItem) {
+        if (data !is RoomInviteListItem) return
+
+        with(binding) {
+            ivGroup.loadRoomProfileIcon(
+                data.info.avatarUrl,
+                data.info.title,
+                applyBlur = data.shouldBlurIcon
+            )
+            tvShowProfileImage.setIsVisible(data.shouldBlurIcon)
+            ivLock.setIsEncryptedIcon(data.isEncrypted)
+            tvGroupTitle.text = data.info.title
+            tvInviterName.text = context.getString(
+                R.string.invited_by_format,
+                data.inviterName
+            )
+        }
+    }
+}
+
+class InvitedCircleViewHolder(
+    parent: ViewGroup,
+    onInviteClicked: (Int, Boolean) -> Unit,
+    onShowProfileIconClicked: (Int) -> Unit
+) : InviteViewHolder(inflate(parent, ListItemInvitedCircleBinding::inflate)) {
+
+    private companion object : ViewBindingHolder
+
+    private val binding = baseBinding as ListItemInvitedCircleBinding
+
+    init {
+        onClick(binding.btnAccept) { position -> onInviteClicked(position, true) }
+        onClick(binding.btnDecline) { position -> onInviteClicked(position, false) }
+        onClick(binding.ivCircle) { position -> onShowProfileIconClicked(position) }
+    }
+
+    override fun bind(data: InviteListItem) {
+        if (data !is RoomInviteListItem) return
+
+        with(binding) {
+            tvShowProfileImage.setIsVisible(data.shouldBlurIcon)
+            ivCircle.loadRoomProfileIcon(
+                data.info.avatarUrl,
+                data.info.title,
+                applyBlur = data.shouldBlurIcon
+            )
+            tvCircleTitle.text = data.info.title
+            binding.tvInvitedBy.text =
+                context.getString(
+                    R.string.invited_by_format,
+                    data.inviterName
+                )
+        }
+    }
+}
+
+class InvitedGalleryViewHolder(
+    parent: ViewGroup,
+    onInviteClicked: (Int, Boolean) -> Unit,
+    onShowProfileIconClicked: (Int) -> Unit
+) : InviteViewHolder(inflate(parent, ListItemInvitedGalleryBinding::inflate)) {
+
+    private companion object : ViewBindingHolder
+
+    private val binding = baseBinding as ListItemInvitedGalleryBinding
+
+    init {
+        onClick(binding.btnAccept) { position -> onInviteClicked(position, true) }
+        onClick(binding.btnDecline) { position -> onInviteClicked(position, false) }
+        onClick(binding.ivGallery) { position -> onShowProfileIconClicked(position) }
+    }
+
+    override fun bind(data: InviteListItem) {
+        if (data !is RoomInviteListItem) return
+
+        with(binding) {
+            tvGalleryTitle.text = data.info.title
+            ivGallery.loadRoomProfileIcon(
+                data.info.avatarUrl,
+                data.info.title,
+                applyBlur = data.shouldBlurIcon
+            )
+            tvShowProfileImage.setIsVisible(data.shouldBlurIcon)
+            tvInviterName.text = context.getString(R.string.invited_by_format, data.inviterName)
+        }
+    }
+}
+
+class FollowRequestViewHolder(
+    parent: ViewGroup,
+    private val onRequestClicked: (Int, Boolean) -> Unit
+) : InviteViewHolder(inflate(parent, ListItemPeopleRequestBinding::inflate)) {
+
+    private companion object : ViewBindingHolder
+
+    private val binding = baseBinding as ListItemPeopleRequestBinding
+
+    init {
+        onClick(binding.btnAccept) { position -> onRequestClicked(position, true) }
+        onClick(binding.btnDecline) { position -> onRequestClicked(position, false) }
+    }
+
+    override fun bind(data: InviteListItem) {
+        val user = (data as? FollowRequestListItem)?.user ?: return
+        bindUser(user)
+        binding.tvReasonMessage.apply {
+            setIsVisible(data.reasonMessage != null)
+            text = data.reasonMessage
+        }
+    }
+
+    private fun bindUser(user: CirclesUserSummary) {
+        with(binding) {
+            tvUserName.text = user.name
+            ivUserImage.loadUserProfileIcon(user.avatarUrl, user.id)
+        }
+    }
+}
diff --git a/app/src/main/res/layout/list_item_invited_circle.xml b/core/src/main/res/layout/list_item_invited_circle.xml
similarity index 100%
rename from app/src/main/res/layout/list_item_invited_circle.xml
rename to core/src/main/res/layout/list_item_invited_circle.xml
diff --git a/app/src/main/res/layout/list_item_invited_group.xml b/core/src/main/res/layout/list_item_invited_group.xml
similarity index 100%
rename from app/src/main/res/layout/list_item_invited_group.xml
rename to core/src/main/res/layout/list_item_invited_group.xml
diff --git a/core/src/main/res/layout/list_item_people_request.xml b/core/src/main/res/layout/list_item_people_request.xml
new file mode 100644
index 000000000..1c760fdfa
--- /dev/null
+++ b/core/src/main/res/layout/list_item_people_request.xml
@@ -0,0 +1,96 @@
+<?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:paddingHorizontal="8dp"
+    android:paddingVertical="4dp"
+    tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
+
+    <com.google.android.material.imageview.ShapeableImageView
+        android:id="@+id/ivUserImage"
+        android:layout_width="72dp"
+        android:layout_height="72dp"
+        android:scaleType="centerCrop"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.CornerSize50Percent"
+        tools:background="@color/blue" />
+
+    <TextView
+        android:id="@+id/tvUserName"
+        style="@style/title2"
+        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_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/ivUserImage"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_chainStyle="packed"
+        tools:text="Android01" />
+
+    <TextView
+        android:id="@+id/tvFollowText"
+        style="@style/subheadline"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:lines="1"
+        android:text="@string/wants_to_follow_you"
+        android:textSize="13sp"
+        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_constraintStart_toEndOf="@id/ivUserImage"
+        app:layout_constraintTop_toBottomOf="@id/tvReasonMessage"
+
+        />
+
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/btnDecline"
+        style="@style/NegativeButtonStyle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="0dp"
+        android:text="@string/decline"
+        android:textSize="14sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/btnAccept"
+        app:layout_constraintTop_toTopOf="@id/btnAccept" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
-- 
GitLab