diff --git a/app/src/main/java/com/nextcloud/talk/adapters/ReactionItem.kt b/app/src/main/java/com/nextcloud/talk/adapters/ReactionItem.kt new file mode 100644 index 00000000000..e260318d2d0 --- /dev/null +++ b/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 + * + * 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 . + */ + +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? +) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/ReactionItemClickListener.kt b/app/src/main/java/com/nextcloud/talk/adapters/ReactionItemClickListener.kt new file mode 100644 index 00000000000..865b122e128 --- /dev/null +++ b/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 + * + * 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 . + */ + +package com.nextcloud.talk.adapters + +interface ReactionItemClickListener { + fun onClick(reactionItem: ReactionItem) +} diff --git a/app/src/main/java/com/nextcloud/talk/adapters/ReactionsAdapter.kt b/app/src/main/java/com/nextcloud/talk/adapters/ReactionsAdapter.kt new file mode 100644 index 00000000000..c16cef9536f --- /dev/null +++ b/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 + * + * 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 . + */ + +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() { + internal var list: MutableList = ArrayList() + + 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 + } +} diff --git a/app/src/main/java/com/nextcloud/talk/adapters/ReactionsViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/ReactionsViewHolder.kt new file mode 100644 index 00000000000..78d6bb0201f --- /dev/null +++ b/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 + * + * 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 . + */ + +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 + } +} diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt index f9d0345690e..e7c21769631 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt +++ b/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 + * Copyright (C) 2017 Mario Danic + * 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 . + * + * 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 = ArrayList() - if (reactionsOverall.ocs?.data != null){ + val reactionVoters: ArrayList = 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 diff --git a/app/src/main/res/layout/dialog_message_reactions.xml b/app/src/main/res/layout/dialog_message_reactions.xml index d61e1ebd756..98d0b3b1c35 100644 --- a/app/src/main/res/layout/dialog_message_reactions.xml +++ b/app/src/main/res/layout/dialog_message_reactions.xml @@ -1,7 +1,9 @@ + + + + + + + + + +