122 lines
2.9 KiB
Go
122 lines
2.9 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"html/template"
|
|
"io/fs"
|
|
"log"
|
|
"net/http"
|
|
|
|
"sprintpadawan/lib"
|
|
)
|
|
|
|
var templates *template.Template
|
|
|
|
func InitTemplates(fsys fs.FS) {
|
|
templates = template.Must(template.New("").Funcs(template.FuncMap{
|
|
"scaleToOptions": scaleToOptions,
|
|
"derefInt": func(i *int) int {
|
|
if i == nil {
|
|
return 0
|
|
}
|
|
return *i
|
|
},
|
|
"slice": func(s string, start, end int) string {
|
|
if len(s) == 0 {
|
|
return ""
|
|
}
|
|
if start < 0 {
|
|
start = 0
|
|
}
|
|
if end > len(s) || end <= 0 {
|
|
end = len(s)
|
|
}
|
|
if start > end {
|
|
return ""
|
|
}
|
|
return s[start:end]
|
|
},
|
|
"dict": func(values ...interface{}) (map[string]interface{}, error) {
|
|
if len(values)%2 != 0 {
|
|
return nil, fmt.Errorf("odd number of arguments to dict")
|
|
}
|
|
d := make(map[string]interface{})
|
|
for i := 0; i < len(values); i += 2 {
|
|
key, ok := values[i].(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("dict keys must be strings")
|
|
}
|
|
d[key] = values[i+1]
|
|
}
|
|
return d, nil
|
|
},
|
|
}).ParseFS(fsys, "templates/*.html"))
|
|
}
|
|
|
|
func isHTMX(r *http.Request) bool {
|
|
return r.Header.Get("HX-Request") == "true"
|
|
}
|
|
|
|
func renderTemplate(w http.ResponseWriter, name string, data interface{}) {
|
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
if err := templates.ExecuteTemplate(w, name, data); err != nil {
|
|
log.Printf("template error (%s): %v", name, err)
|
|
http.Error(w, "internal server error", http.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
func renderRoomStories(w http.ResponseWriter, roomID int, user *lib.User) {
|
|
room, err := lib.GetRoomByID(roomID)
|
|
if err != nil {
|
|
http.Error(w, "room not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
data, err := buildRoomData(room, user)
|
|
if err != nil {
|
|
http.Error(w, "failed to load room data", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
renderTemplate(w, "stories-panel", data)
|
|
}
|
|
|
|
func renderRoomMembers(w http.ResponseWriter, roomID int, user *lib.User) {
|
|
room, err := lib.GetRoomByID(roomID)
|
|
if err != nil {
|
|
http.Error(w, "room not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
data, err := buildRoomData(room, user)
|
|
if err != nil {
|
|
http.Error(w, "failed to load room data", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
renderTemplate(w, "members-panel", data)
|
|
}
|
|
|
|
func requireAuth(next http.HandlerFunc) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
cookie, err := r.Cookie("session_token")
|
|
if err != nil {
|
|
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
|
return
|
|
}
|
|
user, err := lib.GetUserFromSession(cookie.Value)
|
|
if err != nil || user == nil {
|
|
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
|
return
|
|
}
|
|
ctx := context.WithValue(r.Context(), userKey, user)
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
}
|
|
}
|
|
|
|
func isLoggedIn(r *http.Request) bool {
|
|
cookie, err := r.Cookie("session_token")
|
|
if err != nil {
|
|
return false
|
|
}
|
|
user, err := lib.GetUserFromSession(cookie.Value)
|
|
return err == nil && user != nil
|
|
}
|