feat(ActivityCenter): Add CTA for contact request notifications

Close #7277
This commit is contained in:
MishkaRogachev 2022-09-27 20:21:00 +04:00 committed by Mikhail Rogachev
parent acbf6fce51
commit 9b227cbfd9
13 changed files with 105 additions and 15 deletions

View File

@ -195,10 +195,8 @@ QtObject:
self.setNewData(activityCenterNotifications)
else:
for activityCenterNotification in activityCenterNotifications:
var found = false
for notif in self.activityCenterNotifications:
if activityCenterNotification.id == notif.id:
found = true
self.removeNotifications(@[notif.id])
break
if found: continue
self.addActivityNotificationItemToList(activityCenterNotification, false)

View File

@ -54,7 +54,6 @@ method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("activityCenterModule", self.viewVariant)
self.controller.init()
self.view.load()
self.fetchActivityCenterNotifications()
method isLoaded*(self: Module): bool =
return self.moduleLoaded
@ -90,6 +89,7 @@ proc createMessageItemFromDto(self: Module, message: MessageDto, chatDetails: Ch
localTimestamp = message.timestamp,
ContentType(message.contentType),
message.messageType,
message.contactRequestState,
message.sticker.url,
message.sticker.pack,
message.links,

View File

@ -91,6 +91,7 @@ proc createFetchMoreMessagesItem(self: Module): Item =
localTimestamp = 0,
ContentType.FetchMoreMessagesButton,
messageType = -1,
contactRequestState = 0,
sticker = "",
stickerPack = -1,
links = @[],
@ -131,6 +132,7 @@ proc createChatIdentifierItem(self: Module): Item =
localTimestamp = 0,
ContentType.ChatIdentifier,
messageType = -1,
contactRequestState = 0,
sticker = "",
stickerPack = -1,
links = @[],
@ -198,6 +200,7 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
localTimestamp = m.timestamp,
m.contentType.ContentType,
m.messageType,
m.contactRequestState,
sticker = m.sticker.url,
m.sticker.pack,
m.links,
@ -291,6 +294,7 @@ method messageAdded*(self: Module, message: MessageDto) =
localTimestamp = message.timestamp,
message.contentType.ContentType,
message.messageType,
message.contactRequestState,
sticker = message.sticker.url,
message.sticker.pack,
message.links,

View File

@ -181,6 +181,7 @@ proc buildPinnedMessageItem(self: Module, messageId: string, actionInitiatedBy:
localTimestamp = m.timestamp,
m.contentType.ContentType,
m.messageType,
m.contactRequestState,
m.sticker.url,
m.sticker.pack,
m.links,

View File

@ -55,6 +55,7 @@ type
localTimestamp: int64
contentType: ContentType
messageType: int
contactRequestState: int
reactionsModel: MessageReactionModel
pinned: bool
pinnedBy: string
@ -86,6 +87,7 @@ proc initItem*(
localTimestamp: int64, # local timestamp obtained when a message is being sent, with 1ms accuracy
contentType: ContentType,
messageType: int,
contactRequestState: int,
sticker: string,
stickerPack: int,
links: seq[string],
@ -114,6 +116,7 @@ proc initItem*(
result.localTimestamp = localTimestamp
result.contentType = contentType
result.messageType = messageType
result.contactRequestState = contactRequestState
result.pinned = false
result.reactionsModel = newMessageReactionModel()
result.sticker = sticker
@ -163,6 +166,7 @@ proc `$`*(self: Item): string =
localTimestamp:{$self.localTimestamp}
contentType:{$self.contentType.int},
messageType:{$self.messageType},
contactRequestState:{$self.contactRequestState},
pinned:{$self.pinned},
pinnedBy:{$self.pinnedBy},
messageReactions: [{$self.reactionsModel}],
@ -268,6 +272,9 @@ proc contentType*(self: Item): ContentType {.inline.} =
proc messageType*(self: Item): int {.inline.} =
self.messageType
proc contactRequestState*(self: Item): int {.inline.} =
self.contactRequestState
proc pinned*(self: Item): bool {.inline.} =
self.pinned
@ -338,6 +345,7 @@ proc toJsonNode*(self: Item): JsonNode =
"localTimestamp": self.localTimestamp,
"contentType": self.contentType.int,
"messageType": self.messageType,
"contactRequestState": self.contactRequestState,
"pinned": self.pinned,
"pinnedBy": self.pinnedBy,
"editMode": self.editMode,

View File

@ -108,6 +108,10 @@ QtObject:
QtProperty[int] messageType:
read = messageType
proc contactRequestState*(self: MessageItem): int {.slot.} = result = ?.self.messageItem.contactRequestState
QtProperty[int] contactRequestState:
read = contactRequestState
# TODO find a way to pass reactions since they are not basic types (might need to be a Model)
# proc reactions*(self: MessageItem): int {.slot.} = result = ?.self.messageItem.reactions
# QtProperty[int] reactions:

View File

@ -80,7 +80,7 @@ QtObject:
proc init*(self: Service) =
self.asyncActivityNotificationLoad()
self.events.on(SignalType.Message.event) do(e: Args):
var receivedData = MessageSignal(e)
let receivedData = MessageSignal(e)
# Handling activityCenterNotifications updates
if (receivedData.activityCenterNotifications.len > 0):
@ -172,9 +172,8 @@ QtObject:
self.cursor = activityCenterNotificationsTuple[0]
# Filter contact request notification til we have the UI working
self.events.emit(SIGNAL_ACTIVITY_CENTER_NOTIFICATIONS_LOADED,
ActivityCenterNotificationsArgs(activityCenterNotifications: activityCenterNotificationsTuple[1].filter(n => n.notificationType != ActivityCenterNotificationType.ContactRequest)))
ActivityCenterNotificationsArgs(activityCenterNotifications: activityCenterNotificationsTuple[1]))
proc acceptActivityCenterNotifications*(self: Service, notificationIds: seq[string]): string =
try:

View File

@ -100,6 +100,7 @@ type MessageDto* = object
timestamp*: int64
contentType*: int
messageType*: int
contactRequestState*: int
links*: seq[string]
editedAt*: int
transactionParameters*: TransactionParameters
@ -203,6 +204,7 @@ proc toMessageDto*(jsonObj: JsonNode): MessageDto =
discard jsonObj.getProp("timestamp", result.timestamp)
discard jsonObj.getProp("contentType", result.contentType)
discard jsonObj.getProp("messageType", result.messageType)
discard jsonObj.getProp("contactRequestState", result.contactRequestState)
discard jsonObj.getProp("image", result.image)
discard jsonObj.getProp("editedAt", result.editedAt)

View File

@ -0,0 +1,56 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import utils 1.0
import shared.panels 1.0
Item {
id: root
property bool pending: false
property bool accepted: false
property bool dismissed: false
property bool blocked: false
signal acceptClicked()
signal declineClicked()
signal blockClicked()
signal profileClicked()
width: buttons.width
height: buttons.height
StatusBaseText {
id: textItem
anchors.centerIn: parent
visible: !pending
text: {
if (root.accepted) {
return qsTr("Accepted")
} else if (root.dismissed) {
return blocked ? qsTr("Declined & Blocked") : qsTr("Declined")
}
return ""
}
color: {
if (root.accepted) {
return Theme.palette.successColor1
} else if (root.dismissed) {
return Theme.palette.dangerColor1
}
return Theme.palette.directColor1
}
}
AcceptRejectOptionsButtonsPanel {
id: buttons
visible: pending
anchors.centerIn: parent
onAcceptClicked: root.acceptClicked()
onDeclineClicked: root.declineClicked()
onProfileClicked: root.profileClicked()
onBlockClicked: root.blockClicked()
}
}

View File

@ -16,15 +16,14 @@ Item {
property alias bodyComponent: bodyLoader.sourceComponent
property alias badgeComponent: badgeLoader.sourceComponent
property alias actionComponent: actionLoader.sourceComponent
property alias action: actionLoader
property alias ctaComponent: ctaLoader.sourceComponent
height: Math.max(50, bodyLoader.height + (badgeLoader.item ? badgeLoader.height : 0))
Loader {
id: bodyLoader
anchors.top: parent.top
anchors.right: actionLoader.left
anchors.right: ctaLoader.left
anchors.left: parent.left
}
@ -36,8 +35,8 @@ Item {
}
Loader {
id: actionLoader
anchors.verticalCenter: parent.verticalCenter
id: ctaLoader
anchors.bottom: bodyLoader.bottom
anchors.right: parent.right
anchors.rightMargin: Style.current.padding

View File

@ -6,11 +6,24 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import shared 1.0
import shared.panels 1.0
import utils 1.0
import "../panels"
ActivityNotificationMessage {
id: root
// TODO: mark as read ignores notification type
actionComponent: null
ctaComponent: ContactRequestCta {
readonly property string senderId: notification.message.senderId
pending: notification.message.contactRequestState == Constants.contactRequestStatePending
accepted: notification.message.contactRequestState == Constants.contactRequestStateAccepted
dismissed: notification.message.contactRequestState == Constants.contactRequestStateDismissed
blocked: root.store.contactsStore.isBlockedContact(senderId)
onAcceptClicked: root.store.contactsStore.acceptContactRequest(senderId)
onDeclineClicked: root.store.contactsStore.dismissContactRequest(senderId)
onProfileClicked: Global.openProfilePopup(senderId)
onBlockClicked: root.store.contactsStore.blockContact(senderId)
}
}

View File

@ -9,12 +9,13 @@ import utils 1.0
import shared.controls.chat.menuItems 1.0
Row {
id: root
signal acceptClicked()
signal declineClicked()
signal blockClicked()
signal profileClicked()
id: root
height: acceptBtn.height
spacing: Style.current.halfPadding

View File

@ -446,6 +446,11 @@ QtObject {
readonly property int activityCenterNotificationTypeReply: 4
readonly property int activityCenterNotificationTypeContactRequest: 5
readonly property int contactRequestStateNone: 0
readonly property int contactRequestStatePending: 1
readonly property int contactRequestStateAccepted: 2
readonly property int contactRequestStateDismissed: 3
readonly property int maxNbDaysToFetch: 30
readonly property int fetchRangeLast24Hours: 86400
readonly property int fetchRangeLast2Days: 172800