Compare commits
No commits in common. "4fda818e6e819681eeec0fd5af34a6e86ddc908e" and "de66fb0b7788eab05a69c6dd988bb21d3bd23b22" have entirely different histories.
4fda818e6e
...
de66fb0b77
4 changed files with 69 additions and 153 deletions
|
|
@ -24,30 +24,10 @@
|
||||||
href="/static/css/tiny-mde.min.css"
|
href="/static/css/tiny-mde.min.css"
|
||||||
/>
|
/>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
|
||||||
var tinyMDE = new TinyMDE.Editor({ textarea: "noteBodyInput" });
|
var tinyMDE = new TinyMDE.Editor({ textarea: "noteBodyInput" });
|
||||||
var commandBar = new TinyMDE.CommandBar({
|
var commandBar = new TinyMDE.CommandBar({
|
||||||
element: "toolbar",
|
element: "toolbar",
|
||||||
editor: tinyMDE,
|
editor: tinyMDE,
|
||||||
commands: [
|
|
||||||
'bold', 'italic', 'strikethrough',
|
|
||||||
'|',
|
|
||||||
'code',
|
|
||||||
'|',
|
|
||||||
'h1', 'h2',
|
|
||||||
'|',
|
|
||||||
'ul', 'ol', {name: "checklist", title: "Check List", action: makeChecklist},
|
|
||||||
'|',
|
|
||||||
'blockquote', 'hr',
|
|
||||||
'|',
|
|
||||||
'insertLink', 'insertImage'
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function makeChecklist(editor) {
|
|
||||||
editor.wrapSelection("* [ ] ", "")
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
||||||
|
|
@ -7,26 +7,6 @@
|
||||||
<a class="btn btn-primary" href="{{.urlEdit}}">Edit</a>
|
<a class="btn btn-primary" href="{{.urlEdit}}">Edit</a>
|
||||||
<a class="btn btn-danger" href="{{.urlDelete}}">Delete</a>
|
<a class="btn btn-danger" href="{{.urlDelete}}">Delete</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2">
|
|
||||||
<h3>Ownership</h3>
|
|
||||||
{{if .note.Viewers}}
|
|
||||||
<p>This note is owned by <em>{{.note.Owner}}</em> and is further visible to</p>
|
|
||||||
<ul>
|
|
||||||
{{range .viewers}}
|
|
||||||
<li>{{.}}</li>
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
{{else}}
|
|
||||||
<p>This note is owned by <em>{{.note.Owner}}</em>.</p>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<form action="{{.urlShare}}" method="POST">
|
|
||||||
<div class="mb-3">
|
|
||||||
<input type="text" class="form-control" id="viewerInput" name="viewer" aria-described-by="viewerHelp" />
|
|
||||||
<div id="viewerHelp" class="form-text">Share with other user</div>
|
|
||||||
</div>
|
|
||||||
<button class="btn btn-primary" type="submit">Share</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
let checkBoxes = document.querySelectorAll('input[type=checkbox]')
|
let checkBoxes = document.querySelectorAll('input[type=checkbox]')
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ package notes
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/rand"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
|
@ -34,8 +34,7 @@ type Note struct {
|
||||||
BodyRendered template.HTML
|
BodyRendered template.HTML
|
||||||
Body []byte
|
Body []byte
|
||||||
Owner string
|
Owner string
|
||||||
Viewers map[string]struct{}
|
Viewers []string
|
||||||
Uid string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type NoteStore struct {
|
type NoteStore struct {
|
||||||
|
|
@ -72,20 +71,20 @@ func Init() error {
|
||||||
log.Printf("Looking in %s", notesDir)
|
log.Printf("Looking in %s", notesDir)
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
if !f.IsDir() {
|
if !f.IsDir() {
|
||||||
uid := strings.TrimSuffix(f.Name(), filepath.Ext(f.Name()))
|
encodedTitle := strings.TrimSuffix(f.Name(), filepath.Ext(f.Name()))
|
||||||
note, err := loadNote(uid)
|
note, err := LoadNote(encodedTitle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
title := note.Title
|
title := note.Title
|
||||||
|
|
||||||
log.Printf("Found note %s (title '%s', owner %s)", uid, title, note.Owner)
|
log.Printf("Found note %s (title '%s', owner %s)", encodedTitle, title, note.Owner)
|
||||||
|
|
||||||
Notes.Add(note, note.Owner)
|
Notes.notes[note.Owner] = append(Notes.notes[note.Owner], note)
|
||||||
|
|
||||||
for viewer := range note.Viewers {
|
for _, viewer := range note.Viewers {
|
||||||
Notes.Add(note, viewer)
|
Notes.notes[viewer] = append(Notes.notes[viewer], note)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -97,11 +96,11 @@ func (ns *NoteStore) Get(owner string) []*Note {
|
||||||
return ns.notes[owner]
|
return ns.notes[owner]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NoteStore) GetOne(owner string, uid string) (*Note, bool) {
|
func (ns *NoteStore) GetOne(owner string, encodedTitle string) (*Note, bool) {
|
||||||
notes := ns.Get(owner)
|
notes := ns.Get(owner)
|
||||||
|
|
||||||
for _, note := range notes {
|
for _, note := range notes {
|
||||||
if note.Uid == uid {
|
if note.EncodedTitle() == encodedTitle {
|
||||||
log.Printf("Found single note during GetOne %+v", note)
|
log.Printf("Found single note during GetOne %+v", note)
|
||||||
return note, true
|
return note, true
|
||||||
}
|
}
|
||||||
|
|
@ -109,8 +108,8 @@ func (ns *NoteStore) GetOne(owner string, uid string) (*Note, bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NoteStore) Add(note *Note, user string) {
|
func (ns *NoteStore) Add(note *Note) {
|
||||||
ns.notes[user] = append(ns.notes[user], note)
|
ns.notes[note.Owner] = append(ns.notes[note.Owner], note)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fmtPath(path string) string {
|
func fmtPath(path string) string {
|
||||||
|
|
@ -118,42 +117,14 @@ func fmtPath(path string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Note) marshalFrontmatter() ([]byte, error) {
|
func (n *Note) marshalFrontmatter() ([]byte, error) {
|
||||||
viewers := make([]string, 0, len(n.Viewers))
|
|
||||||
|
|
||||||
for viewer := range n.Viewers {
|
|
||||||
viewers = append(viewers, viewer)
|
|
||||||
}
|
|
||||||
frontmatter := make(map[string]interface{})
|
frontmatter := make(map[string]interface{})
|
||||||
frontmatter["owner"] = n.Owner
|
frontmatter["owner"] = n.Owner
|
||||||
frontmatter["viewers"] = viewers
|
frontmatter["viewers"] = n.Viewers
|
||||||
frontmatter["title"] = n.Title
|
|
||||||
|
|
||||||
marshaled, err := yaml.Marshal(&frontmatter)
|
marshaled, err := yaml.Marshal(&frontmatter)
|
||||||
return marshaled, err
|
return marshaled, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Note) ViewersAsList() []string {
|
|
||||||
keys := make([]string, 0, len(n.Viewers))
|
|
||||||
for key := range n.Viewers {
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewNoteNoSave(title string, owner string) *Note {
|
|
||||||
note := &Note{Title: title, Owner: owner}
|
|
||||||
note.Viewers = make(map[string]struct{})
|
|
||||||
return note
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewNote(title string, owner string) *Note {
|
|
||||||
note := NewNoteNoSave(title, owner)
|
|
||||||
note.Uid = rand.Text()
|
|
||||||
note.Save()
|
|
||||||
Notes.Add(note, note.Owner)
|
|
||||||
return note
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save a note to a path derived from the title
|
// Save a note to a path derived from the title
|
||||||
func (n *Note) Save() error {
|
func (n *Note) Save() error {
|
||||||
frontmatter, err := n.marshalFrontmatter()
|
frontmatter, err := n.marshalFrontmatter()
|
||||||
|
|
@ -161,7 +132,7 @@ func (n *Note) Save() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
filename := filepath.Join(conf.Conf.NotesDir, fmtPath(n.Uid))
|
filename := filepath.Join(conf.Conf.NotesDir, fmtPath(n.EncodedTitle()))
|
||||||
return os.WriteFile(
|
return os.WriteFile(
|
||||||
filename,
|
filename,
|
||||||
[]byte(fmt.Sprintf("---\n%s---\n%s", frontmatter, n.Body)),
|
[]byte(fmt.Sprintf("---\n%s---\n%s", frontmatter, n.Body)),
|
||||||
|
|
@ -181,9 +152,9 @@ func (n *Note) Render() {
|
||||||
n.BodyRendered = template.HTML(buf.String())
|
n.BodyRendered = template.HTML(buf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadNote from the disk. The path is derived from the uid
|
// LoadNote from the disk. The path is derived from the title
|
||||||
func loadNote(uid string) (*Note, error) {
|
func LoadNote(encodedTitle string) (*Note, error) {
|
||||||
filename := filepath.Join(conf.Conf.NotesDir, fmtPath(uid))
|
filename := filepath.Join(conf.Conf.NotesDir, fmtPath(encodedTitle))
|
||||||
f, err := os.Open(filename)
|
f, err := os.Open(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -215,6 +186,8 @@ func loadNote(uid string) (*Note, error) {
|
||||||
body = append(body, '\n')
|
body = append(body, '\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
title := DecodeTitle(encodedTitle)
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
context := parser.NewContext()
|
context := parser.NewContext()
|
||||||
if err := md.Convert([]byte(fullBody), &buf, parser.WithContext(context)); err != nil {
|
if err := md.Convert([]byte(fullBody), &buf, parser.WithContext(context)); err != nil {
|
||||||
|
|
@ -228,14 +201,7 @@ func loadNote(uid string) (*Note, error) {
|
||||||
return nil, errors.New("invalid note, missing 'owner' in frontmatter")
|
return nil, errors.New("invalid note, missing 'owner' in frontmatter")
|
||||||
}
|
}
|
||||||
|
|
||||||
title, ok := metaData["title"].(string)
|
note := &Note{Title: title, Body: body, Owner: owner}
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("invalid note, missing 'title' in frontmatter")
|
|
||||||
}
|
|
||||||
|
|
||||||
note := NewNoteNoSave(title, owner)
|
|
||||||
note.Uid = uid
|
|
||||||
note.Body = body
|
|
||||||
|
|
||||||
viewers := metaData["viewers"].([]interface{})
|
viewers := metaData["viewers"].([]interface{})
|
||||||
|
|
||||||
|
|
@ -244,25 +210,20 @@ func loadNote(uid string) (*Note, error) {
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("invalid note, non string type in 'viewers' in frontmatter")
|
return nil, errors.New("invalid note, non string type in 'viewers' in frontmatter")
|
||||||
}
|
}
|
||||||
|
note.Viewers = append(note.Viewers, v)
|
||||||
if v == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
note.AddViewer(v)
|
|
||||||
}
|
}
|
||||||
log.Printf("Note %s shared with %v", note.Title, note.Viewers)
|
log.Printf("Note %s shared with %v", note.Title, note.Viewers)
|
||||||
|
|
||||||
return note, nil
|
return note, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Note) AddViewer(viewer string) {
|
func DeleteNote(title string) error {
|
||||||
n.Viewers[viewer] = struct{}{}
|
filename := filepath.Join(conf.Conf.NotesDir, fmtPath(title))
|
||||||
|
return os.Remove(filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteNote(uid string) error {
|
func (n *Note) EncodedTitle() string {
|
||||||
filename := filepath.Join(conf.Conf.NotesDir, fmtPath(uid))
|
return base64.StdEncoding.EncodeToString([]byte(n.Title))
|
||||||
return os.Remove(filename)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type toggleCheckboxTransformer struct{ nthBox int }
|
type toggleCheckboxTransformer struct{ nthBox int }
|
||||||
|
|
@ -327,3 +288,12 @@ func (n *Note) ToggleBox(nthBox int) {
|
||||||
n.Body = buf.Bytes()
|
n.Body = buf.Bytes()
|
||||||
n.Save()
|
n.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DecodeTitle(encodedTitle string) string {
|
||||||
|
title, err := base64.StdEncoding.DecodeString(encodedTitle)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Couldn't decode base64 string '%s': %s", encodedTitle, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(title)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ func GetRoutes(prefix string) *http.ServeMux {
|
||||||
"view": {Path: "/{note}/", Protocol: "GET", Handler: view},
|
"view": {Path: "/{note}/", Protocol: "GET", Handler: view},
|
||||||
"delete": {Path: "/{note}/delete/", Protocol: "GET", Handler: delete},
|
"delete": {Path: "/{note}/delete/", Protocol: "GET", Handler: delete},
|
||||||
"edit": {Path: "/{note}/edit/", Protocol: "GET", Handler: edit},
|
"edit": {Path: "/{note}/edit/", Protocol: "GET", Handler: edit},
|
||||||
"share": {Path: "/{note}/share/", Protocol: "POST", Handler: share},
|
|
||||||
"save": {Path: "/{note}/edit/save/", Protocol: "POST", Handler: save},
|
"save": {Path: "/{note}/edit/save/", Protocol: "POST", Handler: save},
|
||||||
"togglebox": {Path: "/{note}/togglebox/", Protocol: "POST", Handler: togglebox},
|
"togglebox": {Path: "/{note}/togglebox/", Protocol: "POST", Handler: togglebox},
|
||||||
},
|
},
|
||||||
|
|
@ -36,25 +35,21 @@ func GetRoutes(prefix string) *http.ServeMux {
|
||||||
}
|
}
|
||||||
|
|
||||||
func view(w http.ResponseWriter, r *http.Request) {
|
func view(w http.ResponseWriter, r *http.Request) {
|
||||||
user := r.Context().Value(middleware.ContextKey("user")).(string)
|
// user := r.Context().Value(middleware.ContextKey("user")).(string)
|
||||||
|
|
||||||
uid := r.PathValue("note")
|
title := r.PathValue("note")
|
||||||
note, ok := notes.Notes.GetOne(user, uid)
|
note, err := notes.LoadNote(title)
|
||||||
|
urlEdit := myurls.Reverse("edit", urls.Repl{"note": title})
|
||||||
if !ok {
|
urlNew := myurls.Reverse("new", urls.Repl{})
|
||||||
http.NotFound(w, r)
|
urlDelete := myurls.Reverse("delete", urls.Repl{"note": title})
|
||||||
|
if err != nil {
|
||||||
|
http.Redirect(w, r, urlEdit, http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
viewers := note.ViewersAsList()
|
|
||||||
|
|
||||||
urlEdit := myurls.Reverse("edit", urls.Repl{"note": uid})
|
context := templ.Ctx{"note": note, "urlEdit": urlEdit, "urlDelete": urlDelete, "urlNew": urlNew}
|
||||||
urlNew := myurls.Reverse("new", urls.Repl{})
|
|
||||||
urlDelete := myurls.Reverse("delete", urls.Repl{"note": uid})
|
|
||||||
urlShare := myurls.Reverse("share", urls.Repl{"note": uid})
|
|
||||||
|
|
||||||
context := templ.Ctx{"note": note, "urlEdit": urlEdit, "urlDelete": urlDelete, "urlNew": urlNew, "urlShare": urlShare, "viewers": viewers}
|
|
||||||
note.Render()
|
note.Render()
|
||||||
err := templ.RenderTemplate(w, r, "view.tmpl.html", context)
|
err = templ.RenderTemplate(w, r, "view.tmpl.html", context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err.Error())
|
log.Print(err.Error())
|
||||||
http.Error(w, "Couldn't load template", http.StatusInternalServerError)
|
http.Error(w, "Couldn't load template", http.StatusInternalServerError)
|
||||||
|
|
@ -63,17 +58,18 @@ func view(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func edit(w http.ResponseWriter, r *http.Request) {
|
func edit(w http.ResponseWriter, r *http.Request) {
|
||||||
user := r.Context().Value(middleware.ContextKey("user")).(string)
|
// user := r.Context().Value(middleware.ContextKey("user")).(string)
|
||||||
|
|
||||||
uid := r.PathValue("note")
|
encodedTitle := r.PathValue("note")
|
||||||
note, ok := notes.Notes.GetOne(user, uid)
|
note, err := notes.LoadNote(encodedTitle)
|
||||||
if !ok {
|
if err != nil {
|
||||||
note = notes.NewNote("", user)
|
title := notes.DecodeTitle(encodedTitle)
|
||||||
|
note = ¬es.Note{Title: title}
|
||||||
}
|
}
|
||||||
|
|
||||||
urlSave := myurls.Reverse("save", urls.Repl{"note": uid})
|
urlSave := myurls.Reverse("save", urls.Repl{"note": encodedTitle})
|
||||||
context := templ.Ctx{"note": note, "urlSave": urlSave, "text": string(note.Body)}
|
context := templ.Ctx{"note": note, "urlSave": urlSave, "text": string(note.Body)}
|
||||||
err := templ.RenderTemplate(w, r, "edit.tmpl.html", context)
|
err = templ.RenderTemplate(w, r, "edit.tmpl.html", context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err.Error())
|
log.Print(err.Error())
|
||||||
http.Error(w, "Couldn't load template", http.StatusInternalServerError)
|
http.Error(w, "Couldn't load template", http.StatusInternalServerError)
|
||||||
|
|
@ -89,9 +85,11 @@ func new(w http.ResponseWriter, r *http.Request) {
|
||||||
title = "<New Note>"
|
title = "<New Note>"
|
||||||
}
|
}
|
||||||
|
|
||||||
note := notes.NewNote(title, user)
|
note := ¬es.Note{Title: title, Owner: user}
|
||||||
|
note.Save()
|
||||||
|
notes.Notes.Add(note)
|
||||||
|
|
||||||
urlEdit := myurls.Reverse("edit", urls.Repl{"note": note.Uid})
|
urlEdit := myurls.Reverse("edit", urls.Repl{"note": note.EncodedTitle()})
|
||||||
http.Redirect(w, r, urlEdit, http.StatusFound)
|
http.Redirect(w, r, urlEdit, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,8 +110,8 @@ func delete(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func save(w http.ResponseWriter, r *http.Request) {
|
func save(w http.ResponseWriter, r *http.Request) {
|
||||||
user := r.Context().Value(middleware.ContextKey("user")).(string)
|
user := r.Context().Value(middleware.ContextKey("user")).(string)
|
||||||
uid := r.PathValue("note")
|
oldTitle := r.PathValue("note")
|
||||||
note, ok := notes.Notes.GetOne(user, uid)
|
note, ok := notes.Notes.GetOne(user, oldTitle)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
|
|
@ -127,44 +125,32 @@ func save(w http.ResponseWriter, r *http.Request) {
|
||||||
note.Body = []byte(body)
|
note.Body = []byte(body)
|
||||||
note.Save()
|
note.Save()
|
||||||
|
|
||||||
http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": note.Uid}), http.StatusFound)
|
if oldTitle != note.EncodedTitle() {
|
||||||
}
|
notes.DeleteNote(oldTitle)
|
||||||
|
|
||||||
func share(w http.ResponseWriter, r *http.Request) {
|
|
||||||
user := r.Context().Value(middleware.ContextKey("user")).(string)
|
|
||||||
uid := r.PathValue("note")
|
|
||||||
note, ok := notes.Notes.GetOne(user, uid)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
http.NotFound(w, r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
viewer := r.FormValue("viewer")
|
http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": note.EncodedTitle()}), http.StatusFound)
|
||||||
note.AddViewer(viewer)
|
|
||||||
note.Save()
|
|
||||||
|
|
||||||
http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": note.Uid}), http.StatusFound)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func togglebox(w http.ResponseWriter, r *http.Request) {
|
func togglebox(w http.ResponseWriter, r *http.Request) {
|
||||||
user := r.Context().Value(middleware.ContextKey("user")).(string)
|
// user := r.Context().Value(middleware.ContextKey("user")).(string)
|
||||||
|
|
||||||
uid := r.PathValue("note")
|
title := r.PathValue("note")
|
||||||
nthBox, err := strconv.Atoi(r.FormValue("box"))
|
nthBox, err := strconv.Atoi(r.FormValue("box"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("You fucked up boy")
|
log.Fatal("You fucked up boy")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
note, ok := notes.Notes.GetOne(user, uid)
|
note, err := notes.LoadNote(title)
|
||||||
if !ok {
|
if err != nil {
|
||||||
http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": uid}), http.StatusFound)
|
http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": title}), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
note.ToggleBox(nthBox)
|
note.ToggleBox(nthBox)
|
||||||
|
|
||||||
http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": note.Uid}), http.StatusFound)
|
http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": note.EncodedTitle()}), http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
type titleAndURL struct {
|
type titleAndURL struct {
|
||||||
|
|
@ -184,7 +170,7 @@ func list(w http.ResponseWriter, r *http.Request) {
|
||||||
for _, note := range ns {
|
for _, note := range ns {
|
||||||
titlesAndUrls = append(
|
titlesAndUrls = append(
|
||||||
titlesAndUrls,
|
titlesAndUrls,
|
||||||
titleAndURL{Title: note.Title, URL: myurls.Reverse("view", urls.Repl{"note": note.Uid})},
|
titleAndURL{Title: note.Title, URL: myurls.Reverse("view", urls.Repl{"note": note.EncodedTitle()})},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue