diff --git a/caddyhugo.go b/caddyhugo.go index 780f4d2..ef80f04 100644 --- a/caddyhugo.go +++ b/caddyhugo.go @@ -8,13 +8,13 @@ import ( "html/template" "io/ioutil" "net/http" + _ "net/http/pprof" "os" "os/exec" "path" "path/filepath" "strings" "sync" - "sync/atomic" "time" "git.stephensearles.com/stephen/acedoc" @@ -62,17 +62,20 @@ type CaddyHugo struct { func (ch *CaddyHugo) ObserveLTime(ltime uint64) uint64 { ch.mtx.Lock() - defer ch.mtx.Unlock() if ch.ltime < ltime { ch.ltime = ltime } + ch.mtx.Unlock() return ch.LTime() } func (ch *CaddyHugo) LTime() uint64 { - return atomic.AddUint64(&ch.ltime, 1) + ch.mtx.Lock() + defer ch.mtx.Unlock() + ch.ltime++ + return ch.ltime } func (ch *CaddyHugo) Setup(c *caddy.Controller) error { @@ -261,6 +264,7 @@ func (ch *CaddyHugo) doc(r *http.Request) (*docref, error) { defer ch.mtx.Unlock() name := r.URL.Path[len("/hugo/edit/"):] + name = filepath.Join(ch.Site.Root, name) _, ok := ch.docs[name] if !ok { @@ -363,7 +367,20 @@ func (ch *CaddyHugo) DeltaWebsocket(w http.ResponseWriter, r *http.Request) (int return http.StatusBadRequest, err } + const idlePing = 15 * time.Second + const idlePingShort = 1 * time.Millisecond + var timer *time.Timer + + timer = time.AfterFunc(idlePing, func() { + conn.WriteJSON(Message{ + Deltas: []acedoc.Delta{}, + LTime: ch.LTime(), + }) + timer.Reset(idlePing) + }) + client := doc.doc.Client(acedoc.DeltaHandlerFunc(func(ds []acedoc.Delta) error { + timer.Reset(idlePing) err := conn.WriteJSON(Message{ Deltas: ds, LTime: ch.LTime(), @@ -390,11 +407,13 @@ func (ch *CaddyHugo) DeltaWebsocket(w http.ResponseWriter, r *http.Request) (int fmt.Println(message) ch.ObserveLTime(message.LTime) + timer.Reset(idlePingShort) err = client.PushDeltas(message.Deltas...) if err != nil { return http.StatusBadRequest, err } + } } diff --git a/templates.go b/templates.go index 625c421..9e25bb2 100644 --- a/templates.go +++ b/templates.go @@ -17,10 +17,19 @@ func (t tmplData) Content() ([]string, error) { var files []string err := filepath.Walk(path.Join(t.Site.Root, "content"), func(name string, fi os.FileInfo, err error) error { + if err != nil { + return err + } + if fi.IsDir() { return nil } + name, err = filepath.Rel(t.Site.Root, name) + if err != nil { + return err + } + files = append(files, name) return nil }) @@ -34,6 +43,33 @@ func (t tmplData) Content() ([]string, error) { } func (t tmplData) ContentTypes() ([]string, error) { + nameMap := map[string]struct{}{"default": struct{}{}} + + names, err := t.contentTypes(path.Join(t.Site.Root, "archetypes")) + if err != nil { + return nil, err + } + for _, name := range names { + nameMap[name] = struct{}{} + } + + names, err = t.contentTypes(path.Join(t.Site.Root, "themes", "hugo-theme-minos", "archetypes")) + if err != nil { + return nil, err + } + for _, name := range names { + nameMap[name] = struct{}{} + } + + var out []string + for name := range nameMap { + out = append(out, name[:len(name)-len(filepath.Ext(name))]) + } + + return out, nil +} + +func (t tmplData) contentTypes(dir string) ([]string, error) { layoutDir, err := os.Open(path.Join(t.Site.Root, "archetypes")) if err != nil { fmt.Println("opening layout dir", err) @@ -47,12 +83,7 @@ func (t tmplData) ContentTypes() ([]string, error) { return nil, err } - out := []string{"default"} - for _, name := range names { - out = append(out, name[:len(name)-len(filepath.Ext(name))]) - } - - return out, nil + return names, nil } type tmplData struct { @@ -109,28 +140,64 @@ var EditPage = ` } + + +
+