Эх сурвалжийг харах

add details view for reactions (WIP)

TODO: encoding for emoji is wrong to send it to server
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Marcel Hibbe 3 жил өмнө
parent
commit
4abe8ae41d

+ 1 - 1
app/src/main/java/com/nextcloud/talk/adapters/messages/ReactionsInterface.kt

@@ -3,5 +3,5 @@ package com.nextcloud.talk.adapters.messages
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ChatMessage
 
 
 interface ReactionsInterface {
 interface ReactionsInterface {
-    fun onClickReactions(message: ChatMessage)
+    fun onClickReactions(chatMessage: ChatMessage)
 }
 }

+ 6 - 0
app/src/main/java/com/nextcloud/talk/api/NcApi.java

@@ -37,6 +37,7 @@ import com.nextcloud.talk.models.json.notifications.NotificationOverall;
 import com.nextcloud.talk.models.json.participants.AddParticipantOverall;
 import com.nextcloud.talk.models.json.participants.AddParticipantOverall;
 import com.nextcloud.talk.models.json.participants.ParticipantsOverall;
 import com.nextcloud.talk.models.json.participants.ParticipantsOverall;
 import com.nextcloud.talk.models.json.push.PushRegistrationOverall;
 import com.nextcloud.talk.models.json.push.PushRegistrationOverall;
+import com.nextcloud.talk.models.json.reactions.ReactionsOverall;
 import com.nextcloud.talk.models.json.search.ContactsByNumberOverall;
 import com.nextcloud.talk.models.json.search.ContactsByNumberOverall;
 import com.nextcloud.talk.models.json.signaling.SignalingOverall;
 import com.nextcloud.talk.models.json.signaling.SignalingOverall;
 import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall;
 import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall;
@@ -62,6 +63,7 @@ import retrofit2.http.FieldMap;
 import retrofit2.http.FormUrlEncoded;
 import retrofit2.http.FormUrlEncoded;
 import retrofit2.http.GET;
 import retrofit2.http.GET;
 import retrofit2.http.Header;
 import retrofit2.http.Header;
+import retrofit2.http.Headers;
 import retrofit2.http.Multipart;
 import retrofit2.http.Multipart;
 import retrofit2.http.POST;
 import retrofit2.http.POST;
 import retrofit2.http.PUT;
 import retrofit2.http.PUT;
@@ -488,4 +490,8 @@ public interface NcApi {
     @GET
     @GET
     Observable<StatusesOverall> getUserStatuses(@Header("Authorization") String authorization, @Url String url);
     Observable<StatusesOverall> getUserStatuses(@Header("Authorization") String authorization, @Url String url);
 
 
+    @GET
+    Observable<ReactionsOverall> getParticipantsForEmojiReaction(@Header("Authorization") String authorization,
+                                                                 @Url String url,
+                                                                 @Query("reaction") String reaction);
 }
 }

+ 5 - 3
app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt

@@ -923,11 +923,13 @@ class ChatController(args: Bundle) :
     }
     }
 
 
     override fun onClickReactions(chatMessage: ChatMessage) {
     override fun onClickReactions(chatMessage: ChatMessage) {
-        Log.d(TAG, "onClickReactions" + chatMessage)
-
         activity?.let {
         activity?.let {
             ShowReactionsDialog(
             ShowReactionsDialog(
-                activity!!
+                activity!!,
+                currentConversation,
+                chatMessage,
+                conversationUser,
+                ncApi!!
             ).show()
             ).show()
         }
         }
     }
     }

+ 42 - 0
app/src/main/java/com/nextcloud/talk/models/json/reactions/ReactionVoter.kt

@@ -0,0 +1,42 @@
+/*
+ *
+ *   Nextcloud Talk application
+ *
+ *   @author Marcel Hibbe
+ *   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/>.
+ */
+package com.nextcloud.talk.models.json.reactions
+
+import android.os.Parcelable
+import com.bluelinelabs.logansquare.annotation.JsonField
+import com.bluelinelabs.logansquare.annotation.JsonObject
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+@JsonObject
+data class ReactionVoter(
+    @JsonField(name = ["actorType"])
+    var actorType: String?,
+    @JsonField(name = ["actorId"])
+    var actorId: String?,
+    @JsonField(name = ["actorDisplayName"])
+    var actorDisplayName: String?,
+    @JsonField(name = ["timestamp"])
+    var timestamp: Long = 0
+) : Parcelable {
+    // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
+    constructor() : this(null, null, null, 0)
+}

+ 36 - 0
app/src/main/java/com/nextcloud/talk/models/json/reactions/ReactionsOCS.kt

@@ -0,0 +1,36 @@
+/*
+ *   Nextcloud Talk application
+ *
+ *   @author Marcel Hibbe
+ *   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/>.
+ */
+package com.nextcloud.talk.models.json.reactions
+
+import android.os.Parcelable
+import com.bluelinelabs.logansquare.annotation.JsonField
+import com.bluelinelabs.logansquare.annotation.JsonObject
+import com.nextcloud.talk.models.json.generic.GenericOCS
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+@JsonObject
+data class ReactionsOCS(
+    @JsonField(name = ["data"])
+    var data: List<ReactionVoter>?
+) : GenericOCS(), Parcelable {
+    // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
+    constructor() : this(null)
+}

+ 35 - 0
app/src/main/java/com/nextcloud/talk/models/json/reactions/ReactionsOverall.kt

@@ -0,0 +1,35 @@
+/*
+ *   Nextcloud Talk application
+ *
+ *   @author Marcel Hibbe
+ *   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/>.
+ */
+package com.nextcloud.talk.models.json.reactions
+
+import android.os.Parcelable
+import com.bluelinelabs.logansquare.annotation.JsonField
+import com.bluelinelabs.logansquare.annotation.JsonObject
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+@JsonObject
+data class ReactionsOverall(
+    @JsonField(name = ["ocs"])
+    var ocs: ReactionsOCS?
+) : Parcelable {
+    // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
+    constructor() : this(null)
+}

+ 122 - 4
app/src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt

@@ -2,20 +2,138 @@ package com.nextcloud.talk.ui.dialog
 
 
 import android.app.Activity
 import android.app.Activity
 import android.os.Bundle
 import android.os.Bundle
+import android.util.Log
+import android.view.Gravity
 import android.view.ViewGroup
 import android.view.ViewGroup
+import android.widget.LinearLayout
+import androidx.annotation.NonNull
+import autodagger.AutoInjector
 import com.google.android.material.bottomsheet.BottomSheetDialog
 import com.google.android.material.bottomsheet.BottomSheetDialog
+import com.nextcloud.talk.api.NcApi
+import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.databinding.DialogMessageReactionsBinding
 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
+import com.nextcloud.talk.utils.DisplayUtils
+import com.vanniktech.emoji.EmojiTextView
+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(
 class ShowReactionsDialog(
-    val activity: Activity
+    val activity: Activity,
+    val currentConversation: Conversation?,
+    val chatMessage: ChatMessage,
+    val userEntity: UserEntity?,
+    val ncApi: NcApi
 ) : BottomSheetDialog(activity) {
 ) : BottomSheetDialog(activity) {
 
 
-    private lateinit var dialogMessageReactionsBinding: DialogMessageReactionsBinding
+    private lateinit var binding: DialogMessageReactionsBinding
+
+    // @Inject
+    // lateinit var ncApi: NcApi
 
 
     override fun onCreate(savedInstanceState: Bundle?) {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         super.onCreate(savedInstanceState)
-        dialogMessageReactionsBinding = DialogMessageReactionsBinding.inflate(layoutInflater)
-        setContentView(dialogMessageReactionsBinding.root)
+        binding = DialogMessageReactionsBinding.inflate(layoutInflater)
+        setContentView(binding.root)
         window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
         window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+
+        initEmojiReactions()
+    }
+
+    private fun initEmojiReactions() {
+        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())
+                emojiView.text = emoji
+
+                val params = LinearLayout.LayoutParams(
+                    ViewGroup.LayoutParams.WRAP_CONTENT,
+                    ViewGroup.LayoutParams.WRAP_CONTENT
+                )
+                params.setMargins(0, 0, EMOJI_RIGHT_MARGIN, 0)
+                params.gravity = Gravity.CENTER
+                emojiView.layoutParams = params
+
+                binding.emojiReactionsWrapper.addView(emojiView)
+
+                emojiView.setOnClickListener {
+                    updateParticipantsForEmoji(chatMessage, emoji)
+                }
+            }
+        }
+    }
+
+    private fun updateParticipantsForEmoji(chatMessage: ChatMessage, emoji: String?) {
+
+        val credentials = ApiUtils.getCredentials(userEntity?.username, userEntity?.token)
+
+        Log.d(TAG, "emoji= " + emoji)
+
+        // TODO: fix encoding for emoji. set this in NcApi or here...
+
+        // var emojiForServer = StringEscapeUtils.escapeJava(emoji)
+        // Log.d(TAG, "emojiForServer= " + emojiForServer)            //     ?reaction=%5Cu2764%5CuFE0F
+
+        ncApi.getParticipantsForEmojiReaction(
+            credentials,
+            ApiUtils.getUrlForParticipantsForEmojiReaction(
+                userEntity?.baseUrl,
+                currentConversation!!.token,
+                chatMessage.id),
+            emoji
+        )
+            ?.subscribeOn(Schedulers.io())
+            ?.observeOn(AndroidSchedulers.mainThread())
+            ?.subscribe(object : Observer<ReactionsOverall> {
+                override fun onSubscribe(d: Disposable) {
+                    Log.d(TAG, "onSubscribe")
+                }
+
+                override fun onNext(@NonNull reactionsOverall: ReactionsOverall) {
+                    Log.d(TAG, "onNext")
+
+                    val reactionVoters: ArrayList<ReactionVoter> = ArrayList()
+                    if (reactionsOverall.ocs?.data != null){
+                        for (reactionVoter in reactionsOverall.ocs?.data!!) {
+                            reactionVoters.add(reactionVoter)
+                        }
+                    } else {
+                        Log.e(TAG, "no voters for this reaction")
+                    }
+                }
+
+                override fun onError(e: Throwable) {
+                    Log.e(TAG, "failed to retrieve list of reaction voters")
+                }
+
+                override fun onComplete() {
+                    Log.d(TAG, "onComplete")
+                }
+            })
+
+
+
+
+        // binding.emojiReactionsContactList
+    }
+
+    companion object {
+        const val TAG = "ShowReactionsDialog"
+        const val EMOJI_RIGHT_MARGIN: Int = 12
+        const val EMOJI_SIZE: Float = 30F
     }
     }
 }
 }

+ 7 - 0
app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java

@@ -441,4 +441,11 @@ public class ApiUtils {
     public static String getUrlForUserStatuses(String baseUrl) {
     public static String getUrlForUserStatuses(String baseUrl) {
         return baseUrl + ocsApiVersion + "/apps/user_status/api/v1/statuses";
         return baseUrl + ocsApiVersion + "/apps/user_status/api/v1/statuses";
     }
     }
+
+    public static String getUrlForParticipantsForEmojiReaction(String baseUrl,
+                                                               String roomToken,
+                                                               String messageId) {
+        return baseUrl + ocsApiVersion + spreedApiVersion + "/reaction/" + roomToken + "/" + messageId;
+    }
+
 }
 }

+ 23 - 16
app/src/main/res/layout/dialog_message_reactions.xml

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?><!--
 <?xml version="1.0" encoding="utf-8"?><!--
   ~ Nextcloud Talk application
   ~ Nextcloud Talk application
   ~
   ~
-  ~ @author Andy Scherzinger
-  ~ Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
+  ~ @author Marcel Hibbe
+  ~ Copyright (C) 2022 Marcel Hibbe <dev@mhibbe.de>
   ~
   ~
   ~ This program is free software: you can redistribute it and/or modify
   ~ 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
   ~ it under the terms of the GNU General Public License as published by
@@ -19,7 +19,6 @@
   -->
   -->
 
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 <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"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_height="wrap_content"
@@ -30,25 +29,33 @@
     android:paddingBottom="@dimen/standard_half_padding">
     android:paddingBottom="@dimen/standard_half_padding">
 
 
     <LinearLayout
     <LinearLayout
-        android:id="@+id/menu_copy_message"
         android:layout_width="match_parent"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/bottom_sheet_item_height"
-        android:background="?android:attr/selectableItemBackground"
+        android:layout_height="wrap_content"
         android:gravity="center_vertical"
         android:gravity="center_vertical"
-        android:orientation="horizontal"
+        android:orientation="vertical"
         tools:ignore="UseCompoundDrawables">
         tools:ignore="UseCompoundDrawables">
 
 
-        <androidx.appcompat.widget.AppCompatTextView
-            android:id="@+id/test"
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/emoji_reactions_contact_list"
             android:layout_width="match_parent"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="start|center_vertical"
-            android:paddingStart="@dimen/standard_double_padding"
-            android:paddingEnd="@dimen/zero"
-            android:text="just a test"
-            android:textAlignment="viewStart"
-            android:textColor="@color/high_emphasis_text"
-            android:textSize="@dimen/bottom_sheet_text_size" />
+            tools:listitem="@layout/rv_item_emoji_details_contact"
+            tools:itemCount="4"/>
+
+        <HorizontalScrollView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center">
+
+            <LinearLayout
+                android:id="@+id/emoji_reactions_wrapper"
+                android:layout_width="wrap_content"
+                android:layout_height="50dp"
+                android:orientation="horizontal"
+                android:layout_gravity="center">
+            </LinearLayout>
+
+        </HorizontalScrollView>
 
 
     </LinearLayout>
     </LinearLayout>
 
 

+ 54 - 0
app/src/main/res/layout/rv_item_emoji_details_contact.xml

@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Nextcloud Talk application
+  ~
+  ~ @author Mario Danic
+  ~ @author Andy Scherzinger
+  ~ Copyright (C) 2021 Andy Scherzinger
+  ~ Copyright (C) 2017 Mario Danic
+  ~
+  ~ 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/>.
+  -->
+
+<RelativeLayout 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:layout_marginStart="@dimen/standard_margin"
+    android:layout_marginTop="@dimen/standard_half_margin"
+    android:layout_marginEnd="@dimen/standard_margin"
+    android:layout_marginBottom="@dimen/standard_half_margin"
+    android:orientation="vertical">
+
+    <com.facebook.drawee.view.SimpleDraweeView
+        android:id="@+id/avatar_drawee_view"
+        android:layout_width="@dimen/avatar_size"
+        android:layout_height="@dimen/avatar_size"
+        android:layout_centerVertical="true"
+        android:layout_marginEnd="@dimen/standard_margin"
+        app:roundAsCircle="true" />
+
+    <androidx.emoji.widget.EmojiTextView
+        android:id="@+id/name_text"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_centerVertical="true"
+        android:layout_toEndOf="@id/avatar_drawee_view"
+        android:ellipsize="end"
+        android:lines="1"
+        android:textAlignment="viewStart"
+        android:textAppearance="@style/ListItem"
+        tools:text="Jane Doe" />
+
+</RelativeLayout>