diff options
Diffstat (limited to 'internal/web/handlers_design.go')
| -rw-r--r-- | internal/web/handlers_design.go | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/internal/web/handlers_design.go b/internal/web/handlers_design.go index 0db66c2..3da7ee3 100644 --- a/internal/web/handlers_design.go +++ b/internal/web/handlers_design.go @@ -15,7 +15,8 @@ import ( "github.com/gramanas/blogspace/internal/store" ) -var allowedImageTypes = map[string]bool{"image/png": true, "image/jpeg": true, "image/gif": true, "image/webp": true} +// ICO is here for site icons; it is harmless anywhere else an image can go. +var allowedImageTypes = map[string]bool{"image/png": true, "image/jpeg": true, "image/gif": true, "image/webp": true, "image/x-icon": true} func (s *Server) handleDesignForm(w http.ResponseWriter, r *http.Request) { blog := currentBlog(r) @@ -24,7 +25,7 @@ func (s *Server) handleDesignForm(w http.ResponseWriter, r *http.Request) { s.serverError(w, err) return } - s.render(w, r, "dashboard/design.html", map[string]any{"theme": ParseTheme(blog.ThemeJSON), "images": images}) + s.render(w, r, "dashboard/design.html", map[string]any{"theme": ParseTheme(blog.ThemeJSON), "images": images, "presets": Presets()}) } func (s *Server) handleDesign(w http.ResponseWriter, r *http.Request) { @@ -35,10 +36,11 @@ func (s *Server) handleDesign(w http.ResponseWriter, r *http.Request) { } theme := ThemeFromForm(ParseTheme(blog.ThemeJSON), r.Form) // Optional direct uploads from the design form. - for field, dst := range map[string]*string{"bg_image_file": &theme.BgImage, "header_image_file": &theme.HeaderImage} { + for field, dst := range map[string]*string{"bg_image_file": &theme.BgImage, "header_image_file": &theme.HeaderImage, "favicon_file": &theme.Favicon} { img, err := s.readUpload(r, field) if err != nil { - s.renderStatus(w, r, http.StatusBadRequest, "dashboard/design.html", map[string]any{"theme": theme, "error": err.Error()}) + images, _ := s.st.ListImages(r.Context(), blog.ID) + s.renderStatus(w, r, http.StatusBadRequest, "dashboard/design.html", map[string]any{"theme": theme, "images": images, "presets": Presets(), "error": err.Error()}) return } if img != nil { @@ -52,6 +54,33 @@ func (s *Server) handleDesign(w http.ResponseWriter, r *http.Request) { redirectOK(w, r, "/b/"+blog.Subdomain+"/design", "Design saved. Refresh your blog to see it.") } +// handleDesignPreset applies a colour scheme straight away; it is a separate +// form so it cannot be confused with the unsaved edits of the main one. +func (s *Server) handleDesignPreset(w http.ResponseWriter, r *http.Request) { + blog := currentBlog(r) + p, ok := PresetByKey(r.FormValue("preset")) + if !ok { + s.plainError(w, http.StatusBadRequest, "Unknown colour scheme.") + return + } + theme := ParseTheme(blog.ThemeJSON).WithPreset(p) + if err := s.st.UpdateBlogTheme(r.Context(), blog.ID, theme.JSON()); err != nil { + s.serverError(w, err) + return + } + redirectOK(w, r, "/b/"+blog.Subdomain+"/design", "Applied the "+p.Name+" scheme. Refresh your blog to see it.") +} + +// handleDesignReset restores the defaults; images stay in the library. +func (s *Server) handleDesignReset(w http.ResponseWriter, r *http.Request) { + blog := currentBlog(r) + if err := s.st.UpdateBlogTheme(r.Context(), blog.ID, DefaultTheme().JSON()); err != nil { + s.serverError(w, err) + return + } + redirectOK(w, r, "/b/"+blog.Subdomain+"/design", "Design reset to the defaults.") +} + // readUpload stores the file from a multipart field, returning nil if the field is empty. func (s *Server) readUpload(r *http.Request, field string) (*store.Image, error) { if r.MultipartForm == nil { @@ -82,7 +111,7 @@ func (s *Server) storeUpload(r *http.Request, fh *multipart.FileHeader) (*store. } ct := http.DetectContentType(buf.Bytes()) if !allowedImageTypes[ct] { - return nil, errors.New("only PNG, JPEG, GIF and WebP images are accepted") + return nil, errors.New("only PNG, JPEG, GIF, WebP and ICO images are accepted") } name := filepath.Base(fh.Filename) if name == "" || name == "." || len(name) > 120 { @@ -186,6 +215,9 @@ func (s *Server) handleImageDelete(w http.ResponseWriter, r *http.Request) { if theme.HeaderImage == id.String() { theme.HeaderImage, changed = "", true } + if theme.Favicon == id.String() { + theme.Favicon, changed = "", true + } if changed { if err := s.st.UpdateBlogTheme(r.Context(), blog.ID, theme.JSON()); err != nil { s.serverError(w, err) |
