diff --git a/web/html/feed.html b/web/html/feed.html new file mode 100644 index 0000000..b02b9a9 --- /dev/null +++ b/web/html/feed.html @@ -0,0 +1,75 @@ +{{ define "title" }}{{ if .Items }}({{ len .Items }}) {{ end }}Intake{{ end }} + +{{ define "buttons" -}} + + +{{- if .Link }} +{{ end -}} +{{ end }} + +{{ define "item-title" -}} +{{ or .Title .Id | raw }} +{{- end }} + +{{ define "content" -}} +
+ +Home +[Active | All] + +
+ +{{ if .Items }} +{{ range .Items }} +
+ + {{/* The item title is a clickable if there is body content */}} + {{ if .Body }} +
+ + {{ template "buttons" . }} + {{ template "item-title" . }} + + {{ if .Body }} +

{{ raw .Body }}

+ {{ end }} +
+ {{ template "buttons" . }} + {{ else }} + {{ template "buttons" . }} + {{ template "item-title" . }}
+ {{ end }} + {{/* end if .Body */}} + + {{/* author/time footer line */}} + {{ if or .Author .Time }} + + {{ .Author }} + {{ .Time | tsToDate }} +
+ {{ end }} + + {{/* source/id/created footer line */}} + + {{ .Source }}/{{ .Id }} + {{ .Created | tsToDate }} + + +
+{{ end }} +{{/* end range .Items */}} + +
+ +
+ +{{/* if .Items */}} +{{ else }} +
+ Feed is empty +
+{{ end }} +{{/* end if .Items */}} + +{{ end }} +{{/* end define "content" */}} diff --git a/web/html/html.go b/web/html/html.go index fd7fd8b..967e777 100644 --- a/web/html/html.go +++ b/web/html/html.go @@ -4,8 +4,23 @@ import ( "embed" "html/template" "io" + "time" ) +func rawHtml(str string) template.HTML { + return template.HTML(str) +} + +func tsToDate(t int) string { + tm := time.Unix(int64(t), 0).UTC() + return tm.Format(time.DateTime) +} + +var funcs = template.FuncMap{ + "raw": rawHtml, + "tsToDate": tsToDate, +} + //go:embed intake.css var Stylesheet []byte @@ -13,7 +28,7 @@ var Stylesheet []byte var templates embed.FS func load(file string) *template.Template { - return template.Must(template.New("layout.html").ParseFS(templates, "layout.html", file)) + return template.Must(template.New("layout.html").Funcs(funcs).ParseFS(templates, "layout.html", file)) } var home = load("home.html") @@ -21,3 +36,9 @@ var home = load("home.html") func Home(writer io.Writer, data any) error { return home.Execute(writer, data) } + +var feed = load("feed.html") + +func Feed(writer io.Writer, data any) error { + return feed.Execute(writer, data) +} diff --git a/web/html/intake.css b/web/html/intake.css index 2986bd9..1f2db51 100644 --- a/web/html/intake.css +++ b/web/html/intake.css @@ -8,6 +8,7 @@ article { padding: 5px; margin-bottom: 20px; word-break: break-word; + display: flow-root; } .item-title { font-size: 1.4em; @@ -28,6 +29,15 @@ article { .item-info { color: rgba(0, 0, 0, 0.7); } +details[open] > summary > .item-button, details[open] > summary > .item-link { + display: none; +} +details ~ .item-button, details ~ .item-link { + display: none; +} +details[open] ~ .item-button, details[open] ~ .item-link { + display: inline; +} article img { max-width: 100%; height: auto; diff --git a/web/main.go b/web/main.go index 95191d1..4d94022 100644 --- a/web/main.go +++ b/web/main.go @@ -29,6 +29,7 @@ func RunServer(db *core.DB, addr string, port string) { handleFunc("/", env.rootHandler) handleFunc("/style.css", env.styleHandler) + handleFunc("/source/", env.sourceHandler) log.Fatal(http.ListenAndServe(bind, nil)) } diff --git a/web/root.go b/web/root.go index f54d919..b50ce6b 100644 --- a/web/root.go +++ b/web/root.go @@ -31,5 +31,6 @@ func (env *Env) rootHandler(writer http.ResponseWriter, req *http.Request) { func (env *Env) styleHandler(writer http.ResponseWriter, req *http.Request) { writer.Header()["Cache-Control"] = []string{"public, max-age=86400"} + writer.Header()["Content-Type"] = []string{"text/css; charset=utf-8"} writer.Write(html.Stylesheet) } diff --git a/web/source.go b/web/source.go new file mode 100644 index 0000000..0d4f6a3 --- /dev/null +++ b/web/source.go @@ -0,0 +1,23 @@ +package web + +import ( + "net/http" + + "github.com/Jaculabilis/intake/core" + "github.com/Jaculabilis/intake/web/html" +) + +type FeedData struct { + Items []core.Item +} + +func (env *Env) sourceHandler(writer http.ResponseWriter, req *http.Request) { + source := req.URL.Path[len("/source/"):] + // TODO this needs to properly error if the source doesn't exist instead of just returning [] + items, err := core.GetAllItemsForSource(env.db, source) + if err != nil { + http.NotFound(writer, req) + return + } + html.Feed(writer, FeedData{items}) +}