show loading status in user interface
This commit is contained in:
parent
ae51e9d1b9
commit
ec6016062b
5 changed files with 108 additions and 17 deletions
|
@ -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
37
server/web/opts.go
Normal 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
30
server/web/opts_test.go
Normal 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)
|
||||
}
|
||||
}
|
|
@ -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}}
|
||||
`
|
||||
|
|
|
@ -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(
|
||||
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 {
|
||||
opts *Options
|
||||
fs http.FileSystem
|
||||
templ *template.Template
|
||||
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 {
|
||||
|
|
Loading…
Reference in a new issue