mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-16 16:47:24 +00:00
parent
c2ffb4aee7
commit
cd44b8a606
@ -34,11 +34,10 @@ proc init*(self: ChatController) =
|
|||||||
self.handleSignals()
|
self.handleSignals()
|
||||||
|
|
||||||
let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0")
|
let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0")
|
||||||
let messagesFromContactsOnly = self.status.settings.getSetting[:bool](Setting.MessagesFromContactsOnly, false, true)
|
|
||||||
|
|
||||||
# self.view.pubKey = pubKey
|
# self.view.pubKey = pubKey
|
||||||
self.view.setPubKey(pubKey)
|
self.view.setPubKey(pubKey)
|
||||||
self.status.chat.init(pubKey, messagesFromContactsOnly)
|
self.status.chat.init(pubKey)
|
||||||
self.status.stickers.init()
|
self.status.stickers.init()
|
||||||
self.view.reactions.init()
|
self.view.reactions.init()
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ type
|
|||||||
Read = UserRole + 7
|
Read = UserRole + 7
|
||||||
Dismissed = UserRole + 8
|
Dismissed = UserRole + 8
|
||||||
Accepted = UserRole + 9
|
Accepted = UserRole + 9
|
||||||
|
Author = UserRole + 10
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
@ -71,6 +72,7 @@ QtObject:
|
|||||||
of NotifRoles.Id: result = newQVariant(acitivityNotificationItem.id)
|
of NotifRoles.Id: result = newQVariant(acitivityNotificationItem.id)
|
||||||
of NotifRoles.ChatId: result = newQVariant(acitivityNotificationItem.chatId)
|
of NotifRoles.ChatId: result = newQVariant(acitivityNotificationItem.chatId)
|
||||||
of NotifRoles.Name: result = newQVariant(acitivityNotificationItem.name)
|
of NotifRoles.Name: result = newQVariant(acitivityNotificationItem.name)
|
||||||
|
of NotifRoles.Author: result = newQVariant(acitivityNotificationItem.author)
|
||||||
of NotifRoles.NotificationType: result = newQVariant(acitivityNotificationItem.notificationType.int)
|
of NotifRoles.NotificationType: result = newQVariant(acitivityNotificationItem.notificationType.int)
|
||||||
of NotifRoles.Message: result = newQVariant(acitivityNotificationItem.messageItem)
|
of NotifRoles.Message: result = newQVariant(acitivityNotificationItem.messageItem)
|
||||||
of NotifRoles.Timestamp: result = newQVariant(acitivityNotificationItem.timestamp)
|
of NotifRoles.Timestamp: result = newQVariant(acitivityNotificationItem.timestamp)
|
||||||
@ -86,6 +88,7 @@ QtObject:
|
|||||||
of "id": result = notif.id
|
of "id": result = notif.id
|
||||||
of "chatId": result = notif.chatId
|
of "chatId": result = notif.chatId
|
||||||
of "name": result = notif.name
|
of "name": result = notif.name
|
||||||
|
of "author": result = notif.author
|
||||||
of "notificationType": result = $(notif.notificationType.int)
|
of "notificationType": result = $(notif.notificationType.int)
|
||||||
of "timestamp": result = $(notif.timestamp)
|
of "timestamp": result = $(notif.timestamp)
|
||||||
of "read": result = $(notif.read)
|
of "read": result = $(notif.read)
|
||||||
@ -98,6 +101,7 @@ QtObject:
|
|||||||
NotifRoles.Id.int:"id",
|
NotifRoles.Id.int:"id",
|
||||||
NotifRoles.ChatId.int:"chatId",
|
NotifRoles.ChatId.int:"chatId",
|
||||||
NotifRoles.Name.int: "name",
|
NotifRoles.Name.int: "name",
|
||||||
|
NotifRoles.Author.int: "author",
|
||||||
NotifRoles.NotificationType.int: "notificationType",
|
NotifRoles.NotificationType.int: "notificationType",
|
||||||
NotifRoles.Message.int: "message",
|
NotifRoles.Message.int: "message",
|
||||||
NotifRoles.Timestamp.int: "timestamp",
|
NotifRoles.Timestamp.int: "timestamp",
|
||||||
@ -145,11 +149,54 @@ QtObject:
|
|||||||
let topLeft = self.createIndex(i, 0, nil)
|
let topLeft = self.createIndex(i, 0, nil)
|
||||||
let bottomRight = self.createIndex(i, 0, nil)
|
let bottomRight = self.createIndex(i, 0, nil)
|
||||||
self.dataChanged(topLeft, bottomRight, @[NotifRoles.Read.int])
|
self.dataChanged(topLeft, bottomRight, @[NotifRoles.Read.int])
|
||||||
|
break
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
proc markActivityCenterNotificationRead(self: ActivityNotificationList, id: string): string {.slot.} =
|
proc markActivityCenterNotificationRead(self: ActivityNotificationList, id: string): string {.slot.} =
|
||||||
self.markActivityCenterNotificationsRead(fmt"[""{id}""]")
|
self.markActivityCenterNotificationsRead(fmt"[""{id}""]")
|
||||||
|
|
||||||
|
proc removeNotifications(self: ActivityNotificationList, ids: seq[string]) =
|
||||||
|
var i = 0
|
||||||
|
var indexesToDelete: seq[int] = @[]
|
||||||
|
for activityCenterNotification in self.activityCenterNotifications:
|
||||||
|
for id in ids:
|
||||||
|
if (activityCenterNotification.id == id):
|
||||||
|
indexesToDelete.add(i)
|
||||||
|
break
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
for index in indexesToDelete:
|
||||||
|
let indexUpdated = index - i
|
||||||
|
self.beginRemoveRows(newQModelIndex(), indexUpdated, indexUpdated)
|
||||||
|
self.activityCenterNotifications.delete(indexUpdated)
|
||||||
|
self.endRemoveRows()
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
proc acceptActivityCenterNotifications(self: ActivityNotificationList, idsJson: string): string {.slot.} =
|
||||||
|
let ids = map(parseJson(idsJson).getElems(), proc(x:JsonNode):string = x.getStr())
|
||||||
|
|
||||||
|
let error = self.status.chat.acceptActivityCenterNotifications(ids)
|
||||||
|
if (error != ""):
|
||||||
|
return error
|
||||||
|
|
||||||
|
self.removeNotifications(ids)
|
||||||
|
|
||||||
|
proc acceptActivityCenterNotification(self: ActivityNotificationList, id: string): string {.slot.} =
|
||||||
|
self.acceptActivityCenterNotifications(fmt"[""{id}""]")
|
||||||
|
|
||||||
|
proc dismissActivityCenterNotifications(self: ActivityNotificationList, idsJson: string): string {.slot.} =
|
||||||
|
let ids = map(parseJson(idsJson).getElems(), proc(x:JsonNode):string = x.getStr())
|
||||||
|
|
||||||
|
let error = self.status.chat.dismissActivityCenterNotifications(ids)
|
||||||
|
if (error != ""):
|
||||||
|
return error
|
||||||
|
|
||||||
|
self.removeNotifications(ids)
|
||||||
|
|
||||||
|
proc dismissActivityCenterNotification(self: ActivityNotificationList, id: string): string {.slot.} =
|
||||||
|
self.dismissActivityCenterNotifications(fmt"[""{id}""]")
|
||||||
|
|
||||||
proc toActivityCenterNotificationViewItem*(self: ActivityNotificationList, activityCenterNotification: ActivityCenterNotification): ActivityCenterNotificationViewItem =
|
proc toActivityCenterNotificationViewItem*(self: ActivityNotificationList, activityCenterNotification: ActivityCenterNotification): ActivityCenterNotificationViewItem =
|
||||||
let communityId = self.status.chat.getCommunityIdForChat(activityCenterNotification.chatId)
|
let communityId = self.status.chat.getCommunityIdForChat(activityCenterNotification.chatId)
|
||||||
activityCenterNotification.message.communityId = communityId
|
activityCenterNotification.message.communityId = communityId
|
||||||
@ -158,6 +205,7 @@ QtObject:
|
|||||||
chatId: activityCenterNotification.chatId,
|
chatId: activityCenterNotification.chatId,
|
||||||
name: activityCenterNotification.name,
|
name: activityCenterNotification.name,
|
||||||
notificationType: activityCenterNotification.notificationType,
|
notificationType: activityCenterNotification.notificationType,
|
||||||
|
author: activityCenterNotification.author,
|
||||||
timestamp: activityCenterNotification.timestamp,
|
timestamp: activityCenterNotification.timestamp,
|
||||||
read: activityCenterNotification.read,
|
read: activityCenterNotification.read,
|
||||||
dismissed: activityCenterNotification.dismissed,
|
dismissed: activityCenterNotification.dismissed,
|
||||||
|
@ -52,7 +52,6 @@ type
|
|||||||
|
|
||||||
ChatModel* = ref object
|
ChatModel* = ref object
|
||||||
publicKey*: string
|
publicKey*: string
|
||||||
messagesFromContactsOnly*: bool
|
|
||||||
events*: EventEmitter
|
events*: EventEmitter
|
||||||
communitiesToFetch*: seq[string]
|
communitiesToFetch*: seq[string]
|
||||||
mailserverReady*: bool
|
mailserverReady*: bool
|
||||||
@ -72,7 +71,6 @@ include chat/utils
|
|||||||
|
|
||||||
proc newChatModel*(events: EventEmitter): ChatModel =
|
proc newChatModel*(events: EventEmitter): ChatModel =
|
||||||
result = ChatModel()
|
result = ChatModel()
|
||||||
result.messagesFromContactsOnly = false
|
|
||||||
result.events = events
|
result.events = events
|
||||||
result.mailserverReady = false
|
result.mailserverReady = false
|
||||||
result.communitiesToFetch = @[]
|
result.communitiesToFetch = @[]
|
||||||
@ -86,37 +84,9 @@ proc newChatModel*(events: EventEmitter): ChatModel =
|
|||||||
proc delete*(self: ChatModel) =
|
proc delete*(self: ChatModel) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc cleanSpamChatGroups(self: ChatModel, chats: seq[Chat], contacts: seq[Profile]): seq[Chat] =
|
|
||||||
for chat in chats:
|
|
||||||
if not chat.isActive: continue
|
|
||||||
if chat.chatType == ChatType.PrivateGroupChat:
|
|
||||||
var isContact = false
|
|
||||||
var joined = false
|
|
||||||
for member in chat.members:
|
|
||||||
if member.id == self.publicKey and member.joined:
|
|
||||||
joined = true
|
|
||||||
if member.admin and member.joined:
|
|
||||||
for contact in contacts:
|
|
||||||
if contact.address == member.id:
|
|
||||||
isContact = true
|
|
||||||
if not isContact and not joined:
|
|
||||||
discard status_chat.deactivateChat(chat)
|
|
||||||
else:
|
|
||||||
result.add(chat)
|
|
||||||
else:
|
|
||||||
result.add(chat)
|
|
||||||
|
|
||||||
proc update*(self: ChatModel, chats: seq[Chat], messages: seq[Message], emojiReactions: seq[Reaction], communities: seq[Community], communityMembershipRequests: seq[CommunityMembershipRequest], pinnedMessages: seq[Message], activityCenterNotifications: seq[ActivityCenterNotification]) =
|
proc update*(self: ChatModel, chats: seq[Chat], messages: seq[Message], emojiReactions: seq[Reaction], communities: seq[Community], communityMembershipRequests: seq[CommunityMembershipRequest], pinnedMessages: seq[Message], activityCenterNotifications: seq[ActivityCenterNotification]) =
|
||||||
var contacts = getAddedContacts()
|
for chat in chats:
|
||||||
|
self.channels[chat.id] = chat
|
||||||
var chatList = chats
|
|
||||||
if (self.messagesFromContactsOnly):
|
|
||||||
# Automatically decline chat group invitations if admin is not a contact
|
|
||||||
chatList = self.cleanSpamChatGroups(chats, contacts)
|
|
||||||
|
|
||||||
for chat in chatList:
|
|
||||||
if chat.isActive:
|
|
||||||
self.channels[chat.id] = chat
|
|
||||||
|
|
||||||
for message in messages:
|
for message in messages:
|
||||||
let chatId = message.chatId
|
let chatId = message.chatId
|
||||||
@ -127,7 +97,7 @@ proc update*(self: ChatModel, chats: seq[Chat], messages: seq[Message], emojiRea
|
|||||||
if self.lastMessageTimestamps[chatId] > ts:
|
if self.lastMessageTimestamps[chatId] > ts:
|
||||||
self.lastMessageTimestamps[chatId] = ts
|
self.lastMessageTimestamps[chatId] = ts
|
||||||
|
|
||||||
self.events.emit("chatUpdate", ChatUpdateArgs(messages: messages,chats: chatList, contacts: @[], emojiReactions: emojiReactions, communities: communities, communityMembershipRequests: communityMembershipRequests, pinnedMessages: pinnedMessages, activityCenterNotifications: activityCenterNotifications))
|
self.events.emit("chatUpdate", ChatUpdateArgs(messages: messages,chats: chats, contacts: @[], emojiReactions: emojiReactions, communities: communities, communityMembershipRequests: communityMembershipRequests, pinnedMessages: pinnedMessages, activityCenterNotifications: activityCenterNotifications))
|
||||||
|
|
||||||
proc hasChannel*(self: ChatModel, chatId: string): bool =
|
proc hasChannel*(self: ChatModel, chatId: string): bool =
|
||||||
self.channels.hasKey(chatId)
|
self.channels.hasKey(chatId)
|
||||||
@ -178,16 +148,12 @@ proc requestMissingCommunityInfos*(self: ChatModel) =
|
|||||||
for communityId in self.communitiesToFetch:
|
for communityId in self.communitiesToFetch:
|
||||||
status_chat.requestCommunityInfo(communityId)
|
status_chat.requestCommunityInfo(communityId)
|
||||||
|
|
||||||
proc init*(self: ChatModel, pubKey: string, messagesFromContactsOnly: bool) =
|
proc init*(self: ChatModel, pubKey: string) =
|
||||||
self.publicKey = pubKey
|
self.publicKey = pubKey
|
||||||
self.messagesFromContactsOnly = messagesFromContactsOnly
|
|
||||||
|
|
||||||
var contacts = getAddedContacts()
|
var contacts = getAddedContacts()
|
||||||
var chatList = status_chat.loadChats()
|
var chatList = status_chat.loadChats()
|
||||||
|
|
||||||
if (messagesFromContactsOnly):
|
|
||||||
chatList = self.cleanSpamChatGroups(chatList, contacts)
|
|
||||||
|
|
||||||
let profileUpdatesChatIds = chatList.filter(c => c.chatType == ChatType.Profile).map(c => c.id)
|
let profileUpdatesChatIds = chatList.filter(c => c.chatType == ChatType.Profile).map(c => c.id)
|
||||||
|
|
||||||
if chatList.filter(c => c.chatType == ChatType.Timeline).len == 0:
|
if chatList.filter(c => c.chatType == ChatType.Timeline).len == 0:
|
||||||
@ -576,6 +542,25 @@ proc markActivityCenterNotificationsRead*(self: ChatModel, ids: seq[string]): st
|
|||||||
error "Error marking as read", msg = e.msg
|
error "Error marking as read", msg = e.msg
|
||||||
result = e.msg
|
result = e.msg
|
||||||
|
|
||||||
|
proc acceptActivityCenterNotifications*(self: ChatModel, ids: seq[string]): string =
|
||||||
|
try:
|
||||||
|
let response = status_chat.acceptActivityCenterNotifications(ids)
|
||||||
|
|
||||||
|
let resultTuple = self.processChatUpdate(parseJson(response))
|
||||||
|
let (chats, messages) = resultTuple
|
||||||
|
self.events.emit("chatUpdate", ChatUpdateArgs(messages: messages, chats: chats))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
error "Error marking as accepted", msg = e.msg
|
||||||
|
result = e.msg
|
||||||
|
|
||||||
|
proc dismissActivityCenterNotifications*(self: ChatModel, ids: seq[string]): string =
|
||||||
|
try:
|
||||||
|
discard status_chat.dismissActivityCenterNotifications(ids)
|
||||||
|
except Exception as e:
|
||||||
|
error "Error marking as dismissed", msg = e.msg
|
||||||
|
result = e.msg
|
||||||
|
|
||||||
proc unreadActivityCenterNotificationsCount*(self: ChatModel): int =
|
proc unreadActivityCenterNotificationsCount*(self: ChatModel): int =
|
||||||
status_chat.unreadActivityCenterNotificationsCount()
|
status_chat.unreadActivityCenterNotificationsCount()
|
||||||
|
|
||||||
|
@ -134,6 +134,7 @@ type ActivityCenterNotification* = ref object of RootObj
|
|||||||
id*: string # ID is the id of the chat, for public chats it is the name e.g. status, for one-to-one is the hex encoded public key and for group chats is a random uuid appended with the hex encoded pk of the creator of the chat
|
id*: string # ID is the id of the chat, for public chats it is the name e.g. status, for one-to-one is the hex encoded public key and for group chats is a random uuid appended with the hex encoded pk of the creator of the chat
|
||||||
chatId*: string
|
chatId*: string
|
||||||
name*: string
|
name*: string
|
||||||
|
author*: string
|
||||||
notificationType*: ActivityCenterNotificationType
|
notificationType*: ActivityCenterNotificationType
|
||||||
message*: Message
|
message*: Message
|
||||||
timestamp*: int64
|
timestamp*: int64
|
||||||
|
@ -604,7 +604,13 @@ proc markAllActivityCenterNotificationsRead*() =
|
|||||||
discard callPrivateRPC("markAllActivityCenterNotificationsRead".prefix, %*[])
|
discard callPrivateRPC("markAllActivityCenterNotificationsRead".prefix, %*[])
|
||||||
|
|
||||||
proc markActivityCenterNotificationsRead*(ids: seq[string]) =
|
proc markActivityCenterNotificationsRead*(ids: seq[string]) =
|
||||||
let res = callPrivateRPC("markActivityCenterNotificationsRead".prefix, %*[ids])
|
discard callPrivateRPC("markActivityCenterNotificationsRead".prefix, %*[ids])
|
||||||
|
|
||||||
|
proc acceptActivityCenterNotifications*(ids: seq[string]): string =
|
||||||
|
result = callPrivateRPC("acceptActivityCenterNotifications".prefix, %*[ids])
|
||||||
|
|
||||||
|
proc dismissActivityCenterNotifications*(ids: seq[string]): string =
|
||||||
|
result = callPrivateRPC("dismissActivityCenterNotifications".prefix, %*[ids])
|
||||||
|
|
||||||
proc unreadActivityCenterNotificationsCount*(): int =
|
proc unreadActivityCenterNotificationsCount*(): int =
|
||||||
let rpcResult = callPrivateRPC("unreadActivityCenterNotificationsCount".prefix, %*[]).parseJson
|
let rpcResult = callPrivateRPC("unreadActivityCenterNotificationsCount".prefix, %*[]).parseJson
|
||||||
|
@ -385,6 +385,7 @@ proc toActivityCenterNotification*(jsonNotification: JsonNode, pk: string): Acti
|
|||||||
id: jsonNotification{"id"}.getStr,
|
id: jsonNotification{"id"}.getStr,
|
||||||
chatId: jsonNotification{"chatId"}.getStr,
|
chatId: jsonNotification{"chatId"}.getStr,
|
||||||
name: jsonNotification{"name"}.getStr,
|
name: jsonNotification{"name"}.getStr,
|
||||||
|
author: jsonNotification{"author"}.getStr,
|
||||||
notificationType: activityCenterNotificationType,
|
notificationType: activityCenterNotificationType,
|
||||||
timestamp: jsonNotification{"timestamp"}.getInt,
|
timestamp: jsonNotification{"timestamp"}.getInt,
|
||||||
read: jsonNotification{"read"}.getBool,
|
read: jsonNotification{"read"}.getBool,
|
||||||
|
@ -104,6 +104,7 @@ Popup {
|
|||||||
|
|
||||||
DelegateModelGeneralized {
|
DelegateModelGeneralized {
|
||||||
id: notifDelegateList
|
id: notifDelegateList
|
||||||
|
|
||||||
lessThan: [
|
lessThan: [
|
||||||
function(left, right) { return left.timestamp > right.timestamp }
|
function(left, right) { return left.timestamp > right.timestamp }
|
||||||
]
|
]
|
||||||
@ -135,15 +136,30 @@ Popup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
property int previousNotificationIndex: {
|
||||||
|
if (notificationDelegate.idx === 0) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is used in order to have access to the previous message and determine the timestamp
|
||||||
|
// we can't rely on the index because the sequence of messages is not ordered on the nim side
|
||||||
|
if (notificationDelegate.idx < notifDelegateList.items.count - 1) {
|
||||||
|
return notifDelegateList.items.get(notificationDelegate.idx - 1).model.index
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
property string previousNotificationTimestamp: notificationDelegate.idx === 0 ? "" : chatsModel.activityNotificationList.getNotificationData(previousNotificationIndex, "timestamp")
|
||||||
|
|
||||||
|
|
||||||
id: notifLoader
|
id: notifLoader
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
active: !!sourceComponent
|
active: !!sourceComponent
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: active && item.visible ? item.height : 0
|
|
||||||
sourceComponent: {
|
sourceComponent: {
|
||||||
switch (model.notificationType) {
|
switch (model.notificationType) {
|
||||||
case Constants.activityCenterNotificationTypeMention:return messageNotificationComponent
|
case Constants.activityCenterNotificationTypeMention:return messageNotificationComponent
|
||||||
case Constants.activityCenterNotificationTypeReply: return messageNotificationComponent
|
case Constants.activityCenterNotificationTypeReply: return messageNotificationComponent
|
||||||
|
case Constants.activityCenterNotificationTypeGroupRequest: return groupRequestNotificationComponent
|
||||||
default: return null
|
default: return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,128 +168,13 @@ Popup {
|
|||||||
Component {
|
Component {
|
||||||
id: messageNotificationComponent
|
id: messageNotificationComponent
|
||||||
|
|
||||||
Item {
|
ActivityCenterMessageComponent {}
|
||||||
visible: {
|
}
|
||||||
if (hideReadNotifications && model.read) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return activityCenter.currentFilter === ActivityCenter.Filter.All ||
|
Component {
|
||||||
(model.notificationType === Constants.activityCenterNotificationTypeMention && activityCenter.currentFilter === ActivityCenter.Filter.Mentions) ||
|
id: groupRequestNotificationComponent
|
||||||
(model.notificationType === Constants.activityCenterNotificationTypeReply && activityCenter.currentFilter === ActivityCenter.Filter.Replies)
|
|
||||||
}
|
|
||||||
width: parent.width
|
|
||||||
height: messageNotificationContent.height
|
|
||||||
|
|
||||||
StatusIconButton {
|
ActivityCenterGroupRequest {}
|
||||||
id: markReadBtn
|
|
||||||
icon.name: "double-check"
|
|
||||||
iconColor: Style.current.primary
|
|
||||||
icon.width: 24
|
|
||||||
icon.height: 24
|
|
||||||
width: 32
|
|
||||||
height: 32
|
|
||||||
onClicked: chatsModel.activityNotificationList.markActivityCenterNotificationRead(model.id)
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 12
|
|
||||||
anchors.verticalCenter: messageNotificationContent.verticalCenter
|
|
||||||
z: 52
|
|
||||||
|
|
||||||
StatusToolTip {
|
|
||||||
visible: markReadBtn.hovered
|
|
||||||
text: qsTr("Mark as Read")
|
|
||||||
orientation: "left"
|
|
||||||
x: - width - Style.current.padding
|
|
||||||
y: markReadBtn.height / 2 - height / 2 + 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: messageNotificationContent
|
|
||||||
width: parent.width
|
|
||||||
height: childrenRect.height
|
|
||||||
|
|
||||||
Message {
|
|
||||||
id: notificationMessage
|
|
||||||
anchors.right: undefined
|
|
||||||
fromAuthor: model.message.fromAuthor
|
|
||||||
chatId: model.message.chatId
|
|
||||||
userName: model.message.userName
|
|
||||||
alias: model.message.alias
|
|
||||||
localName: model.message.localName
|
|
||||||
message: model.message.message
|
|
||||||
plainText: model.message.plainText
|
|
||||||
identicon: model.message.identicon
|
|
||||||
isCurrentUser: model.message.isCurrentUser
|
|
||||||
timestamp: model.message.timestamp
|
|
||||||
sticker: model.message.sticker
|
|
||||||
contentType: model.message.contentType
|
|
||||||
outgoingStatus: model.message.outgoingStatus
|
|
||||||
responseTo: model.message.responseTo
|
|
||||||
imageClick: imagePopup.openPopup.bind(imagePopup)
|
|
||||||
messageId: model.message.messageId
|
|
||||||
linkUrls: model.message.linkUrls
|
|
||||||
communityId: model.message.communityId
|
|
||||||
hasMention: model.message.hasMention
|
|
||||||
stickerPackId: model.message.stickerPackId
|
|
||||||
pinnedBy: model.message.pinnedBy
|
|
||||||
pinnedMessage: model.message.isPinned
|
|
||||||
activityCenterMessage: true
|
|
||||||
read: model.read
|
|
||||||
clickMessage: function (isProfileClick) {
|
|
||||||
if (isProfileClick) {
|
|
||||||
const pk = model.message.fromAuthor
|
|
||||||
const userProfileImage = appMain.getProfileImage(pk)
|
|
||||||
return openProfilePopup(chatsModel.userNameOrAlias(pk), pk, userProfileImage || utilsModel.generateIdenticon(pk))
|
|
||||||
}
|
|
||||||
|
|
||||||
activityCenter.close()
|
|
||||||
|
|
||||||
if (model.message.communityId) {
|
|
||||||
chatsModel.communities.setActiveCommunity(model.message.communityId)
|
|
||||||
}
|
|
||||||
|
|
||||||
chatsModel.channelView.setActiveChannel(model.message.chatId)
|
|
||||||
positionAtMessage(model.message.messageId)
|
|
||||||
}
|
|
||||||
|
|
||||||
prevMessageIndex: {
|
|
||||||
if (notificationDelegate.idx === 0) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is used in order to have access to the previous message and determine the timestamp
|
|
||||||
// we can't rely on the index because the sequence of messages is not ordered on the nim side
|
|
||||||
if (notificationDelegate.idx < notifDelegateList.items.count - 1) {
|
|
||||||
return notifDelegateList.items.get(notificationDelegate.idx - 1).model.index
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
prevMsgTimestamp: notificationDelegate.idx === 0 ? "" : chatsModel.activityNotificationList.getNotificationData(prevMessageIndex, "timestamp")
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.top: notificationMessage.bottom
|
|
||||||
anchors.bottom: badge.bottom
|
|
||||||
anchors.bottomMargin: -Style.current.smallPadding
|
|
||||||
width: parent.width
|
|
||||||
color: model.read ? Style.current.transparent : Utils.setColorAlpha(Style.current.blue, 0.1)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ActivityChannelBadge {
|
|
||||||
id: badge
|
|
||||||
name: model.name
|
|
||||||
chatId: model.chatId
|
|
||||||
notificationType: model.notificationType
|
|
||||||
responseTo: model.message.responseTo
|
|
||||||
communityId: model.message.communityId
|
|
||||||
anchors.top: notificationMessage.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 61 // TODO find a way to align with the text of the message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,171 @@
|
|||||||
|
import QtQuick 2.13
|
||||||
|
import QtGraphicalEffects 1.13
|
||||||
|
import "../../../../../imports"
|
||||||
|
import "../../../../../shared"
|
||||||
|
import "../../../../../shared/status"
|
||||||
|
import "../MessageComponents"
|
||||||
|
import "../../components"
|
||||||
|
import ".."
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width
|
||||||
|
height: childrenRect.height + dateGroupLbl.anchors.topMargin
|
||||||
|
|
||||||
|
DateGroup {
|
||||||
|
id: dateGroupLbl
|
||||||
|
previousMessageIndex: previousNotificationIndex
|
||||||
|
previousMessageTimestamp: previousNotificationTimestamp
|
||||||
|
messageTimestamp: model.timestamp
|
||||||
|
isActivityCenterMessage: true
|
||||||
|
height: visible ? implicitHeight : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: groupRequestContent
|
||||||
|
property string timestamp: model.timestamp
|
||||||
|
|
||||||
|
visible: {
|
||||||
|
if (hideReadNotifications && model.read) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return activityCenter.currentFilter === ActivityCenter.Filter.All
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
height: visible ? 60 : 0
|
||||||
|
anchors.top: dateGroupLbl.bottom
|
||||||
|
anchors.topMargin: dateGroupLbl.visible ? 4 : 0
|
||||||
|
color: model.read ? Style.current.transparent : Utils.setColorAlpha(Style.current.blue, 0.1)
|
||||||
|
|
||||||
|
StatusIdenticon {
|
||||||
|
id: channelIdenticon
|
||||||
|
height: 40
|
||||||
|
width: 40
|
||||||
|
chatId: model.chatId
|
||||||
|
chatName: model.name
|
||||||
|
chatType: Constants.chatTypePrivateGroupChat
|
||||||
|
identicon: ""
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Style.current.padding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: nameItem
|
||||||
|
width: childrenRect.width
|
||||||
|
height: chatName.name
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: Style.current.halfPadding
|
||||||
|
// TODO fix anchoring to center when there is no author
|
||||||
|
// anchors.top: inviteText.visible ? parent.top: undefined
|
||||||
|
// anchors.topMargin: inviteText.visible ? Style.current.halfPadding : 0
|
||||||
|
// anchors.verticalCenter: inviteText.visible ? undefined : parent.verticalCenter
|
||||||
|
anchors.left: channelIdenticon.right
|
||||||
|
anchors.leftMargin: Style.current.halfPadding
|
||||||
|
|
||||||
|
SVGImage {
|
||||||
|
id: groupImage
|
||||||
|
width: 16
|
||||||
|
height: 16
|
||||||
|
anchors.verticalCenter: chatName.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
source: "../../../../img/channel-icon-group.svg"
|
||||||
|
|
||||||
|
ColorOverlay {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: parent
|
||||||
|
color: chatName.color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: chatName
|
||||||
|
text: model.name
|
||||||
|
anchors.left: groupImage.right
|
||||||
|
anchors.leftMargin: 4
|
||||||
|
font.pixelSize: 15
|
||||||
|
font.weight: Font.Medium
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatTime {
|
||||||
|
anchors.verticalCenter: chatName.verticalCenter
|
||||||
|
anchors.left: chatName.right
|
||||||
|
anchors.leftMargin: 4
|
||||||
|
font.pixelSize: 10
|
||||||
|
visible: true
|
||||||
|
color: Style.current.secondaryText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openProfile() {
|
||||||
|
const pk = model.author
|
||||||
|
const userProfileImage = appMain.getProfileImage(pk)
|
||||||
|
openProfilePopup(chatsModel.userNameOrAlias(pk), pk, userProfileImage || utilsModel.generateIdenticon(pk))
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledTextEdit {
|
||||||
|
id: inviteText
|
||||||
|
visible: !!model.author
|
||||||
|
text: {
|
||||||
|
if (!visible) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
let name = chatsModel.userNameOrAlias(model.author)
|
||||||
|
if (name.length > 20) {
|
||||||
|
name = name.substring(0, 9) + "..." + name.substring(name.length - 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
return qsTr("%1 invited you to join the group")
|
||||||
|
.arg(`<style type="text/css">`+
|
||||||
|
`a {`+
|
||||||
|
`color: ${Style.current.primary};`+
|
||||||
|
`text-decoration: none;` +
|
||||||
|
`}`+
|
||||||
|
`</style>`+
|
||||||
|
`<a href="#">${name}</a>`)
|
||||||
|
}
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: Style.current.halfPadding
|
||||||
|
anchors.left: nameItem.left
|
||||||
|
anchors.right: buttons.left
|
||||||
|
anchors.rightMargin: Style.current.halfPadding
|
||||||
|
clip: true
|
||||||
|
font.pixelSize: 15
|
||||||
|
font.weight: Font.Medium
|
||||||
|
readOnly: true
|
||||||
|
selectByMouse: true
|
||||||
|
textFormat: Text.RichText
|
||||||
|
onLinkActivated: groupRequestContent.openProfile()
|
||||||
|
onLinkHovered: {
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AcceptRejectOptionsButtons {
|
||||||
|
id: buttons
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Style.current.halfPadding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onAcceptClicked: chatsModel.activityNotificationList.acceptActivityCenterNotification(model.id)
|
||||||
|
onDeclineClicked: chatsModel.activityNotificationList.dismissActivityCenterNotification(model.id)
|
||||||
|
onProfileClicked: groupRequestContent.openProfile()
|
||||||
|
onBlockClicked: {
|
||||||
|
const pk = model.author
|
||||||
|
blockContactConfirmationDialog.contactName = chatsModel.userNameOrAlias(pk)
|
||||||
|
blockContactConfirmationDialog.contactAddress = pk
|
||||||
|
blockContactConfirmationDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockContactConfirmationDialog {
|
||||||
|
id: blockContactConfirmationDialog
|
||||||
|
onBlockButtonClicked: {
|
||||||
|
profileModel.contacts.blockContact(blockContactConfirmationDialog.contactAddress)
|
||||||
|
chatsModel.activityNotificationList.dismissActivityCenterNotification(model.id)
|
||||||
|
blockContactConfirmationDialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,118 @@
|
|||||||
|
import QtQuick 2.13
|
||||||
|
import "../../../../../imports"
|
||||||
|
import "../../../../../shared"
|
||||||
|
import "../../../../../shared/status"
|
||||||
|
import ".."
|
||||||
|
|
||||||
|
|
||||||
|
Item {
|
||||||
|
visible: {
|
||||||
|
if (hideReadNotifications && model.read) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return activityCenter.currentFilter === ActivityCenter.Filter.All ||
|
||||||
|
(model.notificationType === Constants.activityCenterNotificationTypeMention && activityCenter.currentFilter === ActivityCenter.Filter.Mentions) ||
|
||||||
|
(model.notificationType === Constants.activityCenterNotificationTypeReply && activityCenter.currentFilter === ActivityCenter.Filter.Replies)
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
height: visible ? messageNotificationContent.height : 0
|
||||||
|
|
||||||
|
StatusIconButton {
|
||||||
|
id: markReadBtn
|
||||||
|
icon.name: "double-check"
|
||||||
|
iconColor: Style.current.primary
|
||||||
|
icon.width: 24
|
||||||
|
icon.height: 24
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
onClicked: chatsModel.activityNotificationList.markActivityCenterNotificationRead(model.id)
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 12
|
||||||
|
anchors.verticalCenter: messageNotificationContent.verticalCenter
|
||||||
|
z: 52
|
||||||
|
|
||||||
|
StatusToolTip {
|
||||||
|
visible: markReadBtn.hovered
|
||||||
|
text: qsTr("Mark as Read")
|
||||||
|
orientation: "left"
|
||||||
|
x: - width - Style.current.padding
|
||||||
|
y: markReadBtn.height / 2 - height / 2 + 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: messageNotificationContent
|
||||||
|
width: parent.width
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
Message {
|
||||||
|
id: notificationMessage
|
||||||
|
anchors.right: undefined
|
||||||
|
fromAuthor: model.message.fromAuthor
|
||||||
|
chatId: model.message.chatId
|
||||||
|
userName: model.message.userName
|
||||||
|
alias: model.message.alias
|
||||||
|
localName: model.message.localName
|
||||||
|
message: model.message.message
|
||||||
|
plainText: model.message.plainText
|
||||||
|
identicon: model.message.identicon
|
||||||
|
isCurrentUser: model.message.isCurrentUser
|
||||||
|
timestamp: model.message.timestamp
|
||||||
|
sticker: model.message.sticker
|
||||||
|
contentType: model.message.contentType
|
||||||
|
outgoingStatus: model.message.outgoingStatus
|
||||||
|
responseTo: model.message.responseTo
|
||||||
|
imageClick: imagePopup.openPopup.bind(imagePopup)
|
||||||
|
messageId: model.message.messageId
|
||||||
|
linkUrls: model.message.linkUrls
|
||||||
|
communityId: model.message.communityId
|
||||||
|
hasMention: model.message.hasMention
|
||||||
|
stickerPackId: model.message.stickerPackId
|
||||||
|
pinnedBy: model.message.pinnedBy
|
||||||
|
pinnedMessage: model.message.isPinned
|
||||||
|
activityCenterMessage: true
|
||||||
|
read: model.read
|
||||||
|
clickMessage: function (isProfileClick) {
|
||||||
|
if (isProfileClick) {
|
||||||
|
const pk = model.message.fromAuthor
|
||||||
|
const userProfileImage = appMain.getProfileImage(pk)
|
||||||
|
return openProfilePopup(chatsModel.userNameOrAlias(pk), pk, userProfileImage || utilsModel.generateIdenticon(pk))
|
||||||
|
}
|
||||||
|
|
||||||
|
activityCenter.close()
|
||||||
|
|
||||||
|
if (model.message.communityId) {
|
||||||
|
chatsModel.communities.setActiveCommunity(model.message.communityId)
|
||||||
|
}
|
||||||
|
|
||||||
|
chatsModel.channelView.setActiveChannel(model.message.chatId)
|
||||||
|
positionAtMessage(model.message.messageId)
|
||||||
|
}
|
||||||
|
|
||||||
|
prevMessageIndex: previousNotificationIndex
|
||||||
|
prevMsgTimestamp: previousNotificationTimestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.top: notificationMessage.bottom
|
||||||
|
anchors.bottom: badge.bottom
|
||||||
|
anchors.bottomMargin: -Style.current.smallPadding
|
||||||
|
width: parent.width
|
||||||
|
color: model.read ? Style.current.transparent : Utils.setColorAlpha(Style.current.blue, 0.1)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityChannelBadge {
|
||||||
|
id: badge
|
||||||
|
name: model.name
|
||||||
|
chatId: model.chatId
|
||||||
|
notificationType: model.notificationType
|
||||||
|
responseTo: model.message.responseTo
|
||||||
|
communityId: model.message.communityId
|
||||||
|
anchors.top: notificationMessage.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 61 // TODO find a way to align with the text of the message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -58,6 +58,7 @@ Item {
|
|||||||
previousMessageIndex: prevMessageIndex
|
previousMessageIndex: prevMessageIndex
|
||||||
previousMessageTimestamp: prevMsgTimestamp
|
previousMessageTimestamp: prevMsgTimestamp
|
||||||
messageTimestamp: timestamp
|
messageTimestamp: timestamp
|
||||||
|
isActivityCenterMessage: activityCenterMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
@ -3,6 +3,7 @@ import "../../../../../shared"
|
|||||||
import "../../../../../imports"
|
import "../../../../../imports"
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
property bool isActivityCenterMessage: false
|
||||||
property int previousMessageIndex: -1
|
property int previousMessageIndex: -1
|
||||||
property string previousMessageTimestamp
|
property string previousMessageTimestamp
|
||||||
property string messageTimestamp
|
property string messageTimestamp
|
||||||
@ -11,11 +12,11 @@ StyledText {
|
|||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
color: Style.current.secondaryText
|
color: Style.current.secondaryText
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
anchors.horizontalCenter: activityCenterMessage ? undefined : parent.horizontalCenter
|
anchors.horizontalCenter: isActivityCenterMessage ? undefined : parent.horizontalCenter
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: visible ? (activityCenterMessage ? Style.current.halfPadding : 20) : 0
|
anchors.topMargin: visible ? (isActivityCenterMessage ? Style.current.halfPadding : 20) : 0
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: activityCenterMessage ? Style.current.padding : 0
|
anchors.leftMargin: isActivityCenterMessage ? Style.current.padding : 0
|
||||||
|
|
||||||
text: {
|
text: {
|
||||||
if (previousMessageIndex === -1) return ""; // identifier
|
if (previousMessageIndex === -1) return ""; // identifier
|
||||||
|
@ -21,6 +21,7 @@ Item {
|
|||||||
previousMessageIndex: prevMessageIndex
|
previousMessageIndex: prevMessageIndex
|
||||||
previousMessageTimestamp: prevMsgTimestamp
|
previousMessageTimestamp: prevMsgTimestamp
|
||||||
messageTimestamp: timestamp
|
messageTimestamp: timestamp
|
||||||
|
isActivityCenterMessage: activityCenterMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
UserImage {
|
UserImage {
|
||||||
|
@ -0,0 +1,81 @@
|
|||||||
|
import QtQuick 2.13
|
||||||
|
import QtQuick.Controls 2.13
|
||||||
|
import QtQuick.Layouts 1.13
|
||||||
|
import "../../../../imports"
|
||||||
|
import "../../../../shared"
|
||||||
|
import "../../../../shared/status"
|
||||||
|
|
||||||
|
Row {
|
||||||
|
signal acceptClicked()
|
||||||
|
signal declineClicked()
|
||||||
|
signal blockClicked()
|
||||||
|
signal profileClicked()
|
||||||
|
|
||||||
|
id: root
|
||||||
|
height: acceptBtn.height
|
||||||
|
spacing: Style.current.halfPadding
|
||||||
|
|
||||||
|
StatusIconButton {
|
||||||
|
id: acceptBtn
|
||||||
|
icon.name: "check-circle"
|
||||||
|
onClicked: root.acceptClicked()
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
padding: 6
|
||||||
|
iconColor: Style.current.success
|
||||||
|
hoveredIconColor: Style.current.success
|
||||||
|
highlightedBackgroundColor: Utils.setColorAlpha(Style.current.success, 0.1)
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusIconButton {
|
||||||
|
id: declineBtn
|
||||||
|
icon.name: "close"
|
||||||
|
onClicked: root.declineClicked()
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
padding: 6
|
||||||
|
iconColor: Style.current.danger
|
||||||
|
hoveredIconColor: Style.current.danger
|
||||||
|
highlightedBackgroundColor: Utils.setColorAlpha(Style.current.danger, 0.1)
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusContextMenuButton {
|
||||||
|
property int iconSize: 14
|
||||||
|
id: menuButton
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
contactContextMenu.popup()
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupMenu {
|
||||||
|
id: contactContextMenu
|
||||||
|
hasArrow: false
|
||||||
|
Action {
|
||||||
|
icon.source: "../../../img/profileActive.svg"
|
||||||
|
icon.width: menuButton.iconSize
|
||||||
|
icon.height: menuButton.iconSize
|
||||||
|
//% "View Profile"
|
||||||
|
text: qsTrId("view-profile")
|
||||||
|
onTriggered: root.profileClicked()
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
Separator {}
|
||||||
|
Action {
|
||||||
|
icon.source: "../../../img/block-icon.svg"
|
||||||
|
icon.width: menuButton.iconSize
|
||||||
|
icon.height: menuButton.iconSize
|
||||||
|
icon.color: Style.current.danger
|
||||||
|
text: qsTr("Decline and block")
|
||||||
|
onTriggered: root.blockClicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -39,7 +39,7 @@ Rectangle {
|
|||||||
anchors.topMargin: Style.current.smallPadding
|
anchors.topMargin: Style.current.smallPadding
|
||||||
anchors.left: accountImage.right
|
anchors.left: accountImage.right
|
||||||
anchors.leftMargin: Style.current.padding
|
anchors.leftMargin: Style.current.padding
|
||||||
anchors.right: declineBtn.left
|
anchors.right: buttons.left
|
||||||
anchors.rightMargin: Style.current.padding
|
anchors.rightMargin: Style.current.padding
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,76 +58,17 @@ Rectangle {
|
|||||||
onHoveredChanged: container.isHovered = hovered
|
onHoveredChanged: container.isHovered = hovered
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusIconButton {
|
AcceptRejectOptionsButtons {
|
||||||
id: declineBtn
|
id: buttons
|
||||||
icon.name: "close"
|
anchors.right: parent.right
|
||||||
onClicked: profileModel.contacts.rejectContactRequest(container.address)
|
anchors.rightMargin: Style.current.padding
|
||||||
width: 32
|
|
||||||
height: 32
|
|
||||||
padding: 6
|
|
||||||
iconColor: Style.current.danger
|
|
||||||
hoveredIconColor: Style.current.danger
|
|
||||||
highlightedBackgroundColor: Utils.setColorAlpha(Style.current.danger, 0.1)
|
|
||||||
anchors.right: acceptBtn.left
|
|
||||||
anchors.rightMargin: Style.current.halfPadding
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
onAcceptClicked: {
|
||||||
|
|
||||||
StatusIconButton {
|
|
||||||
id: acceptBtn
|
|
||||||
icon.name: "check-circle"
|
|
||||||
onClicked: {
|
|
||||||
chatsModel.channelView.joinPrivateChat(container.address, "")
|
chatsModel.channelView.joinPrivateChat(container.address, "")
|
||||||
profileModel.contacts.addContact(container.address)
|
profileModel.contacts.addContact(container.address)
|
||||||
}
|
}
|
||||||
width: 32
|
onDeclineClicked: profileModel.contacts.rejectContactRequest(container.address)
|
||||||
height: 32
|
onProfileClicked: profileClick(true, name, address, identicon, "", localNickname)
|
||||||
padding: 6
|
onBlockClicked: container.blockContactActionTriggered(name, address)
|
||||||
iconColor: Style.current.success
|
|
||||||
hoveredIconColor: Style.current.success
|
|
||||||
highlightedBackgroundColor: Utils.setColorAlpha(Style.current.success, 0.1)
|
|
||||||
anchors.right: menuButton.left
|
|
||||||
anchors.rightMargin: Style.current.halfPadding
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusContextMenuButton {
|
|
||||||
property int iconSize: 14
|
|
||||||
id: menuButton
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: Style.current.padding
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
contactContextMenu.popup()
|
|
||||||
}
|
|
||||||
|
|
||||||
PopupMenu {
|
|
||||||
id: contactContextMenu
|
|
||||||
hasArrow: false
|
|
||||||
Action {
|
|
||||||
icon.source: "../../../img/profileActive.svg"
|
|
||||||
icon.width: menuButton.iconSize
|
|
||||||
icon.height: menuButton.iconSize
|
|
||||||
//% "View Profile"
|
|
||||||
text: qsTrId("view-profile")
|
|
||||||
onTriggered: profileClick(true, name, address, identicon, "", localNickname)
|
|
||||||
enabled: true
|
|
||||||
}
|
|
||||||
Separator {}
|
|
||||||
Action {
|
|
||||||
icon.source: "../../../img/block-icon.svg"
|
|
||||||
icon.width: menuButton.iconSize
|
|
||||||
icon.height: menuButton.iconSize
|
|
||||||
icon.color: Style.current.danger
|
|
||||||
text: qsTr("Decline and block")
|
|
||||||
onTriggered: container.blockContactActionTriggered(name, address)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ QtObject {
|
|||||||
readonly property int communityChatOnRequestAccess: 3
|
readonly property int communityChatOnRequestAccess: 3
|
||||||
|
|
||||||
|
|
||||||
|
readonly property int activityCenterNotificationTypeGroupRequest: 2
|
||||||
readonly property int activityCenterNotificationTypeMention: 3
|
readonly property int activityCenterNotificationTypeMention: 3
|
||||||
readonly property int activityCenterNotificationTypeReply: 4
|
readonly property int activityCenterNotificationTypeReply: 4
|
||||||
|
|
||||||
|
@ -97,6 +97,8 @@ DISTFILES += \
|
|||||||
app/AppLayouts/Browser/FavoritesList.qml \
|
app/AppLayouts/Browser/FavoritesList.qml \
|
||||||
app/AppLayouts/Browser/components/BookmarkButton.qml \
|
app/AppLayouts/Browser/components/BookmarkButton.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/ActivityCenter.qml \
|
app/AppLayouts/Chat/ChatColumn/ActivityCenter.qml \
|
||||||
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterGroupRequest.qml \
|
||||||
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterMessageComponent.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterTopBar.qml \
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterTopBar.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityChannelBadge.qml \
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityChannelBadge.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/ChatComponents/AddToContactBanner.qml \
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/AddToContactBanner.qml \
|
||||||
@ -155,6 +157,7 @@ DISTFILES += \
|
|||||||
app/AppLayouts/Chat/CommunityComponents/TransferOwnershipPopup.qml \
|
app/AppLayouts/Chat/CommunityComponents/TransferOwnershipPopup.qml \
|
||||||
app/AppLayouts/Chat/ContactsColumn/AddChat.qml \
|
app/AppLayouts/Chat/ContactsColumn/AddChat.qml \
|
||||||
app/AppLayouts/Chat/ContactsColumn/ClosedEmptyView.qml \
|
app/AppLayouts/Chat/ContactsColumn/ClosedEmptyView.qml \
|
||||||
|
app/AppLayouts/Chat/components/AcceptRejectOptionsButtons.qml \
|
||||||
app/AppLayouts/Chat/components/ChooseBrowserPopup.qml \
|
app/AppLayouts/Chat/components/ChooseBrowserPopup.qml \
|
||||||
app/AppLayouts/Chat/ContactsColumn/CommunityButton.qml \
|
app/AppLayouts/Chat/ContactsColumn/CommunityButton.qml \
|
||||||
app/AppLayouts/Chat/ContactsColumn/CommunityList.qml \
|
app/AppLayouts/Chat/ContactsColumn/CommunityList.qml \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user