From 6c83413ada46fd7a7bb898ef88ee7f33d28cc859 Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Mon, 25 May 2026 13:44:02 +0000 Subject: [PATCH] appview/notifications: implement popover based notification tray Signed-off-by: oppiliappan --- appview/notifications/notifications.go | 25 +++++++++++++++++++++++++ appview/pages/pages.go | 9 +++++++++ appview/pages/templates/notifications/fragments/bell.html | 44 +++++++++++++++++++++++++++++++++++++++----- appview/pages/templates/notifications/fragments/preview.html | 19 +++++++++++++++++++ 4 file(s) changed, 92 insertion(s)(+), 5 deletion(s)(-) diff --git a/appview/notifications/notifications.go b/appview/notifications/notifications.go --- a/appview/notifications/notifications.go +++ b/appview/notifications/notifications.go @@ -38,6 +38,7 @@ r.Group(func(r chi.Router) { r.Use(middleware.AuthMiddleware(n.oauth)) r.With(middleware.Paginate).Get("/", n.notificationsPage) + r.Get("/preview", n.previewHandler) r.Post("/{id}/read", n.markRead) r.Post("/read-all", n.markAllRead) r.Delete("/{id}", n.deleteNotification) @@ -87,6 +88,30 @@ Page: page, Total: total, }) +} + +func (n *Notifications) previewHandler(w http.ResponseWriter, r *http.Request) { + l := n.logger.With("handler", "previewHandler") + user := n.oauth.GetMultiAccountUser(r) + + notifications, err := db.GetNotificationsWithEntities( + n.db, + pagination.Page{Limit: 5, Offset: 0}, + orm.FilterEq("recipient_did", user.Did), + ) + if err != nil { + l.Error("failed to get notifications", "err", err) + n.pages.Error500(w) + return + } + + err = n.pages.NotificationPreview(w, pages.NotificationPreviewParams{ + LoggedInUser: user, + Notifications: notifications, + }) + if err != nil { + l.Error("failed to render notification preview", "err", err) + } } func (n *Notifications) getUnreadCount(w http.ResponseWriter, r *http.Request) { diff --git a/appview/pages/pages.go b/appview/pages/pages.go --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -473,6 +473,15 @@ return p.executePlain("notifications/fragments/count", w, params) } +type NotificationPreviewParams struct { + LoggedInUser *oauth.MultiAccountUser + Notifications []*models.NotificationWithEntity +} + +func (p *Pages) NotificationPreview(w io.Writer, params NotificationPreviewParams) error { + return p.executePlain("notifications/fragments/preview", w, params) +} + type UserKeysSettingsParams struct { LoggedInUser *oauth.MultiAccountUser PubKeys []models.PublicKey diff --git a/appview/pages/templates/notifications/fragments/bell.html b/appview/pages/templates/notifications/fragments/bell.html --- a/appview/pages/templates/notifications/fragments/bell.html +++ b/appview/pages/templates/notifications/fragments/bell.html @@ -1,11 +1,45 @@ {{define "notifications/fragments/bell"}} -
+ #notif-bell-btn { + anchor-name: --notif-bell; + } + #notif-popup { + position-anchor: --notif-bell; + position-area: bottom span-left; + } + + {{/* mobile - lnik to notifications page */}} + - {{ i "bell" "size-5" }} - + -
+ + {{/* desktop popover button */}} + + +
+
+ {{ i "loader-circle" "size-4 animate-spin mx-auto" }} +
+
{{end}} diff --git a/appview/pages/templates/notifications/fragments/preview.html b/appview/pages/templates/notifications/fragments/preview.html new file mode 100644 --- /dev/null +++ b/appview/pages/templates/notifications/fragments/preview.html @@ -0,0 +1,19 @@ +{{ define "notifications/fragments/preview" }} + {{ if .Notifications }} +
+ {{ range .Notifications }} + {{ template "notifications/fragments/item" . }} + {{ end }} +
+ {{ else }} +
+ No notifications +
+ {{ end }} + +{{ end }} -- tangled.sh