fix(ActivityCenter): Refactor components for viewing notifications
This commit is contained in:
parent
edbd9adbb6
commit
2d02a3cb2e
|
@ -27,7 +27,7 @@ method unreadActivityCenterNotificationsCount*(self: AccessInterface): int {.bas
|
|||
method convertToItems*(self: AccessInterface, activityCenterNotifications: seq[ActivityCenterNotificationDto]): seq[Item] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getActivityCenterNotifications*(self: AccessInterface): seq[Item] {.base.} =
|
||||
method fetchActivityCenterNotifications*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method markAllActivityCenterNotificationsRead*(self: AccessInterface): string {.base.} =
|
||||
|
|
|
@ -54,6 +54,7 @@ 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
|
||||
|
@ -138,7 +139,7 @@ method convertToItems*(
|
|||
)
|
||||
)
|
||||
|
||||
method getActivityCenterNotifications*(self: Module): seq[notification_item.Item] =
|
||||
method fetchActivityCenterNotifications*(self: Module) =
|
||||
let activityCenterNotifications = self.controller.getActivityCenterNotifications()
|
||||
self.view.pushActivityCenterNotifications(self.convertToItems(activityCenterNotifications))
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ QtObject:
|
|||
self.model.updateUnreadCount(count)
|
||||
|
||||
proc loadMoreNotifications(self: View) {.slot.} =
|
||||
discard self.delegate.getActivityCenterNotifications()
|
||||
self.delegate.fetchActivityCenterNotifications()
|
||||
|
||||
proc markAllActivityCenterNotificationsRead(self: View): string {.slot.} =
|
||||
result = self.delegate.markAllActivityCenterNotificationsRead()
|
||||
|
|
|
@ -36,7 +36,7 @@ proc `$`*(self: ActivityCenterNotificationDto): string =
|
|||
read: {$self.read},
|
||||
dismissed: {$self.dismissed},
|
||||
accepted: {$self.accepted},
|
||||
message:{self.message}
|
||||
message: {self.message}
|
||||
)"""
|
||||
|
||||
proc toActivityCenterNotificationDto*(jsonObj: JsonNode): ActivityCenterNotificationDto =
|
||||
|
|
|
@ -103,8 +103,6 @@ QtObject:
|
|||
self.threadpool.start(arg)
|
||||
|
||||
proc getActivityCenterNotifications*(self: Service): seq[ActivityCenterNotificationDto] =
|
||||
if(self.cursor == ""): return
|
||||
|
||||
var cursorVal: JsonNode
|
||||
|
||||
if self.cursor == "":
|
||||
|
@ -116,7 +114,6 @@ QtObject:
|
|||
let activityCenterNotificationsTuple = parseActivityCenterNotifications(callResult.result)
|
||||
|
||||
self.cursor = activityCenterNotificationsTuple[0];
|
||||
|
||||
result = activityCenterNotificationsTuple[1]
|
||||
|
||||
proc markActivityCenterNotificationRead*(
|
||||
|
@ -155,12 +152,11 @@ QtObject:
|
|||
proc markAllActivityCenterNotificationsRead*(self: Service, initialLoad: bool = true):string =
|
||||
try:
|
||||
discard backend.markAllActivityCenterNotificationsRead()
|
||||
# This proc should accept ActivityCenterNotificationType in order to clear all notifications
|
||||
# per type, that's why we have this part here. If we add all types to notificationsType that
|
||||
# means that we need to clear all notifications for all types.
|
||||
|
||||
# Accroding specs: Clicking the "Mark all as read" MUST mark mentions and replies items as read in the selected category
|
||||
var types : seq[ActivityCenterNotificationType]
|
||||
for t in ActivityCenterNotificationType:
|
||||
types.add(t)
|
||||
types.add(ActivityCenterNotificationType.Mention)
|
||||
types.add(ActivityCenterNotificationType.Reply)
|
||||
|
||||
self.events.emit(SIGNAL_MARK_NOTIFICATIONS_AS_READ,
|
||||
MarkAsReadNotificationProperties(notificationTypes: types, isAll: true))
|
||||
|
|
|
@ -16,7 +16,10 @@ Item {
|
|||
|
||||
property bool hasMentions: false
|
||||
property bool hasReplies: false
|
||||
property bool hasContactRequests: false
|
||||
|
||||
property bool hideReadNotifications: false
|
||||
property int unreadNotificationsCount: 0
|
||||
|
||||
property int currentActivityCategory: ActivityCenterPopup.ActivityCategory.All
|
||||
|
||||
|
@ -24,6 +27,7 @@ Item {
|
|||
|
||||
signal categoryTriggered(int category)
|
||||
signal markAllReadClicked()
|
||||
signal showHideReadNotifications(bool hideReadNotifications)
|
||||
|
||||
height: 64
|
||||
|
||||
|
@ -37,15 +41,15 @@ Item {
|
|||
StatusListView {
|
||||
id: listView
|
||||
// NOTE: some entries are hidden until implimentation
|
||||
model: [ { text: qsTr("All"), category: ActivityCenterPopup.ActivityCategory.All, visible: true },
|
||||
{ text: qsTr("Admin"), category: ActivityCenterPopup.ActivityCategory.Admin, visible: false },
|
||||
{ text: qsTr("Mentions"), category: ActivityCenterPopup.ActivityCategory.Mentions, visible: true },
|
||||
{ text: qsTr("Replies"), category: ActivityCenterPopup.ActivityCategory.Replies, visible: true },
|
||||
{ text: qsTr("Contact requests"), category: ActivityCenterPopup.ActivityCategory.ContactRequests, visible: true },
|
||||
{ text: qsTr("Identity verification"), category: ActivityCenterPopup.ActivityCategory.IdentityVerification, visible: false },
|
||||
{ text: qsTr("Transactions"), category: ActivityCenterPopup.ActivityCategory.Transactions, visible: false },
|
||||
{ text: qsTr("Membership"), category: ActivityCenterPopup.ActivityCategory.Membership, visible: false },
|
||||
{ text: qsTr("System"), category: ActivityCenterPopup.ActivityCategory.System, visible: false } ]
|
||||
model: [ { text: qsTr("All"), category: ActivityCenterPopup.ActivityCategory.All, visible: true, enabled: true },
|
||||
{ text: qsTr("Admin"), category: ActivityCenterPopup.ActivityCategory.Admin, visible: false, enabled: true },
|
||||
{ text: qsTr("Mentions"), category: ActivityCenterPopup.ActivityCategory.Mentions, visible: true, enabled: root.hasMentions },
|
||||
{ text: qsTr("Replies"), category: ActivityCenterPopup.ActivityCategory.Replies, visible: true, enabled: root.hasReplies },
|
||||
{ text: qsTr("Contact requests"), category: ActivityCenterPopup.ActivityCategory.ContactRequests, visible: true, enabled: root.hasContactRequests },
|
||||
{ text: qsTr("Identity verification"), category: ActivityCenterPopup.ActivityCategory.IdentityVerification, visible: false, enabled: true },
|
||||
{ text: qsTr("Transactions"), category: ActivityCenterPopup.ActivityCategory.Transactions, visible: false, enabled: true },
|
||||
{ text: qsTr("Membership"), category: ActivityCenterPopup.ActivityCategory.Membership, visible: false, enabled: true },
|
||||
{ text: qsTr("System"), category: ActivityCenterPopup.ActivityCategory.System, visible: false, enabled: true } ]
|
||||
orientation: StatusListView.Horizontal
|
||||
spacing: 0
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
|
@ -53,6 +57,7 @@ Item {
|
|||
Layout.fillHeight: true
|
||||
|
||||
delegate: StatusFlatButton {
|
||||
enabled: modelData.enabled
|
||||
visible: modelData.visible
|
||||
width: visible ? implicitWidth : 0
|
||||
text: modelData.text
|
||||
|
@ -61,13 +66,15 @@ Item {
|
|||
size: StatusBaseButton.Size.Small
|
||||
highlighted: modelData.category == root.currentActivityCategory
|
||||
onClicked: root.categoryTriggered(modelData.category)
|
||||
onEnabledChanged: if (!enabled && highlighted) root.categoryTriggered(ActivityCenterPopup.ActivityCategory.All)
|
||||
}
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: markAllReadBtn
|
||||
enabled: root.unreadNotificationsCount > 0
|
||||
icon.name: "double-checkmark"
|
||||
onClicked: markAllReadClicked()
|
||||
onClicked: root.markAllReadClicked()
|
||||
|
||||
StatusToolTip {
|
||||
visible: markAllReadBtn.hovered
|
||||
|
@ -77,12 +84,12 @@ Item {
|
|||
|
||||
StatusFlatRoundButton {
|
||||
id: hideReadNotificationsBtn
|
||||
icon.name: "hide"
|
||||
onClicked: hideReadNotifications = !hideReadNotifications
|
||||
icon.name: root.hideReadNotifications ? "hide" : "show"
|
||||
onClicked: root.showHideReadNotifications(!root.hideReadNotifications)
|
||||
|
||||
StatusToolTip {
|
||||
visible: markAllReadBtn.hovered
|
||||
text: hideReadNotifications ? qsTr("Show read notifications") : qsTr("Hide read notifications")
|
||||
visible: hideReadNotificationsBtn.hovered
|
||||
text: root.hideReadNotifications ? qsTr("Show read notifications") : qsTr("Hide read notifications")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import "../panels"
|
|||
Popup {
|
||||
id: root
|
||||
|
||||
// NOTE: temporary enum until we have different categories on UI and status-go sides
|
||||
enum ActivityCategory {
|
||||
All,
|
||||
Admin,
|
||||
|
@ -32,11 +33,11 @@ Popup {
|
|||
System
|
||||
}
|
||||
property int currentActivityCategory: ActivityCenterPopup.ActivityCategory.All
|
||||
property bool hasMentions: false
|
||||
property bool hasReplies: false
|
||||
// property bool hasContactRequests: false
|
||||
|
||||
property int mentionsCount: 0
|
||||
property int repliesCount: 0
|
||||
property int contactRequestsCount: 0
|
||||
property bool hideReadNotifications: false
|
||||
|
||||
property var store
|
||||
property var chatSectionModule
|
||||
property var messageContextMenu: MessageContextMenuView {
|
||||
|
@ -62,7 +63,6 @@ Popup {
|
|||
}
|
||||
|
||||
onOpened: {
|
||||
root.store.loadMoreNotifications()
|
||||
Global.popupOpened = true
|
||||
}
|
||||
onClosed: {
|
||||
|
@ -99,16 +99,15 @@ Popup {
|
|||
ActivityCenterPopupTopBarPanel {
|
||||
id: activityCenterTopBar
|
||||
width: parent.width
|
||||
hasReplies: root.hasReplies
|
||||
hasMentions: root.hasMentions
|
||||
unreadNotificationsCount: root.unreadNotificationsCount
|
||||
hasReplies: root.repliesCount > 0
|
||||
hasMentions: root.mentionsCount > 0
|
||||
hasContactRequests: root.contactRequestsCount > 0
|
||||
hideReadNotifications: root.hideReadNotifications
|
||||
currentActivityCategory: root.currentActivityCategory
|
||||
onCategoryTriggered: {
|
||||
root.currentActivityCategory = category;
|
||||
}
|
||||
onMarkAllReadClicked: {
|
||||
errorText = root.store.activityCenterModuleInst.markAllActivityCenterNotificationsRead()
|
||||
}
|
||||
onCategoryTriggered: root.currentActivityCategory = category
|
||||
onMarkAllReadClicked: errorText = root.store.activityCenterModuleInst.markAllActivityCenterNotificationsRead()
|
||||
onShowHideReadNotifications: root.hideReadNotifications = hideReadNotifications
|
||||
}
|
||||
|
||||
StatusListView {
|
||||
|
@ -122,7 +121,7 @@ Popup {
|
|||
model: SortFilterProxyModel {
|
||||
sourceModel: root.store.activityCenterList
|
||||
|
||||
filters: ExpressionFilter { expression: filterActivityCategories(model.notificationType) }
|
||||
filters: ExpressionFilter { expression: filterActivityCategories(model.notificationType) && !(root.hideReadNotifications && model.read) }
|
||||
}
|
||||
|
||||
delegate: DelegateChooser {
|
||||
|
@ -130,93 +129,38 @@ Popup {
|
|||
|
||||
DelegateChoice {
|
||||
roleValue: Constants.activityCenterNotificationTypeMention
|
||||
ActivityNotificationMention { store: root.store; notification: model }
|
||||
|
||||
ActivityNotificationMention {
|
||||
store: root.store
|
||||
notification: model
|
||||
Component.onCompleted: root.mentionsCount++
|
||||
Component.onDestruction: root.mentionsCount--
|
||||
}
|
||||
}
|
||||
DelegateChoice {
|
||||
roleValue: Constants.activityCenterNotificationTypeReply
|
||||
ActivityNotificationReply { store: root.store; notification: model }
|
||||
|
||||
ActivityNotificationReply {
|
||||
store: root.store
|
||||
notification: model
|
||||
Component.onCompleted: root.repliesCount++
|
||||
Component.onDestruction: root.repliesCount--
|
||||
}
|
||||
}
|
||||
DelegateChoice {
|
||||
roleValue: Constants.activityCenterNotificationTypeContactRequest
|
||||
ActivityNotificationContactRequest { store: root.store; notification: model }
|
||||
|
||||
ActivityNotificationContactRequest {
|
||||
store: root.store
|
||||
notification: model
|
||||
Component.onCompleted: root.contactRequestsCount++
|
||||
Component.onDestruction: root.contactRequestsCount--
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // TODO: replace with StatusListView
|
||||
// StatusScrollView {
|
||||
// id: scrollView
|
||||
// anchors.left: parent.left
|
||||
// anchors.right: parent.right
|
||||
// anchors.top: activityCenterTopBar.bottom
|
||||
// anchors.topMargin: 13
|
||||
// anchors.bottom: parent.bottom
|
||||
// anchors.bottomMargin: Style.current.smallPadding
|
||||
// width: parent.width
|
||||
|
||||
// ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
|
||||
// Column {
|
||||
// id: notificationsContainer
|
||||
// width: scrollView.availableWidth
|
||||
// spacing: 0
|
||||
|
||||
// Repeater {
|
||||
// model: notifDelegateList
|
||||
// }
|
||||
|
||||
// DelegateModelGeneralized {
|
||||
// id: notifDelegateList
|
||||
|
||||
// lessThan: [
|
||||
// function(left, right) { return left.timestamp > right.timestamp }
|
||||
// ]
|
||||
|
||||
// model: root.store.activityCenterList
|
||||
|
||||
// delegate: Item {
|
||||
// id: notificationDelegate
|
||||
// width: parent.availableWidth
|
||||
// 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 {
|
||||
// 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;
|
||||
// }
|
||||
// readonly property string previousNotificationTimestamp: notificationDelegate.idx === 0 ? "" :
|
||||
// root.store.activityCenterList.getNotificationData(previousNotificationIndex, "timestamp")
|
||||
// onPreviousNotificationTimestampChanged: {
|
||||
// root.store.messageStore.prevMsgTimestamp = previousNotificationTimestamp;
|
||||
// }
|
||||
|
||||
// id: notifLoader
|
||||
// anchors.top: parent.top
|
||||
// active: !!sourceComponent
|
||||
|
@ -274,19 +218,3 @@ Popup {
|
|||
// }
|
||||
// }
|
||||
|
||||
// Item {
|
||||
// visible: root.store.activityCenterModuleInst.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: root.store.activityCenterModuleInst.loadMoreNotifications()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -21,10 +21,6 @@ Item {
|
|||
|
||||
StatusFlatRoundButton {
|
||||
id: markReadBtn
|
||||
width: 32
|
||||
height: 32
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
|
|
|
@ -7,43 +7,10 @@ import StatusQ.Components 0.1
|
|||
|
||||
import shared 1.0
|
||||
import utils 1.0
|
||||
import shared.panels.chat 1.0
|
||||
|
||||
ActivityNotificationBase {
|
||||
ActivityNotificationMessage {
|
||||
id: root
|
||||
|
||||
markReadBtnVisible: false
|
||||
height: 60
|
||||
|
||||
StatusSmartIdenticon {
|
||||
id: identicon
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
name: notification.author
|
||||
asset.color: Theme.palette.miscColor5
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.top: parent.top
|
||||
anchors.left: identicon.right
|
||||
|
||||
StatusBaseText {
|
||||
text: notification.name
|
||||
font.pixelSize: 15
|
||||
color: Style.current.primary
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: Utils.getElidedPk(notification.author) + " \u2022"
|
||||
font.pixelSize: 12
|
||||
color: Style.current.secondaryText
|
||||
}
|
||||
|
||||
ChatTimePanel {
|
||||
font.pixelSize: 12
|
||||
color: Style.current.secondaryText
|
||||
timestamp: notification.timestamp
|
||||
}
|
||||
}
|
||||
// TODO: mark as read ignores notification type
|
||||
// markReadBtnVisible: false
|
||||
}
|
|
@ -9,7 +9,7 @@ import shared 1.0
|
|||
import utils 1.0
|
||||
import shared.panels.chat 1.0
|
||||
|
||||
ActivityNotificationBase {
|
||||
ActivityNotificationMessage {
|
||||
id: root
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
import shared 1.0
|
||||
import utils 1.0
|
||||
import shared.views.chat 1.0
|
||||
|
||||
ActivityNotificationBase {
|
||||
id: root
|
||||
|
||||
signal activityCenterClose()
|
||||
|
||||
height: Math.max(60, notificationMessage.height)
|
||||
|
||||
MessageView {
|
||||
id: notificationMessage
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
z: -1
|
||||
rootStore: root.store
|
||||
messageStore: root.store.messageStore
|
||||
messageId: notification.id
|
||||
senderDisplayName: notification.message.senderDisplayName
|
||||
messageText: notification.message.messageText
|
||||
responseToMessageWithId: notification.message.responseToMessageWithId
|
||||
senderId: notification.message.senderId
|
||||
senderLocalName: notification.message.senderLocalName
|
||||
senderIcon: notification.message.senderIcon
|
||||
amISender: notification.message.amISender
|
||||
messageImage: notification.message.messageImage
|
||||
messageTimestamp: notification.timestamp
|
||||
messageOutgoingStatus: notification.message.outgoingStatus
|
||||
messageContentType: notification.message.contentType
|
||||
senderTrustStatus: notification.message.senderTrustStatus
|
||||
activityCenterMessage: true
|
||||
activityCenterMessageRead: false
|
||||
onImageClicked: Global.openImagePopup(image, root.messageContextMenu)
|
||||
scrollToBottom: null
|
||||
messageClickHandler: (sender,
|
||||
point,
|
||||
isProfileClick,
|
||||
isSticker = false,
|
||||
isImage = false,
|
||||
image = null,
|
||||
isEmoji = false,
|
||||
ideEmojiPicker = false,
|
||||
isReply = false,
|
||||
isRightClickOnImage = false,
|
||||
imageSource = "") => {
|
||||
if (isProfileClick) {
|
||||
return Global.openProfilePopup(notification.message.senderId)
|
||||
}
|
||||
|
||||
activityCenterClose()
|
||||
root.store.activityCenterModuleInst.switchTo(notification.sectionId, notification.chatId, notification.id)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ import shared 1.0
|
|||
import utils 1.0
|
||||
import shared.panels.chat 1.0
|
||||
|
||||
ActivityNotificationBase {
|
||||
ActivityNotificationMessage {
|
||||
id: root
|
||||
|
||||
}
|
Loading…
Reference in New Issue