From 7ecb79793fd5a5d73bbefb550be9657582d6b568 Mon Sep 17 00:00:00 2001 From: vilmibm Date: Thu, 23 Feb 2023 07:19:30 +0000 Subject: [PATCH] render notes --- cmd/review/main.go | 59 +++++++++++++++++++++++++++++++++++----------- models/models.go | 45 +++++++++++++++++++++++++++++++---- 2 files changed, 86 insertions(+), 18 deletions(-) diff --git a/cmd/review/main.go b/cmd/review/main.go index 4ef08ba..dcfacea 100644 --- a/cmd/review/main.go +++ b/cmd/review/main.go @@ -78,6 +78,18 @@ func renderSignup(s models.TownSignup) string { return out } +func renderNotes(s models.TownSignup) string { + out := "" + for _, note := range s.Notes { + out += fmt.Sprintf(`%s said on %s: + %s`, note.Author, note.Created.Format("2006-01-02 15:04"), note.Content) + + out += "\n\n" + + } + return out +} + func _main() error { /* TODO will use this for invites @@ -126,11 +138,6 @@ func _main() error { appView := tview.NewTextView() appView.SetDynamicColors(true) - if len(signups) == 0 { - appView.SetText("no signups found.") - } else { - appView.SetText(renderSignup(*signups[signupIx])) - } legend := tview.NewTextView() legend.SetText("s: skip r: random A: approve R: reject N: notate Q: quit") @@ -145,15 +152,23 @@ func _main() error { } updateCount() + notesView := tview.NewTextView() + notesView.SetDynamicColors(true) + bottomFlex := tview.NewFlex() bottomFlex.SetDirection(tview.FlexColumn) bottomFlex.AddItem(count, 0, 1, false) bottomFlex.AddItem(legend, 0, 10, false) + innerFlex := tview.NewFlex() + innerFlex.SetDirection(tview.FlexColumn) + innerFlex.AddItem(appView, 0, 1, true) + innerFlex.AddItem(notesView, 0, 1, true) + mainFlex := tview.NewFlex() mainFlex.SetDirection(tview.FlexRow) mainFlex.AddItem(title, 1, -1, false) - mainFlex.AddItem(appView, 0, 1, true) + mainFlex.AddItem(innerFlex, 0, 1, false) mainFlex.AddItem(bottomFlex, 1, -1, false) pages := tview.NewPages() @@ -164,6 +179,24 @@ func _main() error { pages.SwitchToPage("main") }) + render := func() { + if len(signups) == 0 { + appView.SetText("no signups") + return + } + currSignup := signups[signupIx] + err := currSignup.RefreshNotes(signupDB) + if err != nil { + errorModal.SetText(fmt.Sprintf("error! failed to add note: %s", err.Error())) + pages.SwitchToPage("error") + } + + appView.SetText(renderSignup(*currSignup)) + notesView.SetText(renderNotes(*currSignup)) + } + + render() + notate := tview.NewForm() notate.AddTextArea("note", "", 80, 10, 1000, func(string) {}) notate.AddButton("submit", func() { @@ -175,7 +208,7 @@ func _main() error { return } - // TODO force redraw of current item + render() pages.SwitchToPage("main") }) @@ -192,15 +225,11 @@ func _main() error { // TODO replace imperative shit with a signupManager advanceSignup := func() { - if len(signups) == 0 { - appView.SetText("no signups found.") - return - } signupIx++ if signupIx == len(signups) { signupIx = 0 } - appView.SetText(renderSignup(*signups[signupIx])) + render() } removeSignup := func(signup *models.TownSignup) { @@ -216,7 +245,7 @@ func _main() error { signupIx = 0 } } - appView.SetText(renderSignup(*signups[signupIx])) + render() } app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { @@ -230,7 +259,7 @@ func _main() error { case 'r': if len(signups) > 0 { signupIx = rand.Intn(len(signups)) - appView.SetText(renderSignup(*signups[signupIx])) + render() } case 'A': if len(signups) == 0 { @@ -246,6 +275,7 @@ func _main() error { } removeSignup(signup) updateCount() + render() // TODO generate invite token // TODO send invite email case 'R': @@ -261,6 +291,7 @@ func _main() error { } removeSignup(signup) updateCount() + render() case 'N': if len(signups) == 0 { return nil diff --git a/models/models.go b/models/models.go index eb1e18b..9e89e96 100644 --- a/models/models.go +++ b/models/models.go @@ -54,9 +54,6 @@ const ( SignupRejected SignupDecision = "rejected" ) -// TODO add DecisionTime column to DB -// TODO add DecisionBy column to DB -// TODO add CleanEmail column to DB type TownSignup struct { ID int64 Created time.Time @@ -99,6 +96,41 @@ func (s *TownSignup) Insert(db *sql.DB) error { return nil } +func (s *TownSignup) RefreshNotes(db *sql.DB) error { + stmt, err := db.Prepare(` + SELECT created, author, content + FROM notes + WHERE signupid = ?`) + if err != nil { + return err + } + + rows, err := stmt.Query(s.ID) + if err != nil { + return err + } + defer stmt.Close() + + s.Notes = []SignupNote{} + + for rows.Next() { + note := &SignupNote{} + var timestamp int64 + err = rows.Scan( + ×tamp, + ¬e.Author, + ¬e.Content, + ) + if err != nil { + return err + } + note.Created = time.Unix(timestamp, 0) + s.Notes = append(s.Notes, *note) + } + + return nil +} + func (s *TownSignup) All(db *sql.DB) ([]*TownSignup, error) { // TODO notes; circle back once can author them rows, err := db.Query(` @@ -126,7 +158,12 @@ func (s *TownSignup) All(db *sql.DB) ([]*TownSignup, error) { su.Created = time.Unix(timestamp, 0) - // TODO fetch notes + /* TODO do i need this? refreshing on render + if err = su.RefreshNotes(db); err != nil { + return nil, err + } + */ + out = append(out, su) }