forked from tangled.org/core
this repo has no description
at master 4.0 kB view raw
1package notifications 2 3import ( 4 "fmt" 5 "log" 6 "net/http" 7 "strconv" 8 9 "github.com/go-chi/chi/v5" 10 "tangled.org/core/appview/db" 11 "tangled.org/core/appview/middleware" 12 "tangled.org/core/appview/oauth" 13 "tangled.org/core/appview/pages" 14 "tangled.org/core/appview/pagination" 15) 16 17type Notifications struct { 18 db *db.DB 19 oauth *oauth.OAuth 20 pages *pages.Pages 21} 22 23func New(database *db.DB, oauthHandler *oauth.OAuth, pagesHandler *pages.Pages) *Notifications { 24 return &Notifications{ 25 db: database, 26 oauth: oauthHandler, 27 pages: pagesHandler, 28 } 29} 30 31func (n *Notifications) Router(mw *middleware.Middleware) http.Handler { 32 r := chi.NewRouter() 33 34 r.Use(middleware.AuthMiddleware(n.oauth)) 35 36 r.With(middleware.Paginate).Get("/", n.notificationsPage) 37 38 r.Get("/count", n.getUnreadCount) 39 r.Post("/{id}/read", n.markRead) 40 r.Post("/read-all", n.markAllRead) 41 r.Delete("/{id}", n.deleteNotification) 42 43 return r 44} 45 46func (n *Notifications) notificationsPage(w http.ResponseWriter, r *http.Request) { 47 userDid := n.oauth.GetDid(r) 48 49 page, ok := r.Context().Value("page").(pagination.Page) 50 if !ok { 51 log.Println("failed to get page") 52 page = pagination.FirstPage() 53 } 54 55 total, err := db.CountNotifications( 56 n.db, 57 db.FilterEq("recipient_did", userDid), 58 ) 59 if err != nil { 60 log.Println("failed to get total notifications:", err) 61 n.pages.Error500(w) 62 return 63 } 64 65 notifications, err := db.GetNotificationsWithEntities( 66 n.db, 67 page, 68 db.FilterEq("recipient_did", userDid), 69 ) 70 if err != nil { 71 log.Println("failed to get notifications:", err) 72 n.pages.Error500(w) 73 return 74 } 75 76 err = n.db.MarkAllNotificationsRead(r.Context(), userDid) 77 if err != nil { 78 log.Println("failed to mark notifications as read:", err) 79 } 80 81 unreadCount := 0 82 83 user := n.oauth.GetUser(r) 84 if user == nil { 85 http.Error(w, "Failed to get user", http.StatusInternalServerError) 86 return 87 } 88 89 fmt.Println(n.pages.Notifications(w, pages.NotificationsParams{ 90 LoggedInUser: user, 91 Notifications: notifications, 92 UnreadCount: unreadCount, 93 Page: page, 94 Total: total, 95 })) 96} 97 98func (n *Notifications) getUnreadCount(w http.ResponseWriter, r *http.Request) { 99 user := n.oauth.GetUser(r) 100 count, err := db.CountNotifications( 101 n.db, 102 db.FilterEq("recipient_did", user.Did), 103 db.FilterEq("read", 0), 104 ) 105 if err != nil { 106 http.Error(w, "Failed to get unread count", http.StatusInternalServerError) 107 return 108 } 109 110 params := pages.NotificationCountParams{ 111 Count: count, 112 } 113 err = n.pages.NotificationCount(w, params) 114 if err != nil { 115 http.Error(w, "Failed to render count", http.StatusInternalServerError) 116 return 117 } 118} 119 120func (n *Notifications) markRead(w http.ResponseWriter, r *http.Request) { 121 userDid := n.oauth.GetDid(r) 122 123 idStr := chi.URLParam(r, "id") 124 notificationID, err := strconv.ParseInt(idStr, 10, 64) 125 if err != nil { 126 http.Error(w, "Invalid notification ID", http.StatusBadRequest) 127 return 128 } 129 130 err = n.db.MarkNotificationRead(r.Context(), notificationID, userDid) 131 if err != nil { 132 http.Error(w, "Failed to mark notification as read", http.StatusInternalServerError) 133 return 134 } 135 136 w.WriteHeader(http.StatusNoContent) 137} 138 139func (n *Notifications) markAllRead(w http.ResponseWriter, r *http.Request) { 140 userDid := n.oauth.GetDid(r) 141 142 err := n.db.MarkAllNotificationsRead(r.Context(), userDid) 143 if err != nil { 144 http.Error(w, "Failed to mark all notifications as read", http.StatusInternalServerError) 145 return 146 } 147 148 http.Redirect(w, r, "/notifications", http.StatusSeeOther) 149} 150 151func (n *Notifications) deleteNotification(w http.ResponseWriter, r *http.Request) { 152 userDid := n.oauth.GetDid(r) 153 154 idStr := chi.URLParam(r, "id") 155 notificationID, err := strconv.ParseInt(idStr, 10, 64) 156 if err != nil { 157 http.Error(w, "Invalid notification ID", http.StatusBadRequest) 158 return 159 } 160 161 err = n.db.DeleteNotification(r.Context(), notificationID, userDid) 162 if err != nil { 163 http.Error(w, "Failed to delete notification", http.StatusInternalServerError) 164 return 165 } 166 167 w.WriteHeader(http.StatusOK) 168}