Update the way statuses work

This commit is contained in:
m15o 2021-11-22 18:12:07 +01:00
parent c0922e3fb9
commit 56427140b5
9 changed files with 109 additions and 19 deletions

View file

@ -2,13 +2,14 @@ package model
import ( import (
"errors" "errors"
"fmt"
"time" "time"
) )
type Status struct { type Status struct {
Id int64 Id int64
User string User string
Content string Content string
CreatedAt time.Time CreatedAt time.Time
} }
@ -22,3 +23,34 @@ func (s Status) Validate() error {
func (s Status) Date() string { func (s Status) Date() string {
return s.CreatedAt.Format("2006-01-02") return s.CreatedAt.Format("2006-01-02")
} }
func (s Status) TimeAgo() string {
// Taken from flounder.online <3
// https://github.com/alexwennerberg/flounder
d := time.Since(s.CreatedAt)
if d.Seconds() < 60 {
seconds := int(d.Seconds())
if seconds == 1 {
return "1 second ago"
}
return fmt.Sprintf("%d seconds ago", seconds)
} else if d.Minutes() < 60 {
minutes := int(d.Minutes())
if minutes == 1 {
return "1 minute ago"
}
return fmt.Sprintf("%d minutes ago", minutes)
} else if d.Hours() < 24 {
hours := int(d.Hours())
if hours == 1 {
return "1 hour ago"
}
return fmt.Sprintf("%d hours ago", hours)
} else {
days := int(d.Hours()) / 24
if days == 1 {
return "1 day ago"
}
return fmt.Sprintf("%d days ago", days)
}
}

View file

@ -7,7 +7,7 @@ import (
"strconv" "strconv"
) )
const schemaVersion = 1 const schemaVersion = 2
func Migrate(db *sql.DB) { func Migrate(db *sql.DB) {
var currentVersion int var currentVersion int

View file

@ -24,5 +24,8 @@ create table statuses
content VARCHAR(500) NOT NULL CHECK (content <> ''), content VARCHAR(500) NOT NULL CHECK (content <> ''),
created_at timestamp with time zone DEFAULT now() created_at timestamp with time zone DEFAULT now()
); );
`,
"schema_version_2": `alter table users
add column status_id int references statuses(id);
`, `,
} }

View file

@ -0,0 +1,2 @@
alter table users
add column status_id int references statuses(id);

View file

@ -1,6 +1,7 @@
package storage package storage
import ( import (
"context"
"database/sql" "database/sql"
"status/model" "status/model"
"strconv" "strconv"
@ -37,11 +38,25 @@ func (s *Storage) populateStatus(rows *sql.Rows) (model.Status, error) {
return status, nil return status, nil
} }
func (s *Storage) CreateStatus(status model.Status) (int64, error) { func (s *Storage) CreateStatus(status model.Status) error {
var lid int64 var statusId int64
err := s.db.QueryRow(`INSERT INTO statuses (author, content) VALUES ($1, $2) RETURNING id`, ctx := context.Background()
status.User, status.Content).Scan(&lid) tx, err := s.db.BeginTx(ctx, nil)
return lid, err if err != nil {
return err
}
if err := tx.QueryRowContext(ctx, `INSERT INTO statuses (author, content) VALUES ($1, $2) RETURNING id`,
status.User, status.Content).Scan(&statusId); err != nil {
tx.Rollback()
return err
}
if _, err := tx.ExecContext(ctx, `UPDATE users set status_id=$1 where name=$2`, statusId, status.User); err != nil {
tx.Rollback()
return err
}
err = tx.Commit()
return err
} }
func (s *Storage) StatusById(id int64) (model.Status, error) { func (s *Storage) StatusById(id int64) (model.Status, error) {
@ -100,6 +115,33 @@ func (s *Storage) Statuses(page int64, perPage int) ([]model.Status, bool, error
return statuses, false, err return statuses, false, err
} }
func (s *Storage) LatestStatuses() ([]model.Status, error) {
rows, err := s.db.Query(`
select
statuses.id,
users.name,
statuses.content,
statuses.created_at
from
users
inner join statuses
on users.status_id = statuses.id
order by statuses.created_at desc;
`)
if err != nil {
return nil, err
}
var statuses []model.Status
for rows.Next() {
post, err := s.populateStatus(rows)
if err != nil {
return statuses, err
}
statuses = append(statuses, post)
}
return statuses, err
}
func (s *Storage) UpdateStatus(status model.Status) error { func (s *Storage) UpdateStatus(status model.Status) error {
stmt, err := s.db.Prepare(`UPDATE statuses SET content = $1 WHERE id = $2 and author = $3;`) stmt, err := s.db.Prepare(`UPDATE statuses SET content = $1 WHERE id = $2 and author = $3;`)
if err != nil { if err != nil {

View file

@ -41,7 +41,13 @@ Are you sure you you want to delete the following status?
</form> </form>
{{ end }}`, {{ end }}`,
"index": `{{ define "content" }} "index": `{{ define "content" }}
<p>This is the index</p> <p><a href="javascript:void(open('http://localhost:8000/statuses/new','status.cafe','resizable,scrollbars,width=360,height=200'))">Update your status</a></p>
{{ range .statuses }}
<article class="status">
<div class="username"><a href="/{{ .User }}">{{ .User }}</a>, {{ .TimeAgo }}</div>
<p>{{ .Content }}</p>
</article>
{{ end }}
{{ end }}`, {{ end }}`,
"login": `{{ define "content" }} "login": `{{ define "content" }}
<h1>Login</h1> <h1>Login</h1>

View file

@ -1,3 +1,9 @@
{{ define "content" }} {{ define "content" }}
<p>This is the index</p> <p><a href="javascript:void(open('http://localhost:8000/statuses/new','status.cafe','resizable,scrollbars,width=360,height=200'))">Update your status</a></p>
{{ range .statuses }}
<article class="status">
<div class="username"><a href="/{{ .User }}">{{ .User }}</a>, {{ .TimeAgo }}</div>
<p>{{ .Content }}</p>
</article>
{{ end }}
{{ end }} {{ end }}

View file

@ -10,13 +10,12 @@ type Update struct {
} }
func (h *Handler) showIndexView(w http.ResponseWriter, r *http.Request) { func (h *Handler) showIndexView(w http.ResponseWriter, r *http.Request) {
// user, _ := h.sess.Get(r) statuses, err := h.storage.LatestStatuses()
if err != nil {
//h.renderLayout(w, "index", map[string]interface{}{ serverError(w, err)
// "Pages": pages, return
// "Files": files, }
// "News": news, h.renderLayout(w, "index", map[string]interface{}{
//}, user) "statuses": statuses,
}, "")
h.renderLayout(w, "index", nil, "")
} }

View file

@ -24,7 +24,7 @@ func (h *Handler) saveStatus(w http.ResponseWriter, r *http.Request) {
}, "") }, "")
return return
} }
if _, err := h.storage.CreateStatus(status); err != nil { if err := h.storage.CreateStatus(status); err != nil {
serverError(w, err) serverError(w, err)
return return
} }