Initial lookbook implementation
Pinterest-style visual bookmarking app with: - URL metadata extraction (OG/Twitter meta, oEmbed fallback) - Image caching in Postgres with 480px thumbnails - Multi-tag filtering with Ctrl/Cmd for OR mode - Fuzzy tag suggestions and inline tag editing - Browser console auth() with first-use password setup - Brutalist UI with Commit Mono font and Pico CSS - Light/dark mode via browser preference
This commit is contained in:
commit
fc625fb9cf
486 changed files with 195373 additions and 0 deletions
42
internal/handlers/router.go
Normal file
42
internal/handlers/router.go
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Router wraps http.ServeMux and automatically injects RequestContext into handlers.
|
||||
type Router struct {
|
||||
mux *http.ServeMux
|
||||
rc *RequestContext
|
||||
}
|
||||
|
||||
func NewRouter(rc *RequestContext) *Router {
|
||||
return &Router{
|
||||
mux: http.NewServeMux(),
|
||||
rc: rc,
|
||||
}
|
||||
}
|
||||
|
||||
// Handle registers a handler that returns an error.
|
||||
// The RequestContext is automatically injected and error handling is applied.
|
||||
func (rt *Router) Handle(pattern string, h Handler) {
|
||||
rt.mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||
rc := &RequestContext{
|
||||
DB: rt.rc.DB,
|
||||
Logger: rt.rc.Logger,
|
||||
TmplCache: rt.rc.TmplCache,
|
||||
}
|
||||
|
||||
handler := WithErrorHandling(rc, h)
|
||||
handler(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// HandleStd registers a standard http.Handler (for static files, etc.)
|
||||
func (rt *Router) HandleStd(pattern string, h http.Handler) {
|
||||
rt.mux.Handle(pattern, h)
|
||||
}
|
||||
|
||||
func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
rt.mux.ServeHTTP(w, r)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue