show loading status in user interface

This commit is contained in:
Brad Rydzewski 2017-09-20 12:29:57 -07:00
parent ae51e9d1b9
commit ec6016062b
5 changed files with 108 additions and 17 deletions

View file

@ -2,6 +2,7 @@ package main
import (
"fmt"
"time"
"github.com/cncd/queue"
"github.com/dimfeld/httptreemux"
@ -176,11 +177,10 @@ func setupCoding(c *cli.Context) (remote.Remote, error) {
func setupTree(c *cli.Context) *httptreemux.ContextMux {
tree := httptreemux.NewContextMux()
if path := c.String("www"); path == "" {
web.New().Register(tree)
} else {
web.FromPath(path).Register(tree)
}
web.New(
web.WithDir(c.String("www")),
web.WithSync(time.Hour*72),
).Register(tree)
return tree
}

37
server/web/opts.go Normal file
View file

@ -0,0 +1,37 @@
package web
import "time"
// Options defines website handler options.
type Options struct {
sync time.Duration
path string
docs string
}
// Option configures the website handler.
type Option func(*Options)
// WithSync configures the website hanlder with the duration value
// used to determine if the user account requires synchronization.
func WithSync(d time.Duration) Option {
return func(o *Options) {
o.sync = d
}
}
// WithDir configures the website hanlder with the directory value
// used to serve the website from the local filesystem.
func WithDir(s string) Option {
return func(o *Options) {
o.path = s
}
}
// WithDocs configures the website hanlder with the documentation
// website address, which should be included in the user interface.
func WithDocs(s string) Option {
return func(o *Options) {
o.docs = s
}
}

30
server/web/opts_test.go Normal file
View file

@ -0,0 +1,30 @@
package web
import (
"testing"
"time"
)
func TestWithSync(t *testing.T) {
opts := new(Options)
WithSync(time.Minute)(opts)
if got, want := opts.sync, time.Minute; got != want {
t.Errorf("Want sync duration %v, got %v", want, got)
}
}
func TestWithDir(t *testing.T) {
opts := new(Options)
WithDir("/tmp/www")(opts)
if got, want := opts.path, "/tmp/www"; got != want {
t.Errorf("Want www directory %q, got %q", want, got)
}
}
func TestWithDocs(t *testing.T) {
opts := new(Options)
WithDocs("http://docs.drone.io")(opts)
if got, want := opts.docs, "http://docs.drone.io"; got != want {
t.Errorf("Want documentation url %q, got %q", want, got)
}
}

View file

@ -68,6 +68,7 @@ const partials = `
{{ if .user }}
<script>
window.DRONE_USER = {{ json .user }};
window.DRONE_SYNC = {{ .syncing }};
</script>
{{ end }}
{{end}}
@ -83,4 +84,12 @@ const partials = `
{{define "version"}}
<meta name="version" content="{{ .version }}">
{{end}}
{{define "docs"}}
{{ if .docs -}}
<script>
window.DRONE_DOCS = "{{ .docs }}"
</script>
{{- end }}
{{end}}
`

View file

@ -25,32 +25,42 @@ type Endpoint interface {
}
// New returns the default website endpoint.
func New() Endpoint {
func New(opt ...Option) Endpoint {
opts := new(Options)
for _, f := range opt {
f(opts)
}
if opts.path != "" {
return fromPath(opts)
}
return &website{
fs: dist.New(),
templ: mustCreateTemplate(
fs: dist.New(),
opts: opts,
tmpl: mustCreateTemplate(
string(dist.MustLookup("/index.html")),
),
}
}
// FromPath returns the website endpoint that
// serves the webpage form disk at path p.
func FromPath(p string) Endpoint {
f := filepath.Join(p, "index.html")
func fromPath(opts *Options) *website {
f := filepath.Join(opts.path, "index.html")
b, err := ioutil.ReadFile(f)
if err != nil {
panic(err)
}
return &website{
fs: http.Dir(p),
templ: mustCreateTemplate(string(b)),
fs: http.Dir(opts.path),
tmpl: mustCreateTemplate(string(b)),
opts: opts,
}
}
type website struct {
fs http.FileSystem
templ *template.Template
opts *Options
fs http.FileSystem
tmpl *template.Template
}
func (w *website) Register(mux *httptreemux.ContextMux) {
@ -72,14 +82,19 @@ func (w *website) handleIndex(rw http.ResponseWriter, r *http.Request) {
user.Login,
).Sign(user.Hash)
}
var syncing bool
if user != nil {
syncing = time.Unix(user.Synced, 0).Add(w.opts.sync).Before(time.Now())
}
params := map[string]interface{}{
"user": user,
"csrf": csrf,
"syncing": syncing,
"version": version.Version.String(),
}
rw.Header().Set("Content-Type", "text/html; charset=UTF-8")
w.templ.Execute(rw, params)
w.tmpl.Execute(rw, params)
}
func setupCache(h http.Handler) http.Handler {