From ec6016062bd1d7d702c5edf383eb0728df33dbdd Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Wed, 20 Sep 2017 12:29:57 -0700 Subject: [PATCH] show loading status in user interface --- cmd/drone-server/setup.go | 10 +++++----- server/web/opts.go | 37 +++++++++++++++++++++++++++++++++++++ server/web/opts_test.go | 30 ++++++++++++++++++++++++++++++ server/web/template.go | 9 +++++++++ server/web/web.go | 39 +++++++++++++++++++++++++++------------ 5 files changed, 108 insertions(+), 17 deletions(-) create mode 100644 server/web/opts.go create mode 100644 server/web/opts_test.go diff --git a/cmd/drone-server/setup.go b/cmd/drone-server/setup.go index 04101666..fabc6fac 100644 --- a/cmd/drone-server/setup.go +++ b/cmd/drone-server/setup.go @@ -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 } diff --git a/server/web/opts.go b/server/web/opts.go new file mode 100644 index 00000000..d3e70b05 --- /dev/null +++ b/server/web/opts.go @@ -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 + } +} diff --git a/server/web/opts_test.go b/server/web/opts_test.go new file mode 100644 index 00000000..188ec09d --- /dev/null +++ b/server/web/opts_test.go @@ -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) + } +} diff --git a/server/web/template.go b/server/web/template.go index 8d9e4a1b..dd93a74a 100644 --- a/server/web/template.go +++ b/server/web/template.go @@ -68,6 +68,7 @@ const partials = ` {{ if .user }} {{ end }} {{end}} @@ -83,4 +84,12 @@ const partials = ` {{define "version"}} {{end}} + +{{define "docs"}} +{{ if .docs -}} + +{{- end }} +{{end}} ` diff --git a/server/web/web.go b/server/web/web.go index 5f4d508d..58cb5dce 100644 --- a/server/web/web.go +++ b/server/web/web.go @@ -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 {