From 50385082423aa90f8e7a46a7902fc66a58fbfdf3 Mon Sep 17 00:00:00 2001
From: Taras <tarassmakula@gmail.com>
Date: Tue, 1 Mar 2022 22:21:16 +0200
Subject: [PATCH] Create view types for invite list

---
 .../InviteMembersDialogFragment.kt            | 12 +---
 .../group_invite/InviteMembersViewModel.kt    | 14 ++--
 .../data_source/InviteMembersDataSource.kt    | 30 ++++++--
 .../list/InviteMemberViewHolder.kt            | 70 +++++++++++++++++--
 .../list/InviteMembersListAdapter.kt          | 29 ++++++--
 .../group_timeline/GroupTimelineFragment.kt   |  2 +-
 .../futo/circles/mapping/MatrixUserMapping.kt |  4 +-
 .../circles/model/InviteMemberListItem.kt     | 30 ++++++++
 .../futo/circles/model/RoomMemberListItem.kt  | 10 ---
 .../res/layout/group_timeline_fragment.xml    |  4 +-
 .../res/layout/invite_header_list_item.xml    |  9 +++
 .../res/layout/invite_member_list_item.xml    | 15 ----
 .../layout/invite_members_dialog_fragment.xml |  1 -
 .../main/res/layout/no_results_list_item.xml  | 12 ++++
 app/src/main/res/layout/user_list_item.xml    | 51 ++++++++++++++
 app/src/main/res/values/dimens.xml            |  1 +
 app/src/main/res/values/strings.xml           |  3 +
 17 files changed, 233 insertions(+), 64 deletions(-)
 create mode 100644 app/src/main/java/com/futo/circles/model/InviteMemberListItem.kt
 delete mode 100644 app/src/main/java/com/futo/circles/model/RoomMemberListItem.kt
 create mode 100644 app/src/main/res/layout/invite_header_list_item.xml
 delete mode 100644 app/src/main/res/layout/invite_member_list_item.xml
 create mode 100644 app/src/main/res/layout/no_results_list_item.xml
 create mode 100644 app/src/main/res/layout/user_list_item.xml

diff --git a/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersDialogFragment.kt b/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersDialogFragment.kt
index ecbb830d9..8812ae6f4 100644
--- a/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersDialogFragment.kt
+++ b/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersDialogFragment.kt
@@ -9,7 +9,6 @@ import com.futo.circles.databinding.InviteMembersDialogFragmentBinding
 import com.futo.circles.extensions.getQueryTextChangeStateFlow
 import com.futo.circles.extensions.observeData
 import com.futo.circles.feature.group_invite.list.InviteMembersListAdapter
-import com.futo.circles.model.RoomMemberListItem
 import org.koin.androidx.viewmodel.ext.android.viewModel
 import org.koin.core.parameter.parametersOf
 
@@ -20,7 +19,7 @@ class InviteMembersDialogFragment :
     private val args: InviteMembersDialogFragmentArgs by navArgs()
     private val viewModel by viewModel<InviteMembersViewModel> { parametersOf(args.roomId) }
 
-    private val listAdapter by lazy { InviteMembersListAdapter() }
+    private val listAdapter by lazy { InviteMembersListAdapter(viewModel::onUserSelected) }
 
     private val binding by lazy {
         getBinding() as InviteMembersDialogFragmentBinding
@@ -45,13 +44,8 @@ class InviteMembersDialogFragment :
             binding.toolbar.title = it
         }
 
-        viewModel.usersLiveData.observeData(this) { users ->
-            setUserList(users)
+        viewModel.usersLiveData.observeData(this) { items ->
+            listAdapter.submitList(items)
         }
     }
-
-    private fun setUserList(users: List<RoomMemberListItem>) {
-        listAdapter.submitList(users)
-    }
-
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersViewModel.kt b/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersViewModel.kt
index 380096d8c..edc85c1f8 100644
--- a/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersViewModel.kt
+++ b/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersViewModel.kt
@@ -1,11 +1,11 @@
 package com.futo.circles.feature.group_invite
 
-import android.util.Log
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
 import com.futo.circles.extensions.launchUi
 import com.futo.circles.feature.group_invite.data_source.InviteMembersDataSource
-import com.futo.circles.model.RoomMemberListItem
+import com.futo.circles.model.InviteMemberListItem
+import com.futo.circles.model.CirclesUser
 import kotlinx.coroutines.flow.*
 
 class InviteMembersViewModel(
@@ -14,7 +14,7 @@ class InviteMembersViewModel(
 
     val titleLiveData = MutableLiveData(dataSource.getInviteTitle())
 
-    val usersLiveData = MutableLiveData<List<RoomMemberListItem>>()
+    val usersLiveData = MutableLiveData<List<InviteMemberListItem>>()
 
     fun initSearchListener(queryFlow: StateFlow<String>) {
         launchUi {
@@ -22,12 +22,12 @@ class InviteMembersViewModel(
                 .debounce(500)
                 .distinctUntilChanged()
                 .flatMapLatest { query -> dataSource.search(query) }
-                .collectLatest { members ->
-                    usersLiveData.postValue(members)
-                    Log.d("MyLog", members.size.toString())
-                }
+                .collectLatest { items -> usersLiveData.postValue(items) }
         }
     }
 
+    fun onUserSelected(member: CirclesUser){
+
+    }
 
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/futo/circles/feature/group_invite/data_source/InviteMembersDataSource.kt b/app/src/main/java/com/futo/circles/feature/group_invite/data_source/InviteMembersDataSource.kt
index 258a426ea..db6623d8b 100644
--- a/app/src/main/java/com/futo/circles/feature/group_invite/data_source/InviteMembersDataSource.kt
+++ b/app/src/main/java/com/futo/circles/feature/group_invite/data_source/InviteMembersDataSource.kt
@@ -4,7 +4,10 @@ import android.content.Context
 import androidx.lifecycle.asFlow
 import com.futo.circles.R
 import com.futo.circles.extensions.nameOrId
-import com.futo.circles.mapping.toRoomMember
+import com.futo.circles.mapping.toCirclesUser
+import com.futo.circles.model.HeaderItem
+import com.futo.circles.model.InviteMemberListItem
+import com.futo.circles.model.NoResultsItem
 import com.futo.circles.provider.MatrixSessionProvider
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.*
@@ -27,7 +30,7 @@ class InviteMembersDataSource(
 
     suspend fun search(query: String) = combine(searchKnownUsers(query), searchSuggestions(query))
     { knowUsers, suggestions ->
-        (knowUsers + suggestions).distinctBy { it.userId }.map { it.toRoomMember() }
+        buildList(knowUsers, suggestions)
     }.flowOn(Dispatchers.IO).distinctUntilChanged()
 
 
@@ -46,9 +49,28 @@ class InviteMembersDataSource(
         emit(users ?: emptyList())
     }
 
+    private fun buildList(
+        knowUsers: List<User>,
+        suggestions: List<User>
+    ): List<InviteMemberListItem> {
+        val list = mutableListOf<InviteMemberListItem>()
+        if (knowUsers.isNotEmpty()) {
+            list.add(HeaderItem.knownUsersHeader)
+            list.addAll(knowUsers.map { it.toCirclesUser() })
+        }
 
-    private companion object {
-        private const val MAX_SUGGESTION_COUNT = 50
+        val knowUsersIds = knowUsers.map { it.userId }
+        val filteredSuggestion = suggestions.filterNot { knowUsersIds.contains(it.userId) }
+        if (filteredSuggestion.isNotEmpty()) {
+            list.add(HeaderItem.suggestionHeader)
+            list.addAll(filteredSuggestion.map { it.toCirclesUser() })
+        }
+
+        if (list.isEmpty()) list.add(NoResultsItem())
+        return list
     }
 
+    private companion object {
+        private const val MAX_SUGGESTION_COUNT = 25
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/futo/circles/feature/group_invite/list/InviteMemberViewHolder.kt b/app/src/main/java/com/futo/circles/feature/group_invite/list/InviteMemberViewHolder.kt
index c2894e761..b06a8a015 100644
--- a/app/src/main/java/com/futo/circles/feature/group_invite/list/InviteMemberViewHolder.kt
+++ b/app/src/main/java/com/futo/circles/feature/group_invite/list/InviteMemberViewHolder.kt
@@ -1,22 +1,78 @@
 package com.futo.circles.feature.group_invite.list
 
+import android.util.Size
+import android.view.View
 import android.view.ViewGroup
 import androidx.recyclerview.widget.RecyclerView
 import com.futo.circles.base.ViewBindingHolder
-import com.futo.circles.databinding.InviteMemberListItemBinding
-import com.futo.circles.model.RoomMemberListItem
+import com.futo.circles.base.context
+import com.futo.circles.databinding.InviteHeaderListItemBinding
+import com.futo.circles.databinding.NoResultsListItemBinding
+import com.futo.circles.databinding.UserListItemBinding
+import com.futo.circles.extensions.loadImage
+import com.futo.circles.extensions.onClick
+import com.futo.circles.model.HeaderItem
+import com.futo.circles.model.InviteMemberListItem
+import com.futo.circles.model.NoResultsItem
+import com.futo.circles.model.CirclesUser
 
-class InviteMemberViewHolder(
+abstract class InviteMemberViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+    abstract fun bind(data: InviteMemberListItem)
+}
+
+class UserViewHolder(
+    parent: ViewGroup,
+    private val onMemberClicked: (Int) -> Unit
+) : InviteMemberViewHolder(inflate(parent, UserListItemBinding::inflate)) {
+
+    private companion object : ViewBindingHolder
+
+    private val binding = baseBinding as UserListItemBinding
+
+    init {
+        onClick(itemView) { position -> onMemberClicked(position) }
+    }
+
+    override fun bind(data: InviteMemberListItem) {
+        if (data !is CirclesUser) return
+
+        with(binding) {
+            ivUserImage.loadImage(
+                data.avatarUrl,
+                Size(ivUserImage.width, ivUserImage.height)
+            )
+            tvUserName.text = data.name
+            tvUserId.text = data.id
+        }
+    }
+}
+
+class HeaderViewHolder(
     parent: ViewGroup,
-) : RecyclerView.ViewHolder(inflate(parent, InviteMemberListItemBinding::inflate)) {
+) : InviteMemberViewHolder(inflate(parent, InviteHeaderListItemBinding::inflate)) {
 
     private companion object : ViewBindingHolder
 
-    private val binding = baseBinding as InviteMemberListItemBinding
+    private val binding = baseBinding as InviteHeaderListItemBinding
 
+    override fun bind(data: InviteMemberListItem) {
+        if (data !is HeaderItem) return
 
-    fun bind(data: RoomMemberListItem) {
-        binding.tvText.text = data.name + " / " + data.id
+        binding.tvHeader.text = context.getString(data.titleRes)
     }
+}
 
+class NoResultViewHolder(
+    parent: ViewGroup,
+) : InviteMemberViewHolder(inflate(parent, NoResultsListItemBinding::inflate)) {
+
+    private companion object : ViewBindingHolder
+
+    private val binding = baseBinding as NoResultsListItemBinding
+
+    override fun bind(data: InviteMemberListItem) {
+        if (data !is NoResultsItem) return
+
+        binding.tvMessage.text = context.getString(data.titleRes)
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/futo/circles/feature/group_invite/list/InviteMembersListAdapter.kt b/app/src/main/java/com/futo/circles/feature/group_invite/list/InviteMembersListAdapter.kt
index de81e0ebc..bc396a40b 100644
--- a/app/src/main/java/com/futo/circles/feature/group_invite/list/InviteMembersListAdapter.kt
+++ b/app/src/main/java/com/futo/circles/feature/group_invite/list/InviteMembersListAdapter.kt
@@ -2,17 +2,34 @@ package com.futo.circles.feature.group_invite.list
 
 import android.view.ViewGroup
 import com.futo.circles.base.BaseRvAdapter
-import com.futo.circles.model.RoomMemberListItem
+import com.futo.circles.model.HeaderItem
+import com.futo.circles.model.InviteMemberListItem
+import com.futo.circles.model.NoResultsItem
+import com.futo.circles.model.CirclesUser
 
-class InviteMembersListAdapter() : BaseRvAdapter<RoomMemberListItem, InviteMemberViewHolder>(
+private enum class InviteListViewType { Header, User, NoResults }
+
+class InviteMembersListAdapter(
+    private val onUserSelected: (CirclesUser) -> Unit
+) : BaseRvAdapter<InviteMemberListItem, InviteMemberViewHolder>(
     DefaultIdEntityCallback()
 ) {
 
+    override fun getItemViewType(position: Int): Int = when (getItem(position)) {
+        is HeaderItem -> InviteListViewType.Header.ordinal
+        is CirclesUser -> InviteListViewType.User.ordinal
+        is NoResultsItem -> InviteListViewType.NoResults.ordinal
+    }
 
-    override fun onCreateViewHolder(
-        parent: ViewGroup,
-        viewType: Int
-    ): InviteMemberViewHolder = InviteMemberViewHolder(parent = parent)
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): InviteMemberViewHolder {
+        return when (InviteListViewType.values()[viewType]) {
+            InviteListViewType.Header -> HeaderViewHolder(parent)
+            InviteListViewType.User -> UserViewHolder(
+                parent,
+                onMemberClicked = { position -> onUserSelected(getItem(position) as CirclesUser) })
+            InviteListViewType.NoResults -> NoResultViewHolder(parent)
+        }
+    }
 
     override fun onBindViewHolder(holder: InviteMemberViewHolder, position: Int) {
         holder.bind(getItem(position))
diff --git a/app/src/main/java/com/futo/circles/feature/group_timeline/GroupTimelineFragment.kt b/app/src/main/java/com/futo/circles/feature/group_timeline/GroupTimelineFragment.kt
index a4c3765a0..561ca3f5c 100644
--- a/app/src/main/java/com/futo/circles/feature/group_timeline/GroupTimelineFragment.kt
+++ b/app/src/main/java/com/futo/circles/feature/group_timeline/GroupTimelineFragment.kt
@@ -40,7 +40,7 @@ class GroupTimelineFragment : Fragment(R.layout.group_timeline_fragment), GroupP
         super.onViewCreated(view, savedInstanceState)
         setHasOptionsMenu(true)
 
-        binding.tvGroupTimeline.apply {
+        binding.rvGroupTimeline.apply {
             adapter = listAdapter
             addItemDecoration(
                 BaseRvDecoration.OffsetDecoration<GroupPostViewHolder>(
diff --git a/app/src/main/java/com/futo/circles/mapping/MatrixUserMapping.kt b/app/src/main/java/com/futo/circles/mapping/MatrixUserMapping.kt
index a837f7780..e66dcd10b 100644
--- a/app/src/main/java/com/futo/circles/mapping/MatrixUserMapping.kt
+++ b/app/src/main/java/com/futo/circles/mapping/MatrixUserMapping.kt
@@ -1,9 +1,9 @@
 package com.futo.circles.mapping
 
-import com.futo.circles.model.RoomMemberListItem
+import com.futo.circles.model.CirclesUser
 import org.matrix.android.sdk.api.session.user.model.User
 
-fun User.toRoomMember() = RoomMemberListItem(
+fun User.toCirclesUser() = CirclesUser(
     id = userId,
     name = displayName ?: userId,
     avatarUrl = avatarUrl ?: ""
diff --git a/app/src/main/java/com/futo/circles/model/InviteMemberListItem.kt b/app/src/main/java/com/futo/circles/model/InviteMemberListItem.kt
new file mode 100644
index 000000000..ead4815d4
--- /dev/null
+++ b/app/src/main/java/com/futo/circles/model/InviteMemberListItem.kt
@@ -0,0 +1,30 @@
+package com.futo.circles.model
+
+import com.futo.circles.R
+import com.futo.circles.base.IdEntity
+
+sealed class InviteMemberListItem : IdEntity<String>
+
+data class HeaderItem(
+    val titleRes: Int
+) : InviteMemberListItem() {
+    override val id: String = titleRes.toString()
+
+    companion object {
+        val knownUsersHeader = HeaderItem(R.string.known_users)
+        val suggestionHeader = HeaderItem(R.string.suggestion)
+    }
+}
+
+data class CirclesUser(
+    override val id: String,
+    val name: String,
+    val avatarUrl: String,
+    val isSelected: Boolean = false
+) : InviteMemberListItem()
+
+data class NoResultsItem(
+    val titleRes: Int = R.string.no_results
+) : InviteMemberListItem() {
+    override val id: String = titleRes.toString()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/futo/circles/model/RoomMemberListItem.kt b/app/src/main/java/com/futo/circles/model/RoomMemberListItem.kt
deleted file mode 100644
index 4b236be0c..000000000
--- a/app/src/main/java/com/futo/circles/model/RoomMemberListItem.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.futo.circles.model
-
-import com.futo.circles.base.IdEntity
-
-data class RoomMemberListItem(
-    override val id: String,
-    val name: String,
-    val avatarUrl: String,
-    val isSelected: Boolean = false
-) : IdEntity<String>
\ No newline at end of file
diff --git a/app/src/main/res/layout/group_timeline_fragment.xml b/app/src/main/res/layout/group_timeline_fragment.xml
index 5873afd03..30e82a65a 100644
--- a/app/src/main/res/layout/group_timeline_fragment.xml
+++ b/app/src/main/res/layout/group_timeline_fragment.xml
@@ -6,7 +6,7 @@
     android:layout_height="match_parent">
 
     <androidx.recyclerview.widget.RecyclerView
-        android:id="@+id/tvGroupTimeline"
+        android:id="@+id/rvGroupTimeline"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:clipToPadding="false"
@@ -21,7 +21,7 @@
         android:layout_gravity="bottom|end"
         android:layout_margin="16dp"
         app:fabSize="normal"
-        app:layout_anchor="@id/tvGroupTimeline"
+        app:layout_anchor="@id/rvGroupTimeline"
         app:srcCompat="@drawable/ic_create"
         app:tint="@color/white"
         tools:ignore="ContentDescription" />
diff --git a/app/src/main/res/layout/invite_header_list_item.xml b/app/src/main/res/layout/invite_header_list_item.xml
new file mode 100644
index 000000000..ab9cc4dd2
--- /dev/null
+++ b/app/src/main/res/layout/invite_header_list_item.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/tvHeader"
+    style="@style/headline"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="8dp"
+    tools:text="Header" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/invite_member_list_item.xml b/app/src/main/res/layout/invite_member_list_item.xml
deleted file mode 100644
index 132aefc28..000000000
--- a/app/src/main/res/layout/invite_member_list_item.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?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"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
-
-    <TextView
-        android:id="@+id/tvText"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/invite_members_dialog_fragment.xml b/app/src/main/res/layout/invite_members_dialog_fragment.xml
index cb3fc5824..fbd33cb60 100644
--- a/app/src/main/res/layout/invite_members_dialog_fragment.xml
+++ b/app/src/main/res/layout/invite_members_dialog_fragment.xml
@@ -41,7 +41,6 @@
         android:id="@+id/rvUsers"
         android:layout_width="0dp"
         android:layout_height="0dp"
-        android:layout_marginTop="8dp"
         app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/no_results_list_item.xml b/app/src/main/res/layout/no_results_list_item.xml
new file mode 100644
index 000000000..fcff59970
--- /dev/null
+++ b/app/src/main/res/layout/no_results_list_item.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/tvMessage"
+    style="@style/headline"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:paddingVertical="48dp"
+    tools:text="@string/no_results">
+
+</TextView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/user_list_item.xml b/app/src/main/res/layout/user_list_item.xml
new file mode 100644
index 000000000..4ce0814ac
--- /dev/null
+++ b/app/src/main/res/layout/user_list_item.xml
@@ -0,0 +1,51 @@
+<?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:background="?selectableItemBackground"
+    android:clickable="true"
+    android:focusable="true"
+    android:paddingHorizontal="8dp"
+    android:paddingVertical="4dp">
+
+    <com.google.android.material.imageview.ShapeableImageView
+        android:id="@+id/ivUserImage"
+        android:layout_width="40dp"
+        android:layout_height="0dp"
+        app:layout_constraintDimensionRatio="w,1:1"
+        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/body"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:ellipsize="end"
+        android:lines="1"
+        app:layout_constraintBottom_toTopOf="@id/tvUserId"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/ivUserImage"
+        app:layout_constraintTop_toTopOf="@id/ivUserImage"
+        app:layout_constraintVertical_chainStyle="packed"
+        tools:text="Android01" />
+
+    <TextView
+        android:id="@+id/tvUserId"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:lines="1"
+        android:textSize="13sp"
+        app:layout_constraintBottom_toBottomOf="@id/ivUserImage"
+        app:layout_constraintEnd_toEndOf="@id/tvUserName"
+        app:layout_constraintStart_toStartOf="@id/tvUserName"
+        app:layout_constraintTop_toBottomOf="@id/tvUserName"
+        tools:text="Android01@domain" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index fa720bdd1..83809b81d 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -4,4 +4,5 @@
     <dimen name="group_post_item_offset">4dp</dimen>
     <dimen name="reply_post_item_margin">24dp</dimen>
     <dimen name="post_text_side_margin">24dp</dimen>
+    <dimen name="invite_list_side_margin">8dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 15530f2eb..185312242 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -29,6 +29,9 @@
     <string name="invite_members">Invite members</string>
     <string name="invite_members_to_format">Invite members to %s</string>
     <string name="search_by_name_or_id">Search by name or id</string>
+    <string name="known_users">Known users</string>
+    <string name="suggestion">Suggestions</string>
+    <string name="no_results">No results</string>
 
     <plurals name="member_plurals">
         <item quantity="one">%d member</item>
-- 
GitLab