various changes

This commit is contained in:
m15o 2021-12-14 07:41:05 +01:00
parent 5f97675216
commit 79d73d12f5
12 changed files with 163 additions and 77 deletions

BIN
assets/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

View file

@ -16,22 +16,6 @@ body {
background-color: lightgreen;
padding: 0.5em 1em;
color: darkgreen;
animation: 500ms ease-out 3s 1 forwards fadeout;
}
@keyframes fadeout {
0% {
opacity: 1;
}
99% {
opacity: 0;
font-size: inherit;
height: inherit;
}
100% {
font-size: 0;
height: 0;
}
}
.cols {

1
go.mod
View file

@ -5,7 +5,6 @@ go 1.16
require (
github.com/fogleman/gg v1.3.0
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/gorilla/feeds v1.1.1
github.com/gorilla/mux v1.8.0
github.com/gorilla/sessions v1.2.1
github.com/kr/pretty v0.3.0 // indirect

View file

@ -14,9 +14,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>{{ template "title" . }}Status Cafe</title>
<meta name="description" content="your friends' updates">
<link rel="stylesheet" href="/assets/style.css"/>
{{ if .face }}
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>{{ .face }}</text></svg>">
{{ else }}
<link rel="icon" href="/assets/favicon.ico">
{{ end }}
{{ template "head" . }}
</head>
<body>
@ -40,7 +45,7 @@ var TplCommonMap = map[string]string{
</html>
{{ end }}
{{ define "head" }}{{ end }}
`,
{{ define "title" }}{{ end }}`,
"status": `{{ define "status" }}
<div class="status-username"><a href="/users/{{ .User }}">{{ .User }}</a> {{ .Face }} {{ .TimeAgo }}</div>
<p class="status-content">{{ .Content }}</p>

View file

@ -2,18 +2,112 @@ package handler
import (
"fmt"
"github.com/gorilla/feeds"
"net/http"
"status/model"
"time"
)
import (
"encoding/xml"
)
type Feed struct {
XMLName xml.Name `xml:"http://www.w3.org/2005/Atom feed"`
Title string `xml:"title"`
ID string `xml:"id"`
Link []Link `xml:"link"`
Updated TimeStr `xml:"updated"`
Author *Person `xml:"author"`
Icon string `xml:"icon,omitempty"`
Logo string `xml:"logo,omitempty"`
Subtitle string `xml:"subtitle,omitempty"`
Entry []*Entry `xml:"entry"`
}
type Entry struct {
Title string `xml:"title"`
ID string `xml:"id"`
Link []Link `xml:"link"`
Published TimeStr `xml:"published"`
Updated TimeStr `xml:"updated"`
Author *Person `xml:"author"`
Summary *Text `xml:"summary"`
Content *Text `xml:"content"`
}
type Link struct {
Rel string `xml:"rel,attr,omitempty"`
Href string `xml:"href,attr"`
Type string `xml:"type,attr,omitempty"`
HrefLang string `xml:"hreflang,attr,omitempty"`
Title string `xml:"title,attr,omitempty"`
Length uint `xml:"length,attr,omitempty"`
}
type Person struct {
Name string `xml:"name"`
URI string `xml:"uri,omitempty"`
Email string `xml:"email,omitempty"`
InnerXML string `xml:",innerxml"`
}
type Text struct {
Type string `xml:"type,attr"`
Body string `xml:",chardata"`
}
type TimeStr string
func Time(t time.Time) TimeStr {
return TimeStr(t.Format("2006-01-02T15:04:05-07:00"))
}
func createAtomEntryFromStatus(status model.Status) *Entry {
return &Entry{
Title: fmt.Sprintf("%s %s %s", status.User, status.Face, truncate(status.Content, 50)),
ID: fmt.Sprintf("https://status.cafe/users/%s/%d", status.User, status.Id),
//Link: []Link{
// {
// Rel: "alternate",
// Href: fmt.Sprintf("https://status.cafe/users/%s/%d", status.User, status.Id),
// Type: "text/html",
// },
//},
Updated: Time(status.CreatedAt),
Published: Time(status.CreatedAt),
Author: &Person{
Name: status.User,
URI: fmt.Sprintf("https://status.cafe/users/%s", status.User),
},
Content: &Text{
Type: "text",
Body: status.Content,
},
}
}
func (h *Handler) showFeedView(w http.ResponseWriter, r *http.Request) {
now := time.Now()
feed := &feeds.Feed{
Title: "status.cafe",
Link: &feeds.Link{Href: "https://status.cafe/"},
Author: &feeds.Author{Name: "status.cafe"},
Created: now,
feed := Feed{
Title: "status.cafe",
ID: "https://status.cafe/",
Subtitle: "Your friends' updates",
Icon: "/assets/icon.png",
Author: &Person{
Name: "status.cafe",
URI: "https://status.cafe",
},
Updated: Time(time.Now()),
Link: []Link{
{
Rel: "self",
Href: "https://status.cafe/feed.atom",
},
{
Rel: "alternate",
Type: "text/html",
Href: "https://status.cafe",
},
},
}
statuses, err := h.storage.StatusFeed()
@ -23,25 +117,15 @@ func (h *Handler) showFeedView(w http.ResponseWriter, r *http.Request) {
}
for _, status := range statuses {
if err != nil {
serverError(w, err)
return
}
feed.Items = append(feed.Items, &feeds.Item{
Title: fmt.Sprintf("%s %s %s", status.User, status.Face, truncate(status.Content, 50)),
Link: &feeds.Link{Href: fmt.Sprintf("https://status.cafe/users/%s/%d", status.User, status.Id)},
Author: &feeds.Author{Name: status.User},
Content: status.Content,
Created: status.CreatedAt,
})
}
atom, err := feed.ToAtom()
if err != nil {
serverError(w, err)
return
feed.Entry = append(feed.Entry, createAtomEntryFromStatus(status))
}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "application/atom+xml")
w.Write([]byte(atom))
var data []byte
data, err = xml.MarshalIndent(&feed, "", " ")
if err != nil {
serverError(w, err)
}
w.Write([]byte(xml.Header + string(data)))
}

View file

@ -154,7 +154,6 @@ var TplMap = map[string]string{
{{ if .form.Error }}
<p>{{ .form.Error }}</p>
{{ end }}
{{ template "flash" .flash }}
<form action="/add" method="post">{{ template "status_form" .status }}</form>
<ul class="tools">
<li><a href="/about/status-updater">status updater</a> bookmarklet</li>
@ -369,7 +368,7 @@ var TplMap = map[string]string{
Drag the following link to your bookmarks toolbar:
</p>
<p>
<a href="javascript:void(open('https://status.cafe/add','status.cafe','resizable,scrollbars,width=350,height=290'))">status updater</a>
<a href="javascript:void(open('https://status.cafe/add','status.cafe','resizable,scrollbars,width=350,height=350'))">status updater</a>
</p>
<p>That's it! From now on, whenever you want to update your status, click the status updater button from your bookmarks and a pop-up window will launch to let you update it.</p>
</section>
@ -378,6 +377,8 @@ var TplMap = map[string]string{
<link rel="alternate" type="application/atom+xml" title="Atom feed" href="/users/{{ .user }}.atom" />
{{ end }}
{{ define "title" }}{{ .user }} - {{ end }}
{{ define "content" }}
<div class="cols">
<section>

View file

@ -4,9 +4,14 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>status.cafe</title>
<title>{{ template "title" . }}Status Cafe</title>
<meta name="description" content="your friends' updates">
<link rel="stylesheet" href="/assets/style.css"/>
{{ if .face }}
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>{{ .face }}</text></svg>">
{{ else }}
<link rel="icon" href="/assets/favicon.ico">
{{ end }}
{{ template "head" . }}
</head>
<body>
@ -30,3 +35,4 @@
</html>
{{ end }}
{{ define "head" }}{{ end }}
{{ define "title" }}{{ end }}

View file

@ -6,7 +6,6 @@
{{ if .form.Error }}
<p>{{ .form.Error }}</p>
{{ end }}
{{ template "flash" .flash }}
<form action="/add" method="post">{{ template "status_form" .status }}</form>
<ul class="tools">
<li><a href="/about/status-updater">status updater</a> bookmarklet</li>

View file

@ -15,7 +15,7 @@
Drag the following link to your bookmarks toolbar:
</p>
<p>
<a href="javascript:void(open('https://status.cafe/add','status.cafe','resizable,scrollbars,width=350,height=290'))">status updater</a>
<a href="javascript:void(open('https://status.cafe/add','status.cafe','resizable,scrollbars,width=350,height=350'))">status updater</a>
</p>
<p>That's it! From now on, whenever you want to update your status, click the status updater button from your bookmarks and a pop-up window will launch to let you update it.</p>
</section>

View file

@ -2,6 +2,8 @@
<link rel="alternate" type="application/atom+xml" title="Atom feed" href="/users/{{ .user }}.atom" />
{{ end }}
{{ define "title" }}{{ .user }} - {{ end }}
{{ define "content" }}
<div class="cols">
<section>

View file

@ -16,7 +16,7 @@ func (h *Handler) initTpl() {
for name, content := range TplMap {
views[name] = template.Must(template.New("main").Funcs(template.FuncMap{
"faces": func() []string {
return []string{"🙂", "😎", "😛", "🥰", "👽", "😱", "🤔", "😯", "🤒", "😡", "🥺", "🥳", "🤖", "💀", "😴", "😭", "☕", "🍺", "📖", "🔥", "❄️", "✨", "💡", "🎼"}
return []string{"🙂", "😎", "😛", "🥰", "❤️", "👽", "😱", "🤔", "😯", "🤒", "😡", "🥺", "🥳", "🤖", "💀", "😴", "😭", "🤐", "🤢", "👀", "☕", "🍺", "📖", "🔥", "❄️", "✨", "💡", "🎶", "✈️", "🚄", "🍿", "📰", "✏️", "🍱", "🎄", "🎁", "🌧️", "🌙", "🎨", "📺", "🍕", "✅"}
}}).Parse(commonTemplates + content))
}
}

View file

@ -2,11 +2,11 @@ package handler
import (
"encoding/json"
"encoding/xml"
"fmt"
"github.com/fogleman/gg"
"github.com/golang/freetype"
"github.com/golang/freetype/truetype"
"github.com/gorilla/feeds"
"github.com/gorilla/mux"
"golang.org/x/image/font"
"golang.org/x/image/font/gofont/goregular"
@ -75,9 +75,14 @@ func (h *Handler) showUserView(w http.ResponseWriter, r *http.Request) {
serverError(w, err)
return
}
face := ""
if len(statuses) > 0 {
face = statuses[0].Face
}
h.renderLayout(w, "user", map[string]interface{}{
"user": username,
"statuses": statuses,
"face": face,
"homepage": user.Homepage,
"about": template.HTML(user.About),
"picture": user.Picture,
@ -282,41 +287,42 @@ func (h *Handler) showAtomView(w http.ResponseWriter, r *http.Request) {
notFound(w)
return
}
now := time.Now()
feed := &feeds.Feed{
Title: user.Name,
Link: &feeds.Link{Href: fmt.Sprintf("https://status.cafe/users/%s", username)}, // TODO change the scheme?
Author: &feeds.Author{Name: user.Name, Email: "todo@todo.com"}, // TODO EMAIL
Created: now,
feed := Feed{
Title: user.Name,
ID: fmt.Sprintf("https://status.cafe/users/%s/", user.Name),
Author: &Person{
Name: user.Name,
URI: fmt.Sprintf("https://status.cafe/users/%s", user.Name),
},
Updated: Time(time.Now()),
Link: []Link{
{
Rel: "self",
Href: fmt.Sprintf("https://status.cafe/users/%s.atom", user.Name),
},
{
Rel: "alternate",
Href: fmt.Sprintf("https://status.cafe/users/%s", user.Name),
Type: "text/html",
},
},
Icon: user.Picture,
Logo: user.Picture,
}
statuses, _, err := h.storage.StatusByUsername(user.Name, 20, 0)
if err != nil {
serverError(w, err)
return
}
for _, status := range statuses {
if err != nil {
serverError(w, err)
return
}
feed.Items = append(feed.Items, &feeds.Item{
Title: fmt.Sprintf("%s - %s", status.User, truncate(status.Content, 50)),
Link: &feeds.Link{Href: fmt.Sprintf("https://status.cafe/users/%s/%d", username, status.Id)},
Author: &feeds.Author{Name: user.Name},
Content: status.Content,
Created: status.CreatedAt,
})
feed.Entry = append(feed.Entry, createAtomEntryFromStatus(status))
}
atom, err := feed.ToAtom()
if err != nil {
serverError(w, err)
return
}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "application/atom+xml")
w.Write([]byte(atom))
var data []byte
data, err = xml.MarshalIndent(&feed, "", " ")
if err != nil {
serverError(w, err)
}
w.Write([]byte(xml.Header + string(data)))
}