various changes
This commit is contained in:
parent
5f97675216
commit
79d73d12f5
12 changed files with 163 additions and 77 deletions
BIN
assets/favicon.ico
Normal file
BIN
assets/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 132 B |
|
|
@ -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
1
go.mod
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 }}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue