Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ActivityCenter): Fetch notifications on scroll to bottom #12712

Merged
merged 1 commit into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions src/app/modules/main/activity_center/controller.nim
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ proc init*(self: Controller) =
self.events.on(activity_center_service.SIGNAL_ACTIVITY_CENTER_NOTIFICATIONS_LOADED) do(e: Args):
let args = ActivityCenterNotificationsArgs(e)
self.delegate.addActivityCenterNotifications(args.activityCenterNotifications)
self.updateActivityGroupCounters()

self.events.on(activity_center_service.SIGNAL_MARK_NOTIFICATIONS_AS_ACCEPTED) do(e: Args):
var evArgs = MarkAsAcceptedNotificationProperties(e)
Expand All @@ -66,8 +67,8 @@ proc init*(self: Controller) =
self.events.on(activity_center_service.SIGNAL_MARK_NOTIFICATIONS_AS_READ) do(e: Args):
var evArgs = MarkAsReadNotificationProperties(e)
if (evArgs.isAll):
self.delegate.markAllActivityCenterNotificationsReadDone()
return
self.delegate.markAllActivityCenterNotificationsReadDone()
return
if (evArgs.notificationIds.len > 0):
self.delegate.markActivityCenterNotificationReadDone(evArgs.notificationIds)

Expand All @@ -87,48 +88,51 @@ proc init*(self: Controller) =
self.delegate.removeActivityCenterNotifications(evArgs.notificationIds)

proc hasMoreToShow*(self: Controller): bool =
return self.activityCenterService.hasMoreToShow()
return self.activityCenterService.hasMoreToShow()

proc unreadActivityCenterNotificationsCount*(self: Controller): int =
return self.activityCenterService.getUnreadActivityCenterNotificationsCount()
return self.activityCenterService.getUnreadActivityCenterNotificationsCount()

proc hasUnseenActivityCenterNotifications*(self: Controller): bool =
return self.activityCenterService.getHasUnseenActivityCenterNotifications()
return self.activityCenterService.getHasUnseenActivityCenterNotifications()

proc getContactDetails*(self: Controller, contactId: string): ContactDetails =
return self.contactsService.getContactDetails(contactId)
return self.contactsService.getContactDetails(contactId)

proc getCommunityById*(self: Controller, communityId: string): CommunityDto =
return self.communityService.getCommunityById(communityId)

proc getActivityCenterNotifications*(self: Controller): seq[ActivityCenterNotificationDto] =
return self.activityCenterService.getActivityCenterNotifications()
return self.activityCenterService.getActivityCenterNotifications()

proc asyncActivityNotificationLoad*(self: Controller) =
self.activityCenterService.asyncActivityNotificationLoad()

proc markAllActivityCenterNotificationsRead*(self: Controller): string =
return self.activityCenterService.markAllActivityCenterNotificationsRead()
return self.activityCenterService.markAllActivityCenterNotificationsRead()

proc markActivityCenterNotificationRead*(
self: Controller,
notificationId: string,
markAsReadProps: MarkAsReadNotificationProperties
): string =
return self.activityCenterService.markActivityCenterNotificationRead(notificationId, markAsReadProps)
return self.activityCenterService.markActivityCenterNotificationRead(notificationId, markAsReadProps)

proc markActivityCenterNotificationUnread*(
self: Controller,
notificationId: string,
markAsUnreadProps: MarkAsUnreadNotificationProperties
): string =
return self.activityCenterService.markActivityCenterNotificationUnread(notificationId, markAsUnreadProps)
return self.activityCenterService.markActivityCenterNotificationUnread(notificationId, markAsUnreadProps)

proc markAsSeenActivityCenterNotifications*(self: Controller) =
self.activityCenterService.markAsSeenActivityCenterNotifications()
self.activityCenterService.markAsSeenActivityCenterNotifications()

proc acceptActivityCenterNotifications*(self: Controller, notificationIds: seq[string]): string =
return self.activityCenterService.acceptActivityCenterNotifications(notificationIds)
return self.activityCenterService.acceptActivityCenterNotifications(notificationIds)

proc dismissActivityCenterNotifications*(self: Controller, notificationIds: seq[string]): string =
return self.activityCenterService.dismissActivityCenterNotifications(notificationIds)
return self.activityCenterService.dismissActivityCenterNotifications(notificationIds)

proc replacePubKeysWithDisplayNames*(self: Controller, message: string): string =
return self.messageService.replacePubKeysWithDisplayNames(message)
Expand Down
47 changes: 30 additions & 17 deletions src/app/modules/main/activity_center/model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -156,27 +156,40 @@ QtObject:
self.activityCenterNotifications = activityCenterNotifications
self.endResetModel()

proc addActivityNotificationItemToList*(self: Model, activityCenterNotification: Item, addToCount: bool = true) =
let modelIndex = newQModelIndex()
defer: modelIndex.delete
self.beginInsertRows(modelIndex, 0, 0)
self.activityCenterNotifications.insert(activityCenterNotification, 0)
proc updateActivityCenterNotification*(self: Model, ind: int, newNotification: Item) =
self.activityCenterNotifications[ind] = newNotification
let index = self.createIndex(ind, 0, nil)
defer: index.delete
self.dataChanged(index, index)

proc upsertActivityCenterNotification*(self: Model, newNotification: Item) =
for i, notification in self.activityCenterNotifications:
if newNotification.id == notification.id:
self.updateActivityCenterNotification(i, newNotification)
return

let parentModelIndex = newQModelIndex()
defer: parentModelIndex.delete

var indexToInsert = self.activityCenterNotifications.len
for i, notification in self.activityCenterNotifications:
if newNotification.timestamp > notification.timestamp:
indexToInsert = i
break

self.beginInsertRows(parentModelIndex, indexToInsert, indexToInsert)
self.activityCenterNotifications.insert(newNotification, indexToInsert)
self.endInsertRows()

if self.activityCenterNotifications.len > 1:
let topLeft = self.createIndex(0, 0, nil)
let bottomRight = self.createIndex(1, 0, nil)
defer: topLeft.delete
defer: bottomRight.delete
self.dataChanged(topLeft, bottomRight, @[NotifRoles.Timestamp.int, NotifRoles.PreviousTimestamp.int])
let indexToUpdate = indexToInsert - 2
if indexToUpdate >= 0 and indexToUpdate < self.activityCenterNotifications.len:
let index = self.createIndex(indexToUpdate, 0, nil)
defer: index.delete
self.dataChanged(index, index, @[NotifRoles.PreviousTimestamp.int])

proc addActivityNotificationItemsToList*(self: Model, activityCenterNotifications: seq[Item]) =
proc upsertActivityCenterNotifications*(self: Model, activityCenterNotifications: seq[Item]) =
if self.activityCenterNotifications.len == 0:
self.setNewData(activityCenterNotifications)
else:
for activityCenterNotification in activityCenterNotifications:
for notif in self.activityCenterNotifications:
if activityCenterNotification.id == notif.id:
self.removeNotifications(@[notif.id])
break
self.addActivityNotificationItemToList(activityCenterNotification, false)
self.upsertActivityCenterNotification(activityCenterNotification)
3 changes: 1 addition & 2 deletions src/app/modules/main/activity_center/module.nim
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,7 @@ method convertToItems*(
)

method fetchActivityCenterNotifications*(self: Module) =
let activityCenterNotifications = self.controller.getActivityCenterNotifications()
self.view.addActivityCenterNotifications(self.convertToItems(activityCenterNotifications))
self.controller.asyncActivityNotificationLoad()

method markAllActivityCenterNotificationsRead*(self: Module): string =
self.controller.markAllActivityCenterNotificationsRead()
Expand Down
4 changes: 2 additions & 2 deletions src/app/modules/main/activity_center/view.nim
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ QtObject:
read = hasUnseenActivityCenterNotifications
notify = hasUnseenActivityCenterNotificationsChanged

proc loadMoreNotifications(self: View) {.slot.} =
proc fetchActivityCenterNotifications(self: View) {.slot.} =
self.delegate.fetchActivityCenterNotifications()

proc markAllActivityCenterNotificationsRead(self: View): string {.slot.} =
Expand Down Expand Up @@ -136,7 +136,7 @@ QtObject:
self.model.removeNotifications(notificationIds)

proc addActivityCenterNotifications*(self: View, activityCenterNotifications: seq[Item]) =
self.model.addActivityNotificationItemsToList(activityCenterNotifications)
self.model.upsertActivityCenterNotifications(activityCenterNotifications)

proc resetActivityCenterNotifications*(self: View, activityCenterNotifications: seq[Item]) =
self.model.setNewData(activityCenterNotifications)
Expand Down
13 changes: 13 additions & 0 deletions ui/app/mainui/activitycenter/popups/ActivityCenterPopup.qml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ Popup {
modal: true
parent: Overlay.overlay

QtObject {
id: d

readonly property var loadMoreNotificationsIfScrollBelowThreshold: Backpressure.oneInTimeQueued(root, 100, function() {
if (listView.contentY >= listView.contentHeight - listView.height - 1) {
root.activityCenterStore.fetchActivityCenterNotifications()
}
})
}

Overlay.modal: MouseArea { // eat every event behind the popup
hoverEnabled: true
onPressed: (event) => {
Expand Down Expand Up @@ -79,6 +89,7 @@ Popup {

StatusListView {
id: listView

anchors.left: parent.left
anchors.right: parent.right
anchors.top: activityCenterTopBar.bottom
Expand All @@ -88,6 +99,8 @@ Popup {

model: root.activityCenterStore.activityCenterNotifications

onContentYChanged: d.loadMoreNotificationsIfScrollBelowThreshold()

delegate: Loader {
width: listView.availableWidth

Expand Down
4 changes: 4 additions & 0 deletions ui/app/mainui/activitycenter/stores/ActivityCenterStore.qml
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,8 @@ QtObject {
function setActivityCenterReadType(readType) {
root.activityCenterModuleInst.setActivityCenterReadType(readType)
}

function fetchActivityCenterNotifications() {
root.activityCenterModuleInst.fetchActivityCenterNotifications()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ ActivityNotificationMessage {
}

ctaComponent: MembershipCta {
membershipStatus: notification && notification.membershipStatus ? notification.membershipStatus : ActivityNotification.MembershipStatus.None
membershipStatus: notification && notification.membershipStatus ? notification.membershipStatus : ActivityCenterStore.ActivityCenterMembershipStatus.None
onAcceptRequestToJoinCommunity: root.store.acceptRequestToJoinCommunity(notification.id, notification.communityId)
onDeclineRequestToJoinCommunity: root.store.declineRequestToJoinCommunity(notification.id, notification.communityId)
//TODO: Get backend value. If the membersip is in acceptedPending or declinedPending state, another user can't accept or decline the request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import utils 1.0
ActivityNotificationBase {
id: root

readonly property bool isOutgoingMessage: notification && notification.message && notification.message.amISender
readonly property bool isOutgoingMessage: notification && notification.message && notification.message.amISender || false
caybro marked this conversation as resolved.
Show resolved Hide resolved
readonly property string contactId: notification ? isOutgoingMessage ? notification.chatId : notification.author : ""
readonly property string contactName: contactDetails ? ProfileUtils.displayName(contactDetails.localNickname, contactDetails.name,
contactDetails.displayName, contactDetails.alias) : ""
Expand Down