···
+
"github.com/go-chi/chi/v5"
+
"tangled.org/core/appview/db"
+
"tangled.org/core/appview/middleware"
+
"tangled.org/core/appview/oauth"
+
"tangled.org/core/appview/pages"
+
type Notifications struct {
+
func New(database *db.DB, oauthHandler *oauth.OAuth, pagesHandler *pages.Pages) *Notifications {
+
func (n *Notifications) Router(mw *middleware.Middleware) http.Handler {
+
r.Use(middleware.AuthMiddleware(n.oauth))
+
r.Get("/", n.notificationsPage)
+
r.Get("/count", n.getUnreadCount)
+
r.Post("/{id}/read", n.markRead)
+
r.Post("/read-all", n.markAllRead)
+
r.Delete("/{id}", n.deleteNotification)
+
func (n *Notifications) notificationsPage(w http.ResponseWriter, r *http.Request) {
+
userDid := n.oauth.GetDid(r)
+
limitStr := r.URL.Query().Get("limit")
+
offsetStr := r.URL.Query().Get("offset")
+
if l, err := strconv.Atoi(limitStr); err == nil && l > 0 && l <= 100 {
+
if o, err := strconv.Atoi(offsetStr); err == nil && o >= 0 {
+
notifications, err := n.db.GetNotificationsWithEntities(r.Context(), userDid, limit+1, offset)
+
log.Println("failed to get notifications:", err)
+
hasMore := len(notifications) > limit
+
notifications = notifications[:limit]
+
err = n.db.MarkAllNotificationsRead(r.Context(), userDid)
+
log.Println("failed to mark notifications as read:", err)
+
user := n.oauth.GetUser(r)
+
http.Error(w, "Failed to get user", http.StatusInternalServerError)
+
params := pages.NotificationsParams{
+
Notifications: notifications,
+
UnreadCount: unreadCount,
+
NextOffset: offset + limit,
+
err = n.pages.Notifications(w, params)
+
log.Println("failed to load notifs:", err)
+
func (n *Notifications) getUnreadCount(w http.ResponseWriter, r *http.Request) {
+
userDid := n.oauth.GetDid(r)
+
count, err := n.db.GetUnreadNotificationCount(r.Context(), userDid)
+
http.Error(w, "Failed to get unread count", http.StatusInternalServerError)
+
params := pages.NotificationCountParams{
+
err = n.pages.NotificationCount(w, params)
+
http.Error(w, "Failed to render count", http.StatusInternalServerError)
+
func (n *Notifications) markRead(w http.ResponseWriter, r *http.Request) {
+
userDid := n.oauth.GetDid(r)
+
idStr := chi.URLParam(r, "id")
+
notificationID, err := strconv.ParseInt(idStr, 10, 64)
+
http.Error(w, "Invalid notification ID", http.StatusBadRequest)
+
err = n.db.MarkNotificationRead(r.Context(), notificationID, userDid)
+
http.Error(w, "Failed to mark notification as read", http.StatusInternalServerError)
+
w.WriteHeader(http.StatusNoContent)
+
func (n *Notifications) markAllRead(w http.ResponseWriter, r *http.Request) {
+
userDid := n.oauth.GetDid(r)
+
err := n.db.MarkAllNotificationsRead(r.Context(), userDid)
+
http.Error(w, "Failed to mark all notifications as read", http.StatusInternalServerError)
+
http.Redirect(w, r, "/notifications", http.StatusSeeOther)
+
func (n *Notifications) deleteNotification(w http.ResponseWriter, r *http.Request) {
+
userDid := n.oauth.GetDid(r)
+
idStr := chi.URLParam(r, "id")
+
notificationID, err := strconv.ParseInt(idStr, 10, 64)
+
http.Error(w, "Invalid notification ID", http.StatusBadRequest)
+
err = n.db.DeleteNotification(r.Context(), notificationID, userDid)
+
http.Error(w, "Failed to delete notification", http.StatusInternalServerError)
+
w.WriteHeader(http.StatusOK)