Monorepo for Tangled
Something went wrong. Try again.
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128package focus
import ( "log/slog" "net/http" "strconv"
"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" "tangled.org/core/idresolver")
type Focus struct { db *db.DB oauth *oauth.OAuth pages *pages.Pages logger *slog.Logger resolver *idresolver.Resolver}
func New(database *db.DB, o *oauth.OAuth, res *idresolver.Resolver, p *pages.Pages, logger *slog.Logger) *Focus { return &Focus{ db: database, oauth: o, pages: p, resolver: res, logger: logger, }}
func (f *Focus) Router(mw *middleware.Middleware) http.Handler { r := chi.NewRouter() r.Use(middleware.AuthMiddleware(f.oauth)) r.Post("/begin", f.BeginFocus) r.Post("/end", f.EndFocus) r.Post("/next", f.FocusNext) return r}
// BeginFocus activates focus mode and redirects the user to the oldest unread// focus-eligible notification.func (f *Focus) BeginFocus(w http.ResponseWriter, r *http.Request) { l := f.logger.With("handler", "BeginFocus") did := f.oauth.GetDid(r)
if err := db.BeginFocus(f.db, did); err != nil { l.Error("failed to begin focus", "err", err) http.Error(w, "internal error", http.StatusInternalServerError) return }
item, err := db.GetNextFocusItem(f.db, did) if err != nil { l.Error("failed to get first focus item", "err", err) _ = db.EndFocus(f.db, did) http.Redirect(w, r, "/notifications", http.StatusSeeOther) return } if item == nil { _ = db.EndFocus(f.db, did) http.Redirect(w, r, "/notifications", http.StatusSeeOther) return }
target := item.URL(f.resolver) if target == "" { _ = db.EndFocus(f.db, did) http.Redirect(w, r, "/notifications", http.StatusSeeOther) return }
http.Redirect(w, r, target, http.StatusSeeOther)}
// EndFocus deactivates focus mode and redirects to /notifications.func (f *Focus) EndFocus(w http.ResponseWriter, r *http.Request) { l := f.logger.With("handler", "EndFocus") did := f.oauth.GetDid(r)
if err := db.EndFocus(f.db, did); err != nil { l.Error("failed to end focus", "err", err) http.Error(w, "internal error", http.StatusInternalServerError) return }
http.Redirect(w, r, "/notifications", http.StatusSeeOther)}
// FocusNext marks the current focus notification as read and redirects to the// next focus item. If the queue is empty, focus mode is ended.func (f *Focus) FocusNext(w http.ResponseWriter, r *http.Request) { l := f.logger.With("handler", "FocusNext") did := f.oauth.GetDid(r)
// Mark the current item read so it leaves the queue. if currentIDStr := r.FormValue("current_id"); currentIDStr != "" { if currentID, err := strconv.ParseInt(currentIDStr, 10, 64); err == nil && currentID > 0 { if err := db.MarkNotificationRead(f.db, currentID, did); err != nil { l.Warn("failed to mark notification read", "id", currentID, "err", err) } } }
item, err := db.GetNextFocusItem(f.db, did) if err != nil { l.Error("failed to get next focus item", "err", err) http.Error(w, "internal error", http.StatusInternalServerError) return } if item == nil { _ = db.EndFocus(f.db, did) http.Redirect(w, r, "/notifications", http.StatusSeeOther) return }
target := item.URL(f.resolver) if target == "" { _ = db.EndFocus(f.db, did) http.Redirect(w, r, "/notifications", http.StatusSeeOther) return }
http.Redirect(w, r, target, http.StatusSeeOther)}