package html
import (
"embed"
"encoding/json"
"fmt"
"html/template"
"io"
"log"
"time"
"github.com/Jaculabilis/intake/core"
)
func rawHtml(str string) template.HTML {
return template.HTML(str)
}
func dateFormat(tm time.Time) string {
return tm.Format(time.DateTime)
}
func tsToDate(t int) time.Time {
return time.Unix(int64(t), 0).UTC()
}
func until(tm time.Time) string {
now := time.Now() // TODO pass this value in
dur := tm.Sub(now).Round(time.Second)
var format string
if dur < 0 {
format = "%s ago"
dur = dur.Abs()
} else {
format = "in %s"
}
var length string
if dur.Hours() > 24 {
length = fmt.Sprintf("%dd", int(dur.Hours()/24))
} else {
length = dur.String()
}
return fmt.Sprintf(format, length)
}
func massDeactivateVals(items []core.Item) string {
var shorts []string
for _, item := range items {
shorts = append(shorts, core.FormatAsShort(item))
}
massDeac := struct {
Items []string `json:"items"`
}{shorts}
vals, err := json.Marshal(massDeac)
if err != nil {
log.Printf("error serializing mass deactivate list: %v", err)
}
return string(vals)
}
func page(i int, delta int) int {
i = i + delta
if i < 1 {
return 1
}
return i
}
var funcs = template.FuncMap{
"raw": rawHtml,
"dateFormat": dateFormat,
"tsToDate": tsToDate,
"until": until,
"massDeacVars": massDeactivateVals,
"page": page,
}
//go:embed intake.css
var Stylesheet []byte
//go:embed htmx.org@2.0.4.js
var Htmx []byte
//go:embed *.html
var templates embed.FS
func load(files ...string) *template.Template {
files = append([]string{"layout.html"}, files...)
return template.Must(template.New("layout.html").Funcs(funcs).ParseFS(templates, files...))
}
var home = load("home.html")
type ChannelData struct {
Name string
Active int
}
type SourceData struct {
Name string
}
type HomeData struct {
Channels []ChannelData
Sources []SourceData
}
func Home(writer io.Writer, data HomeData) {
if err := home.Execute(writer, data); err != nil {
log.Printf("error: failed to render home: %v", err)
}
}
var feed = load("feed.html", "item.html")
type FeedData struct {
Items []core.Item
ShowHidden int
Page int
Count int
}
func Feed(writer io.Writer, data FeedData) {
if err := feed.Execute(writer, data); err != nil {
log.Printf("error: failed to render feed: %v", err)
}
}
var item = load("itemPage.html", "item.html")
type ItemData struct {
Item core.Item
}
func Item(writer io.Writer, data ItemData) {
if err := item.Execute(writer, data); err != nil {
log.Printf("error: failed to render item: %v", err)
}
}
var login = load("login.html")
type LoginData struct {
Error string
}
func Login(writer io.Writer, data LoginData) {
err := login.Execute(writer, data)
if err != nil {
log.Printf("error: failed to render login: %v", err)
}
}
var fetch = load("fetch.html")
type FetchData struct {
Source string
Added int
Updated int
Deleted int
Items []core.Item
}
func Fetch(writer io.Writer, data FetchData) {
if err := fetch.Execute(writer, data); err != nil {
log.Printf("error: failed to render fetch: %v", err)
}
}
var editChannels = load("editChannels.html")
type EditChannelsData struct {
Sources []string
ChannelSources map[string][]string
}
func EditChannels(writer io.Writer, data EditChannelsData) {
if err := editChannels.Execute(writer, data); err != nil {
log.Printf("error: failed to render edit channels: %v", err)
}
}
var editSource = load("editSource.html")
type EditSourceData struct {
Name string
Envs map[string]string
Actions map[string]string
}
func EditSource(writer io.Writer, data EditSourceData) {
if err := editSource.Execute(writer, data); err != nil {
log.Printf("error: failed to render edit source: %v", err)
}
}