package main import ( _ "embed" "encoding/json" "log" "net/http" "strings" "github.com/kami/maven/internal/ipc" ) //go:embed reminders.html var remindersHTML string var remindersTmpl = parsePage("reminders", remindersHTML, nil) // reminderRow is one line on /reminders, with the payload unwrapped and both // timestamps already in his clock. // // The page rendered `{{.Payload}}` and the UTC instant, so a reminder read // `{"text":"выпить таблетки"}` and fired an hour off what he was told // (Vikunja #469). Neither is a formatting nicety: the envelope is an internal // shape he never chose, and a time on a page he reads is the time on his wall. type reminderRow struct { Created string Fires string Status string Text string } // reminderText unwraps the {"text":...} payload the router writes. // // A copy of store.ReminderText rather than a call to it, because mavweb is one // of the pure-Go daemons and internal/store carries the CGO sqlite driver. The // ipc DTO is decoupled from the store on purpose, so the unwrap belongs to // whoever renders it. Payload that is not that shape is shown as he said it. func reminderText(payload string) string { var m map[string]any if err := json.Unmarshal([]byte(payload), &m); err == nil { if t, ok := m["text"]; ok { if s, isStr := t.(string); isStr && s != "" { return s } } } return strings.TrimSpace(payload) } func reminderRows(rs []ipc.Reminder) []reminderRow { out := make([]reminderRow, 0, len(rs)) for _, r := range rs { out = append(out, reminderRow{ Created: r.CreatedTs.Local().Format("02 Jan 15:04"), Fires: r.FireTs.Local().Format("02 Jan 15:04"), Status: r.Status, Text: reminderText(r.Payload), }) } return out } func handleReminders(w http.ResponseWriter, r *http.Request, core ipc.CoreAPI) { if !requireCore(w, core, "reminders") { return } reminders, err := core.ListReminders(r.Context(), 50) if err != nil { log.Printf("reminders: %v", err) http.Error(w, "reminders error: "+err.Error(), http.StatusBadGateway) return } renderPage(w, remindersTmpl, map[string]any{"Reminders": reminderRows(reminders)}) }