Skip to content

Commit

Permalink
Feature: added minimal UI for better scrolling (#1)
Browse files Browse the repository at this point in the history
* some droft far a ui

* made UI acceptable

* css: tiny cleanup and improvements

* added more error checking to satisfy linter

---------

Co-authored-by: Daniel Menet <[email protected]>
  • Loading branch information
sontags and Daniel Menet authored Aug 7, 2023
1 parent d4528fd commit 147d076
Show file tree
Hide file tree
Showing 5 changed files with 452 additions and 58 deletions.
68 changes: 10 additions & 58 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package main

import (
"fmt"
"net/http"
"os"
"strings"

"github.com/carlmjohnson/versioninfo"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -143,62 +141,16 @@ func (a *App) svgCmd(cmd *cobra.Command, args []string) {
}

func (a *App) serveCmd(cmd *cobra.Command, args []string) {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
var focus []string
for _, e := range strings.Split(r.URL.Path, "+") {
focus = append(focus, strings.Trim(e, "/"))
}

rendererName := r.URL.Query().Get("renderer")
if rendererName == "" {
rendererName = a.flags.serve.renderer
}

cfg, err := NewConfig(a.flags.configfile)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}

// build system
sys, errs := build(a.flags.base, a.flags.glob, focus)
if len(errs) > 0 {
w.WriteHeader(http.StatusInternalServerError)
out := ""
for _, err = range errs {
out += fmt.Sprintf("%s\n", err.Error())
}
_, _ = w.Write([]byte(out))
return
}

// render template
renderer, ok := cfg.Renderer[rendererName]
if !ok {
exitOnErr(fmt.Errorf("renderer %s not specified in %s", rendererName, a.flags.configfile))
}
out, err := render(sys, renderer)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}

// create svg
img, err := svg(out)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}

w.Header().Set("Content-Type", "image/svg+xml")
_, _ = w.Write(img)
})

fmt.Printf("server listening on http://%s/, hit CTRL-C to stop server...\n", a.flags.serve.listener)
_ = http.ListenAndServe(a.flags.serve.listener, nil)
s, err := NewServer(
a.flags.serve.listener,
a.flags.serve.renderer,
a.flags.configfile,
a.flags.base,
a.flags.glob,
)
exitOnErr(err)
err = s.Run()
exitOnErr(err)
}

func (a *App) versionCmd(cmd *cobra.Command, args []string) {
Expand Down
117 changes: 117 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package main

import (
"bytes"
"embed"
"fmt"
"io/fs"
"net/http"
"strings"
"text/template"
)

//go:embed server/templates/*
var templateFS embed.FS

//go:embed server/static/*
var staticFS embed.FS

type server struct {
indexTemplate *template.Template
listener string
defaultRenderer string
configfile string
base string
glob string
}

func NewServer(listener, defaultRenderer, configfile, base, glob string) (*server, error) {
s := &server{
listener: listener,
defaultRenderer: defaultRenderer,
configfile: configfile,
base: base,
glob: glob,
}
var err error
s.indexTemplate, err = template.ParseFS(templateFS, "server/templates/index.html.tmpl")
return s, err
}

func (s *server) Run() error {
http.HandleFunc("/index.html", s.HandleIndex)

assets, err := fs.Sub(staticFS, "server")
if err != nil {
return err
}
fs := http.FileServer(http.FS(assets))
http.Handle("/static/", fs)

http.HandleFunc("/", s.HandleIndex)

fmt.Printf("server listening on http://%s/, hit CTRL-C to stop server...\n", s.listener)
err = http.ListenAndServe(s.listener, nil)
return err
}

func (s *server) HandleIndex(w http.ResponseWriter, r *http.Request) {
focusElems := r.URL.Query().Get("focus")
focus := strings.Split(focusElems, "_")

rendererName := r.URL.Query().Get("renderer")
if rendererName == "" {
rendererName = s.defaultRenderer
}

cfg, err := NewConfig(s.configfile)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}

// build system
sys, errs := build(s.base, s.glob, focus)
if len(errs) > 0 {
w.WriteHeader(http.StatusInternalServerError)
out := ""
for _, err = range errs {
out += fmt.Sprintf("%s\n", err.Error())
}
_, _ = w.Write([]byte(out))
return
}

// render template
renderer, ok := cfg.Renderer[rendererName]
if !ok {
exitOnErr(fmt.Errorf("renderer %s not specified in %s", rendererName, s.configfile))
}
out, err := render(sys, renderer)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}

// create svg
img, err := svg(out)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}

var buf bytes.Buffer

thing := strings.TrimSuffix(strings.TrimPrefix(string(img), `<?xml version="1.0" encoding="utf-8"?><svg`), "</xml>")
thing = `<svg id="svg" class="svg"` + thing
err = s.indexTemplate.Execute(&buf, thing)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
return
}
_, _ = w.Write(buf.Bytes())
}
Loading

0 comments on commit 147d076

Please sign in to comment.