diff --git a/assets/style.css b/assets/style.css
index 9b51a95..844c811 100644
--- a/assets/style.css
+++ b/assets/style.css
@@ -15,8 +15,11 @@ section {
row-gap: 1em;
}
-.status-username {
+a {
font-weight: bold;
+}
+
+.status-username {
margin-bottom: .5em;
}
@@ -28,6 +31,26 @@ section {
margin-bottom: 1em;
}
+dt {
+ font-weight: bold;
+}
+
+dd {
+ margin-bottom: 1em;
+}
+
+.profile-picture {
+ float: right;
+}
+
+nav {
+ margin-bottom: 1em;
+}
+
+h1, h2 {
+ margin-top: 0;
+}
+
@media (min-width: 650px) {
.cols {
grid-template-columns: repeat(2, 1fr);
diff --git a/model/user.go b/model/user.go
index c649e2e..cc671fc 100644
--- a/model/user.go
+++ b/model/user.go
@@ -13,6 +13,8 @@ type User struct {
Hash []byte
Homepage string
About string
+ Style string
+ Picture string
CreatedAt time.Time
}
diff --git a/storage/migration.go b/storage/migration.go
index e89fd82..a04a0c3 100644
--- a/storage/migration.go
+++ b/storage/migration.go
@@ -7,7 +7,7 @@ import (
"strconv"
)
-const schemaVersion = 3
+const schemaVersion = 6
func Migrate(db *sql.DB) {
var currentVersion int
diff --git a/storage/sql.go b/storage/sql.go
index 65dbcad..e771881 100644
--- a/storage/sql.go
+++ b/storage/sql.go
@@ -32,4 +32,10 @@ create table statuses
add column homepage varchar(500) not null DEFAULT '',
add column about varchar(500) not null DEFAULT '';
`,
+ "schema_version_4": `alter table users
+alter column about TYPE TEXT;`,
+ "schema_version_5": `alter table users
+ add column style TEXT not null DEFAULT '';`,
+ "schema_version_6": `alter table users
+ add column picture varchar(500) not null DEFAULT '';`,
}
diff --git a/storage/sql/schema_version_4.sql b/storage/sql/schema_version_4.sql
new file mode 100644
index 0000000..dff65a9
--- /dev/null
+++ b/storage/sql/schema_version_4.sql
@@ -0,0 +1,2 @@
+alter table users
+alter column about TYPE TEXT;
\ No newline at end of file
diff --git a/storage/sql/schema_version_5.sql b/storage/sql/schema_version_5.sql
new file mode 100644
index 0000000..04faed7
--- /dev/null
+++ b/storage/sql/schema_version_5.sql
@@ -0,0 +1,2 @@
+alter table users
+ add column style TEXT not null DEFAULT '';
\ No newline at end of file
diff --git a/storage/sql/schema_version_6.sql b/storage/sql/schema_version_6.sql
new file mode 100644
index 0000000..589a347
--- /dev/null
+++ b/storage/sql/schema_version_6.sql
@@ -0,0 +1,2 @@
+alter table users
+ add column picture varchar(500) not null DEFAULT '';
\ No newline at end of file
diff --git a/storage/status.go b/storage/status.go
index 81ee7e7..63fd90a 100644
--- a/storage/status.go
+++ b/storage/status.go
@@ -70,27 +70,27 @@ func (s *Storage) StatusById(id int64) (model.Status, error) {
return status, err
}
-func (s *Storage) StatusByUsername(user string, perPage int, page int64) ([]model.Status, error) {
+func (s *Storage) StatusByUsername(user string, perPage int, page int64) ([]model.Status, bool, error) {
rows, err := s.db.Query(statusQueryBuilder{
where: `author = $1`,
limit: strconv.Itoa(perPage + 1),
offset: `$2`,
}.build(), user, page*int64(perPage))
if err != nil {
- return nil, err
+ return nil, false, err
}
var statuses []model.Status
for rows.Next() {
post, err := s.populateStatus(rows)
if err != nil {
- return statuses, err
+ return nil, false, err
}
statuses = append(statuses, post)
}
if len(statuses) > perPage {
- return statuses[0:perPage], err
+ return statuses[0:perPage], true, err
}
- return statuses, err
+ return statuses, false, err
}
func (s *Storage) Statuses(page int64, perPage int) ([]model.Status, bool, error) {
diff --git a/storage/user.go b/storage/user.go
index 0aaaf1b..9f2524b 100644
--- a/storage/user.go
+++ b/storage/user.go
@@ -4,10 +4,10 @@ import (
"status/model"
)
-const queryFindName = `SELECT name, hash, created_at, homepage, about FROM users WHERE name=lower($1);`
+const queryFindName = `SELECT name, hash, created_at, homepage, about, style, picture FROM users WHERE name=lower($1);`
func (s *Storage) queryUser(q string, params ...interface{}) (user model.User, err error) {
- err = s.db.QueryRow(q, params...).Scan(&user.Name, &user.Hash, &user.CreatedAt, &user.Homepage, &user.About)
+ err = s.db.QueryRow(q, params...).Scan(&user.Name, &user.Hash, &user.CreatedAt, &user.Homepage, &user.About, &user.Style, &user.Picture)
return
}
@@ -77,11 +77,11 @@ func (s *Storage) DeleteUser(username string) error {
return err
}
-func (s *Storage) UpdateSettings(username, homepage, about string) error {
- stmt, err := s.db.Prepare(`UPDATE users SET homepage = $1, about = $2 WHERE name = $3;`)
+func (s *Storage) UpdateSettings(username, homepage, about, style, picture string) error {
+ stmt, err := s.db.Prepare(`UPDATE users SET homepage = $1, about = $2, style = $3, picture = $4 WHERE name = $5;`)
if err != nil {
return err
}
- _, err = stmt.Exec(homepage, about, username)
+ _, err = stmt.Exec(homepage, about, style, picture, username)
return err
}
diff --git a/web/handler/common.go b/web/handler/common.go
index 03274f4..364ccd0 100644
--- a/web/handler/common.go
+++ b/web/handler/common.go
@@ -16,7 +16,13 @@ var TplCommonMap = map[string]string{
{{ template "content" . }}
@@ -32,7 +38,7 @@ var TplCommonMap = map[string]string{
`,
"status": `{{ define "status" }}
-
+
{{ .Content }}
{{ end }}`,
diff --git a/web/handler/form/settings.go b/web/handler/form/settings.go
index 6cd85db..9338731 100644
--- a/web/handler/form/settings.go
+++ b/web/handler/form/settings.go
@@ -7,11 +7,15 @@ import (
type SettingsForm struct {
Homepage string
About string
+ Style string
+ Picture string
}
func NewSettingsForm(r *http.Request) *SettingsForm {
return &SettingsForm{
Homepage: r.FormValue("homepage"),
About: r.FormValue("about"),
+ Style: r.FormValue("style"),
+ Picture: r.FormValue("picture"),
}
}
diff --git a/web/handler/html.go b/web/handler/html.go
index 0a06b28..304b404 100644
--- a/web/handler/html.go
+++ b/web/handler/html.go
@@ -84,7 +84,7 @@ Are you sure you you want to delete the following status?
{{ end }}
{{ end }}`,
- "user": `{{ define "content" }}
+ "user": `{{ define "head" }}
+
+{{ end }}
+
+{{ define "content" }}
+
{{ .user }}
Homepage
@@ -178,6 +192,20 @@ Are you sure you you want to delete the following status?
{{ range .statuses }}
{{ template "status" . }}
{{ end }}
+ {{ if or .showMore (ne 0 .page) }}
+
+ {{ if ne 0 .page }}
+ {{ if eq 0 .prev_page }}
+ Newer statuses
+ {{ else }}
+ Newer statuses
+ {{ end }}
+ {{ end }}
+ {{ if .showMore }}
+ Older statuses
+ {{- end }}
+
+ {{ end }}
{{ end }}`,
diff --git a/web/handler/html/common/layout.html b/web/handler/html/common/layout.html
index f783b06..bff5167 100644
--- a/web/handler/html/common/layout.html
+++ b/web/handler/html/common/layout.html
@@ -11,7 +11,13 @@
{{ template "content" . }}
diff --git a/web/handler/html/common/status.html b/web/handler/html/common/status.html
index f31bbd0..1b96a13 100644
--- a/web/handler/html/common/status.html
+++ b/web/handler/html/common/status.html
@@ -1,6 +1,6 @@
{{ define "status" }}
-
+
{{ .Content }}
{{ end }}
\ No newline at end of file
diff --git a/web/handler/html/index.html b/web/handler/html/index.html
index f30508f..cf54db4 100644
--- a/web/handler/html/index.html
+++ b/web/handler/html/index.html
@@ -10,7 +10,7 @@
{{ end }}
-
+
Update status with bookmarklet
diff --git a/web/handler/html/settings.html b/web/handler/html/settings.html
index 9ae8789..69ecc4f 100644
--- a/web/handler/html/settings.html
+++ b/web/handler/html/settings.html
@@ -11,10 +11,19 @@
- about
- {{ .About }}
+ picture URL
+
+
+ about
+ {{ .About }}
+
+
+
+ style
+ {{ .Style }}
+
diff --git a/web/handler/html/user.html b/web/handler/html/user.html
index bab2a1d..9ad72b7 100644
--- a/web/handler/html/user.html
+++ b/web/handler/html/user.html
@@ -1,6 +1,11 @@
+{{ define "head" }}
+
+{{ end }}
+
{{ define "content" }}
+
{{ .user }}
Homepage
@@ -14,6 +19,20 @@
{{ range .statuses }}
{{ template "status" . }}
{{ end }}
+ {{ if or .showMore (ne 0 .page) }}
+
+ {{ if ne 0 .page }}
+ {{ if eq 0 .prev_page }}
+ Newer statuses
+ {{ else }}
+ Newer statuses
+ {{ end }}
+ {{ end }}
+ {{ if .showMore }}
+ Older statuses
+ {{- end }}
+
+ {{ end }}
{{ end }}
\ No newline at end of file
diff --git a/web/handler/index_show.go b/web/handler/index_show.go
index 688971e..cac232a 100644
--- a/web/handler/index_show.go
+++ b/web/handler/index_show.go
@@ -10,12 +10,13 @@ type Update struct {
}
func (h *Handler) showIndexView(w http.ResponseWriter, r *http.Request) {
+ user, _ := h.sess.Get(r)
statuses, err := h.storage.LatestStatuses()
if err != nil {
serverError(w, err)
return
}
- session, err := h.sess.Store.Get(r, "ichi")
+ session, err := h.sess.Store.Get(r, "status")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -28,5 +29,5 @@ func (h *Handler) showIndexView(w http.ResponseWriter, r *http.Request) {
h.renderLayout(w, "index", map[string]interface{}{
"statuses": statuses,
"flash": flash,
- }, "")
+ }, user)
}
diff --git a/web/handler/settings_show.go b/web/handler/settings_show.go
index 5c69480..f034b95 100644
--- a/web/handler/settings_show.go
+++ b/web/handler/settings_show.go
@@ -13,7 +13,7 @@ func (h *Handler) showSettingsView(w http.ResponseWriter, r *http.Request) {
unauthorized(w)
return
}
- session, err := h.sess.Store.Get(r, "ichi")
+ session, err := h.sess.Store.Get(r, "status")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -27,5 +27,7 @@ func (h *Handler) showSettingsView(w http.ResponseWriter, r *http.Request) {
"flash": flash,
"About": user.About,
"Homepage": user.Homepage,
+ "Style": user.Style,
+ "Picture": user.Picture,
}, username)
}
diff --git a/web/handler/settings-update.go b/web/handler/settings_update.go
similarity index 77%
rename from web/handler/settings-update.go
rename to web/handler/settings_update.go
index bd7a9a5..c6bcc97 100644
--- a/web/handler/settings-update.go
+++ b/web/handler/settings_update.go
@@ -13,11 +13,11 @@ func (h *Handler) updateSettings(w http.ResponseWriter, r *http.Request) {
return
}
f := form.NewSettingsForm(r)
- if err := h.storage.UpdateSettings(user, f.Homepage, f.About); err != nil {
+ if err := h.storage.UpdateSettings(user, f.Homepage, f.About, f.Style, f.Picture); err != nil {
serverError(w, err)
return
}
- session, err := h.sess.Store.Get(r, "ichi")
+ session, err := h.sess.Store.Get(r, "status")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/web/handler/status_edit.go b/web/handler/status_edit.go
index 518d6f6..6520508 100644
--- a/web/handler/status_edit.go
+++ b/web/handler/status_edit.go
@@ -33,7 +33,7 @@ func (h *Handler) showEditStatusView(w http.ResponseWriter, r *http.Request) {
unauthorized(w)
return
}
- session, err := h.sess.Store.Get(r, "ichi")
+ session, err := h.sess.Store.Get(r, "status")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/web/handler/status_save.go b/web/handler/status_save.go
index 1f4b13d..5a0b884 100644
--- a/web/handler/status_save.go
+++ b/web/handler/status_save.go
@@ -29,7 +29,7 @@ func (h *Handler) saveStatus(w http.ResponseWriter, r *http.Request) {
return
}
if r.URL.Query().Get("silent") != "1" {
- session, err := h.sess.Store.Get(r, "ichi")
+ session, err := h.sess.Store.Get(r, "status")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/web/handler/status_update.go b/web/handler/status_update.go
index 72a498e..cfcc566 100644
--- a/web/handler/status_update.go
+++ b/web/handler/status_update.go
@@ -35,7 +35,7 @@ func (h *Handler) updateStatus(w http.ResponseWriter, r *http.Request) {
serverError(w, err)
return
}
- session, err := h.sess.Store.Get(r, "ichi")
+ session, err := h.sess.Store.Get(r, "status")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/web/handler/user_show.go b/web/handler/user_show.go
index 7fcda58..a99b2e9 100644
--- a/web/handler/user_show.go
+++ b/web/handler/user_show.go
@@ -9,30 +9,43 @@ import (
"golang.org/x/image/font"
"golang.org/x/image/font/gofont/goregular"
"golang.org/x/image/math/fixed"
+ "html/template"
"image"
"image/color"
"image/draw"
+ "strconv"
+
//"image/png"
"net/http"
)
func (h *Handler) showUserView(w http.ResponseWriter, r *http.Request) {
+ var page int64 = 0
+ if val, ok := r.URL.Query()["page"]; ok && len(val[0]) == 1 {
+ page, _ = strconv.ParseInt(val[0], 10, 64)
+ }
username := mux.Vars(r)["user"]
user, err := h.storage.UserByName(username)
if err != nil {
notFound(w)
return
}
- statuses, err := h.storage.StatusByUsername(mux.Vars(r)["user"], 20, 0)
+ statuses, showMore, err := h.storage.StatusByUsername(mux.Vars(r)["user"], 20, page)
if err != nil {
serverError(w, err)
return
}
h.renderLayout(w, "user", map[string]interface{}{
- "user": username,
- "statuses": statuses,
- "homepage": user.Homepage,
- "about": user.About,
+ "user": username,
+ "statuses": statuses,
+ "homepage": user.Homepage,
+ "about": template.HTML(user.About),
+ "picture": user.Picture,
+ "style": template.CSS(user.Style),
+ "showMore": showMore,
+ "page": page,
+ "next_page": page + 1,
+ "prev_page": page - 1,
}, username)
}
@@ -48,7 +61,7 @@ func (h *Handler) showUserStatusView(w http.ResponseWriter, r *http.Request) {
notFound(w)
return
}
- statuses, err := h.storage.StatusByUsername(mux.Vars(r)["user"], 1, 0)
+ statuses, _, err := h.storage.StatusByUsername(mux.Vars(r)["user"], 1, 0)
if err != nil {
serverError(w, err)
return
@@ -113,7 +126,7 @@ func (h *Handler) showUserStatusImageView(w http.ResponseWriter, r *http.Request
notFound(w)
return
}
- statuses, err := h.storage.StatusByUsername(mux.Vars(r)["user"], 1, 0)
+ statuses, _, err := h.storage.StatusByUsername(mux.Vars(r)["user"], 1, 0)
if err != nil {
serverError(w, err)
return
@@ -137,11 +150,11 @@ func (h *Handler) showUserStatusImageView(w http.ResponseWriter, r *http.Request
}
width := 350
- dc := gg.NewContext(width, 80)
+ dc := gg.NewContext(width, 84)
dc.SetHexColor(background)
dc.Clear()
dc.SetHexColor(foreground)
- dc.DrawStringWrapped(text, 19, 16, 0, 0, float64(width-(2*16)), 1.5, gg.AlignLeft)
+ dc.DrawStringWrapped(text, 8, 4, 0, 0, float64(width-(2*16)), 1.5, gg.AlignLeft)
dc.EncodePNG(w)
//dc.SavePNG("out.png")