Pārlūkot izejas kodu

Render list of reactions in recycler view in bottom sheet

Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Andy Scherzinger 3 gadi atpakaļ
vecāks
revīzija
06f42a4c00

+ 29 - 0
app/src/main/java/com/nextcloud/talk/adapters/ReactionItem.kt

@@ -0,0 +1,29 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Andy Scherzinger
+ * Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.adapters
+
+import com.nextcloud.talk.models.json.reactions.ReactionVoter
+
+// TODO: replace with proper class with correct data objects
+data class ReactionItem(
+    val reactionVoter: ReactionVoter,
+    val reaction: String?
+)

+ 25 - 0
app/src/main/java/com/nextcloud/talk/adapters/ReactionItemClickListener.kt

@@ -0,0 +1,25 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Andy Scherzinger
+ * Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.adapters
+
+interface ReactionItemClickListener {
+    fun onClick(reactionItem: ReactionItem)
+}

+ 45 - 0
app/src/main/java/com/nextcloud/talk/adapters/ReactionsAdapter.kt

@@ -0,0 +1,45 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Andy Scherzinger
+ * Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.nextcloud.talk.databinding.ReactionItemBinding
+
+class ReactionsAdapter(
+    private val clickListener: ReactionItemClickListener
+) : RecyclerView.Adapter<ReactionsViewHolder>() {
+    internal var list: MutableList<ReactionItem> = ArrayList<ReactionItem>()
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReactionsViewHolder {
+        val itemBinding = ReactionItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+        return ReactionsViewHolder(itemBinding)
+    }
+
+    override fun onBindViewHolder(holder: ReactionsViewHolder, position: Int) {
+        holder.bind(list[position], clickListener)
+    }
+
+    override fun getItemCount(): Int {
+        return list.size
+    }
+}

+ 33 - 0
app/src/main/java/com/nextcloud/talk/adapters/ReactionsViewHolder.kt

@@ -0,0 +1,33 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Andy Scherzinger
+ * Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.adapters
+
+import androidx.recyclerview.widget.RecyclerView
+import com.nextcloud.talk.databinding.ReactionItemBinding
+
+class ReactionsViewHolder(private val binding: ReactionItemBinding) : RecyclerView.ViewHolder(binding.root) {
+
+    fun bind(reactionItem: ReactionItem, clickListener: ReactionItemClickListener) {
+        binding.root.setOnClickListener { clickListener.onClick(reactionItem) }
+        binding.reaction.text = reactionItem.reaction
+        binding.name.text = reactionItem.reactionVoter.actorDisplayName
+    }
+}

+ 58 - 14
app/src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt

@@ -1,3 +1,29 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Andy Scherzinger
+ * @author Mario Danic
+ * @author Marcel Hibbe
+ * Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
+ * Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
+ * Copyright (C) 2022 Marcel Hibbe (dev@mhibbe.de)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Parts related to account import were either copied from or inspired by the great work done by David Luhmer at:
+ * https://github.com/nextcloud/ownCloud-Account-Importer
+ */
 package com.nextcloud.talk.ui.dialog
 
 import android.app.Activity
@@ -7,15 +33,18 @@ import android.view.Gravity
 import android.view.ViewGroup
 import android.widget.LinearLayout
 import androidx.annotation.NonNull
+import androidx.recyclerview.widget.LinearLayoutManager
 import autodagger.AutoInjector
 import com.google.android.material.bottomsheet.BottomSheetDialog
+import com.nextcloud.talk.adapters.ReactionItem
+import com.nextcloud.talk.adapters.ReactionItemClickListener
+import com.nextcloud.talk.adapters.ReactionsAdapter
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.databinding.DialogMessageReactionsBinding
 import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.conversations.Conversation
-import com.nextcloud.talk.models.json.generic.GenericOverall
 import com.nextcloud.talk.models.json.reactions.ReactionVoter
 import com.nextcloud.talk.models.json.reactions.ReactionsOverall
 import com.nextcloud.talk.utils.ApiUtils
@@ -25,10 +54,6 @@ import io.reactivex.Observer
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.disposables.Disposable
 import io.reactivex.schedulers.Schedulers
-import org.apache.commons.lang3.StringEscapeUtils
-import java.net.URLDecoder
-import java.net.URLEncoder
-import javax.inject.Inject
 
 @AutoInjector(NextcloudTalkApplication::class)
 class ShowReactionsDialog(
@@ -37,10 +62,12 @@ class ShowReactionsDialog(
     val chatMessage: ChatMessage,
     val userEntity: UserEntity?,
     val ncApi: NcApi
-) : BottomSheetDialog(activity) {
+) : BottomSheetDialog(activity), ReactionItemClickListener {
 
     private lateinit var binding: DialogMessageReactionsBinding
 
+    private var adapter: ReactionsAdapter? = null
+
     // @Inject
     // lateinit var ncApi: NcApi
 
@@ -49,12 +76,16 @@ class ShowReactionsDialog(
         binding = DialogMessageReactionsBinding.inflate(layoutInflater)
         setContentView(binding.root)
         window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
-
+        adapter = ReactionsAdapter(this)
+        binding.reactionsList.adapter = adapter
+        binding.reactionsList.layoutManager = LinearLayoutManager(context)
         initEmojiReactions()
     }
 
     private fun initEmojiReactions() {
+        adapter?.list?.clear()
         if (chatMessage.reactions != null && chatMessage.reactions.isNotEmpty()) {
+
             for ((emoji, amount) in chatMessage.reactions) {
                 var emojiView = EmojiTextView(activity)
                 emojiView.setEmojiSize(DisplayUtils.convertDpToPixel(EMOJI_SIZE, context).toInt())
@@ -73,8 +104,12 @@ class ShowReactionsDialog(
                 emojiView.setOnClickListener {
                     updateParticipantsForEmoji(chatMessage, emoji)
                 }
+
+                // TODO: Add proper implementation
+                adapter?.list?.add(ReactionItem(ReactionVoter(null, null, "Marcel", 0), emoji))
             }
         }
+        adapter?.notifyDataSetChanged()
     }
 
     private fun updateParticipantsForEmoji(chatMessage: ChatMessage, emoji: String?) {
@@ -93,7 +128,8 @@ class ShowReactionsDialog(
             ApiUtils.getUrlForParticipantsForEmojiReaction(
                 userEntity?.baseUrl,
                 currentConversation!!.token,
-                chatMessage.id),
+                chatMessage.id
+            ),
             emoji
         )
             ?.subscribeOn(Schedulers.io())
@@ -106,11 +142,14 @@ class ShowReactionsDialog(
                 override fun onNext(@NonNull reactionsOverall: ReactionsOverall) {
                     Log.d(TAG, "onNext")
 
-                    val reactionVoters: ArrayList<ReactionVoter> = ArrayList()
-                    if (reactionsOverall.ocs?.data != null){
+                    val reactionVoters: ArrayList<ReactionItem> = ArrayList()
+                    if (reactionsOverall.ocs?.data != null) {
                         for (reactionVoter in reactionsOverall.ocs?.data!!) {
-                            reactionVoters.add(reactionVoter)
+                            reactionVoters.add(ReactionItem(reactionVoter, emoji))
                         }
+                        // TODO: Test and check for data notification call need
+                        adapter?.list?.addAll(reactionVoters)
+                        Log.e(TAG, "voters:" + reactionVoters.size)
                     } else {
                         Log.e(TAG, "no voters for this reaction")
                     }
@@ -125,12 +164,17 @@ class ShowReactionsDialog(
                 }
             })
 
-
-
-
         // binding.emojiReactionsContactList
     }
 
+    override fun onClick(reactionItem: ReactionItem) {
+        Log.d(TAG, "onClick(reactionItem: ReactionItem): " + reactionItem.reaction)
+        // TODO: implement removal of users reaction,
+        //  ownership needs to be checked, so only owned
+        //  reactions can be removed upon click
+        dismiss()
+    }
+
     companion object {
         const val TAG = "ShowReactionsDialog"
         const val EMOJI_RIGHT_MARGIN: Int = 12

+ 10 - 1
app/src/main/res/layout/dialog_message_reactions.xml

@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?><!--
   ~ Nextcloud Talk application
   ~
+  ~ @author Andy Scherzinger
   ~ @author Marcel Hibbe
+  ~ Copyright (C) 2022 Andy Scherzinger
   ~ Copyright (C) 2022 Marcel Hibbe <dev@mhibbe.de>
   ~
   ~ This program is free software: you can redistribute it and/or modify
@@ -28,12 +30,19 @@
     android:paddingEnd="@dimen/standard_padding"
     android:paddingBottom="@dimen/standard_half_padding">
 
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/reactions_list"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        tools:listitem="@layout/reaction_item" />
+
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="center_vertical"
         android:orientation="vertical"
-        tools:ignore="UseCompoundDrawables">
+        tools:ignore="UseCompoundDrawables"
+        android:visibility="gone">
 
         <androidx.recyclerview.widget.RecyclerView
             android:id="@+id/emoji_reactions_contact_list"

+ 53 - 0
app/src/main/res/layout/reaction_item.xml

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+
+  Nextcloud Talk application
+
+  Copyright (C) 2022 Andy Scherzinger
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU Affero General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU Affero General Public License for more details.
+
+  You should have received a copy of the GNU Affero General Public License
+  along with this program. If not, see <https://www.gnu.org/licenses/>.
+-->
+
+<LinearLayout 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="48dp">
+
+    <com.facebook.drawee.view.SimpleDraweeView
+        android:id="@+id/avatar"
+        android:layout_width="@dimen/avatar_size"
+        android:layout_height="@dimen/avatar_size"
+        android:layout_gravity="center_vertical"
+        android:layout_marginEnd="@dimen/standard_margin"
+        app:roundAsCircle="true" />
+
+    <TextView
+        android:id="@+id/name"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:ellipsize="middle"
+        android:gravity="center_vertical"
+        android:textAppearance="?android:attr/textAppearanceListItem"
+        tools:text="Participant Name" />
+
+    <androidx.emoji.widget.EmojiTextView
+        android:id="@+id/reaction"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:gravity="center"
+        android:textSize="25sp"
+        tools:text="@string/default_emoji" />
+
+</LinearLayout>