I've included a way to see status as an image. I don't know if I will end-up using that.

This commit is contained in:
m15o 2021-11-25 06:51:40 +01:00
parent 003373834f
commit 8a2a048f83
9 changed files with 133 additions and 9 deletions

View file

@ -15,6 +15,19 @@ section {
row-gap: 1em;
}
.status-username {
font-weight: bold;
margin-bottom: .5em;
}
.status-content {
margin: 0 1em;
}
.status {
margin-bottom: 1em;
}
@media (min-width: 650px) {
.cols {
grid-template-columns: repeat(2, 1fr);

3
go.mod
View file

@ -3,8 +3,11 @@ module status
go 1.16
require (
github.com/fogleman/gg v1.3.0 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/gorilla/mux v1.8.0
github.com/gorilla/sessions v1.2.1
github.com/lib/pq v1.10.4
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect
)

6
go.sum
View file

@ -1,3 +1,7 @@
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
@ -8,6 +12,8 @@ github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI=
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View file

@ -9,14 +9,14 @@ var TplCommonMap = map[string]string{
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>status cafe</title>
<title>status </title>
<meta name="description" content="your friends' updates">
<link rel="stylesheet" href="/assets/style.css"/>
{{ template "head" . }}
</head>
<body>
<header>
<h1>status.cafe</h1>
<p>status </p>
</header>
<main>
{{ template "content" . }}

View file

@ -77,6 +77,7 @@ func New(cfg *config.Config, sess *session.Session, data *storage.Storage) (http
router.HandleFunc("/users/{user}", h.showUserView).Methods(http.MethodGet)
router.HandleFunc("/users/{user}/status.json", h.showUserStatusView).Methods(http.MethodGet)
router.HandleFunc("/users/{user}/status.png", h.showUserStatusImageView).Methods(http.MethodGet)
router.PathPrefix("/assets/").Handler(
http.StripPrefix("/assets/",
http.FileServer(

View file

@ -88,15 +88,18 @@ Are you sure you you want to delete the following status?
</div>
<br>
<input type="submit" value="Submit">
<h3>Update status with bookmarklet</h3>
<p>Drag to your bookmarks to update from anywhere: <a href="javascript:void(open('https://status.cafe/status-new','status.cafe','resizable,scrollbars,width=360,height=200'))">Set status</a></p>
<h3>Display status on your homepage</h3>
<p>todo</p>
</form>
</section>
<section>
<h2>Status stream</h2>
{{ range .statuses }}
<article class="status">
<div class="username"><a href="/users/{{ .User }}">{{ .User }}</a>, {{ .TimeAgo }}</div>
<p>{{ .Content }}</p>
<div class="status-username"><a href="/users/{{ .User }}">{{ .User }}</a>'s status, updated {{ .TimeAgo }}</div>
<p class="status-content">{{ .Content }}</p>
</article>
{{ end }}
</section>

View file

@ -4,14 +4,14 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>status cafe</title>
<title>status </title>
<meta name="description" content="your friends' updates">
<link rel="stylesheet" href="/assets/style.css"/>
{{ template "head" . }}
</head>
<body>
<header>
<h1>status.cafe</h1>
<p>status ☕</p>
</header>
<main>
{{ template "content" . }}

View file

@ -14,15 +14,18 @@
</div>
<br>
<input type="submit" value="Submit">
<h3>Update status with bookmarklet</h3>
<p>Drag to your bookmarks to update from anywhere: <a href="javascript:void(open('https://status.cafe/status-new','status.cafe','resizable,scrollbars,width=360,height=200'))">Set status</a></p>
<h3>Display status on your homepage</h3>
<p>todo</p>
</form>
</section>
<section>
<h2>Status stream</h2>
{{ range .statuses }}
<article class="status">
<div class="username"><a href="/users/{{ .User }}">{{ .User }}</a>, {{ .TimeAgo }}</div>
<p>{{ .Content }}</p>
<div class="status-username"><a href="/users/{{ .User }}">{{ .User }}</a>'s status, updated {{ .TimeAgo }}</div>
<p class="status-content">{{ .Content }}</p>
</article>
{{ end }}
</section>

View file

@ -2,7 +2,17 @@ package handler
import (
"encoding/json"
"github.com/fogleman/gg"
"github.com/golang/freetype"
"github.com/golang/freetype/truetype"
"github.com/gorilla/mux"
"golang.org/x/image/font"
"golang.org/x/image/font/gofont/goregular"
"golang.org/x/image/math/fixed"
"image"
"image/color"
"image/draw"
//"image/png"
"net/http"
)
@ -26,7 +36,7 @@ func (h *Handler) showUserView(w http.ResponseWriter, r *http.Request) {
type statusjson struct {
Author string `json:"author"`
Content string `json:"content"`
TimeAgo string `json:"time_ago"`
TimeAgo string `json:"timeAgo"`
}
func (h *Handler) showUserStatusView(w http.ResponseWriter, r *http.Request) {
@ -50,3 +60,88 @@ func (h *Handler) showUserStatusView(w http.ResponseWriter, r *http.Request) {
}
json.NewEncoder(w).Encode(res)
}
func drawText(canvas *image.RGBA, text string) error {
var (
fgColor image.Image
fontFace *truetype.Font
err error
fontSize = 12.0
)
fgColor = image.White
fontFace, err = freetype.ParseFont(goregular.TTF)
fontDrawer := &font.Drawer{
Dst: canvas,
Src: fgColor,
Face: truetype.NewFace(fontFace, &truetype.Options{
Size: fontSize,
Hinting: font.HintingFull,
}),
}
//textBounds, _ := fontDrawer.BoundString(text)
xPosition := fixed.I(20)
//textHeight := textBounds.Max.Y - textBounds.Min.Y
yPosition := fixed.I(20)
fontDrawer.Dot = fixed.Point26_6{
X: xPosition,
Y: yPosition,
}
fontDrawer.DrawString(text)
return err
}
func createAvatar(text string) *image.RGBA {
bgColor := color.RGBA{
R: 255,
G: 20,
B: 100,
A: 255,
}
background := image.NewRGBA(image.Rect(0, 0, 200, 100))
draw.Draw(background, background.Bounds(), &image.Uniform{C: bgColor},
image.Point{}, draw.Src)
drawText(background, text)
return background
}
func (h *Handler) showUserStatusImageView(w http.ResponseWriter, r *http.Request) {
user := mux.Vars(r)["user"]
if !h.storage.UserExists(user) {
notFound(w)
return
}
statuses, err := h.storage.StatusByUsername(mux.Vars(r)["user"], 1, 0)
if err != nil {
serverError(w, err)
return
}
//w.Header().Set("Access-Control-Allow-Origin", "*")
//w.Header().Set("Content-Type", "application/json")
var text string
if len(statuses) > 0 {
text = statuses[0].Content
}
background := "#ffffff"
foreground := "#000000"
if c := r.URL.Query().Get("background"); c != "" {
background = "#" + c
}
if c := r.URL.Query().Get("foreground"); c != "" {
foreground = "#" + c
}
width := 350
dc := gg.NewContext(width, 80)
dc.SetHexColor(background)
dc.Clear()
dc.SetHexColor(foreground)
dc.DrawStringWrapped(text, 19, 16, 0, 0, float64(width-(2*16)), 1.5, gg.AlignLeft)
dc.EncodePNG(w)
//dc.SavePNG("out.png")
//avatar := createAvatar(text)
//png.Encode(w, avatar)
}