fix(@desktop/chat): Message reactions popup shouldn't revoke reactions (#13003)

fixes #10703

- Adding a reaction by going in add reaction and clicking R1 should have no effect (Currently the reaction R1 is removed which is not expected)
- Clicking on the R1 directly on the message should remove the reaction (I checked and this already works)
- Add a visual indicator in the add reaction popup on which emoji is already selected
This commit is contained in:
Godfrain Jacques 2023-12-18 14:34:10 -08:00 committed by GitHub
parent b58612f070
commit 8872877524
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 139 additions and 40 deletions

View File

@ -4,6 +4,7 @@ import ./gif_column_model
import ./preserved_properties
import ./urls_model
import ../../../../../../app/modules/shared_models/link_preview_model as link_preview_model
import ../../../../../../app/modules/shared_models/emoji_reactions_model as emoji_reactions_model
import ../../../../../../app_service/service/gif/dto
QtObject:
@ -21,6 +22,8 @@ QtObject:
urlsModel: urls_model.Model
urlsModelVariant: QVariant
askToEnableLinkPreview: bool
emojiReactionsModel: emoji_reactions_model.Model
emojiReactionsModelVariant: QVariant
proc delete*(self: View) =
self.QObject.delete
@ -33,6 +36,8 @@ QtObject:
self.linkPreviewModel.delete
self.urlsModelVariant.delete
self.urlsModel.delete
self.emojiReactionsModel.delete
self.emojiReactionsModelVariant.delete
proc newView*(delegate: io_interface.AccessInterface): View =
new(result, delete)
@ -49,6 +54,8 @@ QtObject:
result.urlsModel = newUrlsModel()
result.urlsModelVariant = newQVariant(result.urlsModel)
result.askToEnableLinkPreview = false
result.emojiReactionsModel = newEmojiReactionsModel()
result.emojiReactionsModelVariant = newQVariant(result.emojiReactionsModel)
proc load*(self: View) =
self.delegate.viewDidLoad()

View File

@ -0,0 +1,25 @@
import NimQml
type
EmojiReactionItem* = ref object
emojiId: int
filename: string
didIReactWithThisEmoji: bool
proc initItem*(emojiId: int, filename: string, didIReactWithThisEmoji: bool): EmojiReactionItem =
result = EmojiReactionItem()
result.emojiId = emojiId
result.filename = filename
result.didIReactWithThisEmoji = didIReactWithThisEmoji
proc emojiId*(self: EmojiReactionItem): int =
self.emojiId
proc filename*(self: EmojiReactionItem): string =
self.filename
proc didIReactWithThisEmoji*(self: EmojiReactionItem): bool =
self.didIReactWithThisEmoji
proc `didIReactWithThisEmoji=`*(self: EmojiReactionItem, value: bool) {.inline.} =
self.didIReactWithThisEmoji = value

View File

@ -0,0 +1,84 @@
import NimQml, Tables
import emoji_reactions_item
type
ModelRole {.pure.} = enum
EmojiId = UserRole + 1
Filename
DidIReactWithThisEmoji
QtObject:
type Model* = ref object of QAbstractListModel
items: seq[EmojiReactionItem]
proc delete(self: Model) =
self.items = @[]
self.QAbstractListModel.delete
# TODO : To make this code scale, we can consider a loop similar to
# below code, and rename emoji to just be emojiReactions/emoji_[1 ... n]
#
# ```nim
# for i in 1..itemCount:
# items.add(initItem(i, "emojiReactions/emoji_$(i)", false))
# ```
proc setup(self: Model) =
self.items = @[
initItem(1, "emojiReactions/heart", false),
initItem(2, "emojiReactions/thumbsUp", false),
initItem(3, "emojiReactions/thumbsDown", false),
initItem(4, "emojiReactions/laughing", false),
initItem(5, "emojiReactions/sad", false),
initItem(6, "emojiReactions/angry", false),
]
self.QAbstractListModel.setup
proc newEmojiReactionsModel*(): Model =
new(result, delete)
result.setup
proc newModel*(): Model =
new(result, delete)
result.setup
proc countChanged(self: Model) {.signal.}
proc getCount*(self: Model): int {.slot.} =
self.items.len
QtProperty[int] count:
read = getCount
notify = countChanged
method rowCount(self: Model, index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: Model): Table[int, string] =
{
ModelRole.EmojiId.int: "emojiId",
ModelRole.Filename.int: "filename",
ModelRole.DidIReactWithThisEmoji.int: "didIReactWithThisEmoji"
}.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant =
if not index.isValid:
return
if index.row < 0 or index.row >= self.items.len:
return
let item = self.items[index.row]
let enumRole = role.ModelRole
case enumRole:
of ModelRole.EmojiId: result = newQVariant(item.emojiId)
of ModelRole.Filename: result = newQVariant(item.filename)
of ModelRole.DidIReactWithThisEmoji: result = newQVariant(item.didIReactWithThisEmoji)
proc setItems*(self: Model, items: seq[EmojiReactionItem]) =
self.beginResetModel()
self.items = items
self.endResetModel()
proc setItemDidIReactWithThisEmoji*(self: Model, emojiId: int, didIReactWithThisEmoji: bool) =
if self.items.len > 0:
self.items[emojiId - 1].didIReactWithThisEmoji = didIReactWithThisEmoji

View File

@ -4,6 +4,7 @@ import ../../../app_service/service/contacts/dto/contact_details
import ../../../app_service/service/message/dto/message
import ../../../app_service/service/message/dto/link_preview
import ./link_preview_model as link_preview_model
import ./emoji_reactions_model as emoji_reactions_model
export types.ContentType
import message_reaction_model, message_reaction_item, message_transaction_parameters_item
@ -47,6 +48,7 @@ type
deletedByContactDetails: ContactDetails
links: seq[string]
linkPreviewModel: link_preview_model.Model
emojiReactionsModel: emoji_reactions_model.Model
transactionParameters: TransactionParametersItem
mentionedUsersPks: seq[string]
senderTrustStatus: TrustStatus
@ -154,6 +156,7 @@ proc initItem*(
result.deletedByContactDetails = deletedByContactDetails
result.links = links
result.linkPreviewModel = newLinkPreviewModel(linkPreviews)
result.emojiReactionsModel = newEmojiReactionsModel()
result.transactionParameters = transactionParameters
result.mentionedUsersPks = mentionedUsersPks
result.gapFrom = 0
@ -458,9 +461,11 @@ proc getReactionId*(self: Item, emojiId: EmojiId, userPublicKey: string): string
proc addReaction*(self: Item, emojiId: EmojiId, didIReactWithThisEmoji: bool, userPublicKey: string,
userDisplayName: string, reactionId: string) =
self.reactionsModel.addReaction(emojiId, didIReactWithThisEmoji, userPublicKey, userDisplayName, reactionId)
self.emojiReactionsModel.setItemDidIReactWithThisEmoji(ord(emojiId), didIReactWithThisEmoji)
proc removeReaction*(self: Item, emojiId: EmojiId, reactionId: string, didIRemoveThisReaction: bool) =
self.reactionsModel.removeReaction(emojiId, reactionId, didIRemoveThisReaction)
self.emojiReactionsModel.setItemDidIReactWithThisEmoji(ord(emojiId), not didIRemoveThisReaction)
proc messageAttachments*(self: Item): seq[string] {.inline.} =
self.messageAttachments
@ -474,6 +479,9 @@ proc `links=`*(self: Item, links: seq[string]) {.inline.} =
proc linkPreviewModel*(self: Item): link_preview_model.Model {.inline.} =
return self.linkPreviewModel
proc emojiReactionsModel*(self: Item): emoji_reactions_model.Model {.inline.} =
return self.emojiReactionsModel
proc mentionedUsersPks*(self: Item): seq[string] {.inline.} =
self.mentionedUsersPks

View File

@ -50,6 +50,7 @@ type
DeletedByContactColorHash
Links
LinkPreviewModel
EmojiReactionsModel
TransactionParameters
MentionedUsersPks
SenderTrustStatus
@ -156,6 +157,7 @@ QtObject:
ModelRole.DeletedByContactColorHash.int: "deletedByContactColorHash",
ModelRole.Links.int: "links",
ModelRole.LinkPreviewModel.int: "linkPreviewModel",
ModelRole.EmojiReactionsModel.int: "emojiReactionsModel",
ModelRole.TransactionParameters.int: "transactionParameters",
ModelRole.MentionedUsersPks.int: "mentionedUsersPks",
ModelRole.SenderTrustStatus.int: "senderTrustStatus",
@ -325,6 +327,8 @@ QtObject:
result = newQVariant(item.links.join(" "))
of ModelRole.LinkPreviewModel:
result = newQVariant(item.linkPreviewModel)
of ModelRole.EmojiReactionsModel:
result = newQVariant(item.emojiReactionsModel)
of ModelRole.TransactionParameters:
result = newQVariant($(%*{
"id": item.transactionParameters.id,

View File

@ -297,6 +297,7 @@ Item {
pinnedMessage: model.pinned
messagePinnedBy: model.pinnedBy
reactionsModel: model.reactions
emojiReactionsModel: model.emojiReactionsModel
sticker: model.sticker
stickerPack: model.stickerPack
editModeOn: model.editMode

View File

@ -1,30 +0,0 @@
import QtQuick 2.13
ListModel {
id: reactionModel
ListElement {
emojiId: 1
filename: "emojiReactions/heart"
}
ListElement {
emojiId: 2
filename: "emojiReactions/thumbsUp"
}
ListElement {
emojiId: 3
filename: "emojiReactions/thumbsDown"
}
ListElement {
emojiId: 4
filename: "emojiReactions/laughing"
}
ListElement {
emojiId: 5
filename: "emojiReactions/sad"
}
ListElement {
emojiId: 6
filename: "emojiReactions/angry"
}
}

View File

@ -124,9 +124,6 @@ QtObject {
property ProfileSectionStore profileSectionStore: ProfileSectionStore {
}
property EmojiReactions emojiReactionsModel: EmojiReactions {
}
property var chatSearchModel: mainModuleInst.chatSearchModel
function rebuildChatSearchModel() {

View File

@ -6,8 +6,7 @@ import shared 1.0
Row {
id: root
property var reactionsModel
property var messageReactionsModel: [] // TODO: https://github.com/status-im/status-desktop/issues/10703
property var reactionsModel: []
signal toggleReaction(int emojiId)
@ -20,8 +19,11 @@ Row {
delegate: EmojiReaction {
source: Style.svg(filename)
emojiId: model.emojiId
// reactedByUser: !!root.messageReactionsModel[emojiId]
reactedByUser: model.didIReactWithThisEmoji
onCloseModal: {
if (reactedByUser) {
return
}
root.toggleReaction(emojiId)
}
}

View File

@ -6,7 +6,6 @@ StatusMenu {
id: root
property alias reactionsModel: emojiRow.reactionsModel
property alias messageReactionsModel: emojiRow.messageReactionsModel
signal toggleReaction(int emojiId)

View File

@ -18,7 +18,7 @@ StatusMenu {
id: root
property var store
property var reactionModel
property var reactionModel: []
property string myPublicKey: ""
property bool amIChatAdmin: false

View File

@ -64,6 +64,7 @@ Loader {
property var linkPreviewModel
property string messageAttachments: ""
property var transactionParams
property var emojiReactionsModel
// These 2 properties can be dropped when the new unfurling flow supports GIFs
property var links
@ -1043,7 +1044,8 @@ Loader {
id: addReactionContextMenu
MessageAddReactionContextMenu {
reactionsModel: root.rootStore.emojiReactionsModel
reactionsModel: root.emojiReactionsModel
onToggleReaction: (emojiId) => {
root.messageStore.toggleReaction(root.messageId, emojiId)
}
@ -1094,7 +1096,7 @@ Loader {
MessageContextMenuView {
store: root.rootStore
reactionModel: root.rootStore.emojiReactionsModel
reactionModel: root.emojiReactionsModel
disabledForChat: !root.rootStore.isUserAllowedToSendMessage
onPinMessage: (messageId) => {