297 lines
13 KiB
QML
297 lines
13 KiB
QML
import QtQuick 2.13
|
|
import QtQuick.Controls 2.13
|
|
import QtQml.Models 2.13
|
|
import "../../../../shared"
|
|
import "../../../../shared/status"
|
|
import "../../../../imports"
|
|
import "./ChatComponents"
|
|
import "../components"
|
|
import "./MessageComponents"
|
|
|
|
Popup {
|
|
enum Filter {
|
|
All,
|
|
Mentions,
|
|
Replies,
|
|
ContactRequests
|
|
}
|
|
property int currentFilter: ActivityCenter.Filter.All
|
|
property bool hasMentions: false
|
|
property bool hasReplies: false
|
|
property bool hasContactRequests: contactList.count > 0
|
|
|
|
property bool hideReadNotifications: false
|
|
|
|
id: activityCenter
|
|
modal: true
|
|
|
|
Overlay.modal: Rectangle {
|
|
color: Qt.rgba(0, 0, 0, 0.4)
|
|
}
|
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
|
parent: Overlay.overlay
|
|
width: 560
|
|
height: chatColumnLayout.height - (chatTopBarContent.height * 2) // TODO get screen size
|
|
background: Rectangle {
|
|
color: Style.current.background
|
|
radius: Style.current.radius
|
|
}
|
|
y: chatTopBarContent.height
|
|
x: applicationWindow.width - activityCenter.width - Style.current.halfPadding
|
|
onOpened: {
|
|
popupOpened = true
|
|
}
|
|
onClosed: {
|
|
popupOpened = false
|
|
}
|
|
padding: 0
|
|
|
|
ActivityCenterTopBar {
|
|
id: activityCenterTopBar
|
|
}
|
|
|
|
ScrollView {
|
|
id: scrollView
|
|
anchors.top: activityCenterTopBar.bottom
|
|
anchors.topMargin: 13
|
|
anchors.bottom: parent.bottom
|
|
anchors.bottomMargin: Style.current.smallPadding
|
|
width: parent.width
|
|
clip: true
|
|
|
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
|
|
Column {
|
|
id: notificationsContainer
|
|
width: parent.width
|
|
spacing: 0
|
|
|
|
property Component profilePopupComponent: ProfilePopup {
|
|
id: profilePopup
|
|
onClosed: destroy()
|
|
}
|
|
|
|
// TODO remove this once it is handled by the activity center
|
|
Repeater {
|
|
id: contactList
|
|
model: profileModel.contacts.contactRequests
|
|
|
|
delegate: ContactRequest {
|
|
visible: !hideReadNotifications &&
|
|
(activityCenter.currentFilter === ActivityCenter.Filter.All || activityCenter.currentFilter === ActivityCenter.Filter.ContactRequests)
|
|
name: Utils.removeStatusEns(model.name)
|
|
address: model.address
|
|
localNickname: model.localNickname
|
|
identicon: model.thumbnailImage || model.identicon
|
|
// TODO set to transparent bg if the notif is read
|
|
color: Utils.setColorAlpha(Style.current.blue, 0.1)
|
|
radius: 0
|
|
profileClick: function (showFooter, userName, fromAuthor, identicon, textParam, nickName) {
|
|
var popup = profilePopupComponent.createObject(contactList);
|
|
popup.openPopup(showFooter, userName, fromAuthor, identicon, textParam, nickName);
|
|
}
|
|
onBlockContactActionTriggered: {
|
|
blockContactConfirmationDialog.contactName = name
|
|
blockContactConfirmationDialog.contactAddress = address
|
|
blockContactConfirmationDialog.open()
|
|
}
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
model: notifDelegateList
|
|
}
|
|
|
|
DelegateModelGeneralized {
|
|
id: notifDelegateList
|
|
lessThan: [
|
|
function(left, right) { return left.timestamp > right.timestamp }
|
|
]
|
|
|
|
model: chatsModel.activityNotificationList
|
|
|
|
delegate: Item {
|
|
id: notificationDelegate
|
|
width: parent.width
|
|
height: notifLoader.active ? childrenRect.height : 0
|
|
|
|
property int idx: DelegateModel.itemsIndex
|
|
|
|
Component.onCompleted: {
|
|
switch (model.notificationType) {
|
|
case Constants.activityCenterNotificationTypeMention:
|
|
if (!hasMentions) {
|
|
hasMentions = true
|
|
}
|
|
break
|
|
|
|
case Constants.activityCenterNotificationTypeReply:
|
|
if (!hasReplies) {
|
|
hasReplies = true
|
|
}
|
|
break
|
|
|
|
}
|
|
}
|
|
|
|
Loader {
|
|
id: notifLoader
|
|
anchors.top: parent.top
|
|
active: !!sourceComponent
|
|
width: parent.width
|
|
height: active && item.visible ? item.height : 0
|
|
sourceComponent: {
|
|
switch (model.notificationType) {
|
|
case Constants.activityCenterNotificationTypeMention:return messageNotificationComponent
|
|
case Constants.activityCenterNotificationTypeReply: return messageNotificationComponent
|
|
default: return null
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: messageNotificationComponent
|
|
|
|
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: messageNotificationContent.height
|
|
|
|
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: {
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
visible: chatsModel.activityNotificationList.hasMoreToShow
|
|
width: parent.width
|
|
height: visible ? showMoreBtn.height + showMoreBtn.anchors.topMargin : 0
|
|
StatusButton {
|
|
id: showMoreBtn
|
|
text: qsTr("Show more")
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
anchors.top: parent.top
|
|
anchors.topMargin: Style.current.smallPadding
|
|
onClicked: chatsModel.activityNotificationList.loadMoreNotifications()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|