Skip to content

Commit

Permalink
Issue #31: Replace separate UI with the embedded HTMX based
Browse files Browse the repository at this point in the history
   - code review improvements
  • Loading branch information
oneils authored and umputun committed Oct 8, 2023
1 parent 2b01215 commit bdb40f4
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 59 deletions.
70 changes: 15 additions & 55 deletions backend/app/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"html/template"
"net/http"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -100,18 +99,26 @@ func (s Server) routes() chi.Router {
s.render(w, http.StatusNotFound, "404.tmpl.html", baseTmpl, "not found")
})

router.Get("/", s.indexCtrl)
router.Post("/generate-link", s.generateLink)
router.Get("/message/{key}", s.showMessageView)
router.Post("/load-message", s.loadMessage)
router.Get("/about", s.aboutView)
router.Group(func(r chi.Router) {
r.Use(Logger(log.Default()))
r.Use(middleware.StripSlashes)
r.Post("/generate-link", s.generateLinkCtrl)
r.Get("/message/{key}", s.showMessageViewCtrl)
r.Post("/load-message", s.loadMessageCtrl)
r.Get("/about", s.aboutViewCtrl)
r.Get("/", s.indexCtrl)
})

s.fileServer(router, "/", truncatedFileSystem{http.Dir(s.WebRoot)})
fs, err := um.NewFileServer("/static", s.WebRoot)
if err != nil {
log.Fatalf("[ERROR] can't create file server %v", err)
}

router.Handle("/static/*", fs)

return router
}

// POST /v1/message
func (s Server) saveMessageCtrl(w http.ResponseWriter, r *http.Request) {
request := struct {
Message string
Expand Down Expand Up @@ -187,50 +194,3 @@ func (s Server) getParamsCtrl(w http.ResponseWriter, r *http.Request) {
}
render.JSON(w, r, params)
}

// serves static files
func (s Server) fileServer(r chi.Router, path string, root http.FileSystem) {
log.Printf("[INFO] run file server for %s", root)
fs := http.StripPrefix(path, http.FileServer(root))

path += "*"

r.Handle(path, http.StripPrefix("/static", fs))
}

// truncatedFileSystem is a wrapper for http.FileSystem to disable directory listings.
// It serves index.html for directories if present and return 404 for others
type truncatedFileSystem struct {
fs http.FileSystem
}

// Open returns file or index.html for directories
func (nfs truncatedFileSystem) Open(path string) (http.File, error) {
f, err := nfs.fs.Open(path)
if err != nil {
return nil, err
}

s, err := f.Stat()
if err != nil {
closeErr := f.Close()
if closeErr != nil {
return nil, closeErr
}

return nil, err
}
if s.IsDir() {
index := filepath.Join(path, "index.html")
if _, err := nfs.fs.Open(index); err != nil {
closeErr := f.Close()
if closeErr != nil {
return nil, closeErr
}

return nil, err
}
}

return f, nil
}
26 changes: 22 additions & 4 deletions backend/app/server/templates.go → backend/app/server/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type templateData struct {
PinSize int
}

// render renders a template
func (s Server) render(w http.ResponseWriter, status int, page, tmplName string, data any) {
ts, ok := s.TemplateCache[page]
if !ok {
Expand Down Expand Up @@ -81,6 +82,7 @@ func (s Server) render(w http.ResponseWriter, status int, page, tmplName string,
}

// renders the home page
// GET /
func (s Server) indexCtrl(w http.ResponseWriter, r *http.Request) { // nolint
data := templateData{
Form: createMsgForm{
Expand All @@ -94,7 +96,12 @@ func (s Server) indexCtrl(w http.ResponseWriter, r *http.Request) { // nolint
}

// renders the generate link page
func (s Server) generateLink(w http.ResponseWriter, r *http.Request) {
// POST /generate-link
// Request Body: This function expects a POST request body containing the following fields:
// - "message" (string): The message content to be associated with the secure link.
// - "expUnit" (string): The unit of expiration time (e.g., "m" for minutes, "h" for hours, "d" for days).
// - "pin" (slice of strings): An array of PIN values.
func (s Server) generateLinkCtrl(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
s.render(w, http.StatusOK, "error.tmpl.html", errorTmpl, err.Error())
Expand Down Expand Up @@ -156,7 +163,10 @@ func (s Server) generateLink(w http.ResponseWriter, r *http.Request) {
}

// renders the show decoded message page
func (s Server) showMessageView(w http.ResponseWriter, r *http.Request) {
// GET /message/{key}
// URL Parameters:
// - "key" (string): A path parameter representing the unique key of the message to be displayed.
func (s Server) showMessageViewCtrl(w http.ResponseWriter, r *http.Request) {
key := chi.URLParam(r, keyKey)

data := templateData{
Expand All @@ -172,11 +182,17 @@ func (s Server) showMessageView(w http.ResponseWriter, r *http.Request) {
}

// renders the about page
func (s Server) aboutView(w http.ResponseWriter, r *http.Request) { // nolint
// GET /about
func (s Server) aboutViewCtrl(w http.ResponseWriter, r *http.Request) { // nolint
s.render(w, http.StatusOK, "about.tmpl.html", baseTmpl, nil)
}

func (s Server) loadMessage(w http.ResponseWriter, r *http.Request) {
// renders the decoded message page
// POST /load-message
// Request Body: This function expects a POST request body containing the following fields:
// - "key" (string): A path parameter representing the unique key of the message to be displayed.
// - "pin" (slice of strings): An array of PIN values.
func (s Server) loadMessageCtrl(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
s.render(w, http.StatusOK, "error.tmpl.html", errorTmpl, err.Error())
Expand Down Expand Up @@ -232,6 +248,7 @@ func (s Server) loadMessage(w http.ResponseWriter, r *http.Request) {
s.render(w, http.StatusOK, "decoded-message.tmpl.html", "decoded-message", string(msg.Data))
}

// duration converts a number and unit into a time.Duration
func duration(n int, unit string) time.Duration {
switch unit {
case "m":
Expand All @@ -245,6 +262,7 @@ func duration(n int, unit string) time.Duration {
}
}

// humanDuration converts a time.Duration into a human readable string like "5 minutes"
func humanDuration(d time.Duration) string {
switch {
case d < time.Minute:
Expand Down
File renamed without changes.

0 comments on commit bdb40f4

Please sign in to comment.