diff options
Diffstat (limited to 'internal/components/page.go')
-rw-r--r-- | internal/components/page.go | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/internal/components/page.go b/internal/components/page.go new file mode 100644 index 0000000..5cfa4ff --- /dev/null +++ b/internal/components/page.go @@ -0,0 +1,152 @@ +package components + +import ( + "net/url" + + "go.alanpearce.eu/searchix/frontend" + "go.alanpearce.eu/searchix/internal/config" + + g "go.alanpearce.eu/gomponents" + c "go.alanpearce.eu/gomponents/components" + . "go.alanpearce.eu/gomponents/html" +) + +func Page(tdata TemplateData, children ...g.Node) g.Node { + return Doctype( + HTML( + Lang("en-GB"), + Head( + Meta(Charset("utf-8")), + Meta(Name("viewport"), Content("width=device-width, initial-scale=1")), + TitleEl(g.Text("Searchix"), g.If(config.DevMode, g.Text(" (Dev)"))), + g.Map(tdata.Assets.Stylesheets, css), + g.Raw(tdata.ExtraHeadHTML), + Link( + Rel("search"), + Type("application/opensearchdescription+xml"), + TitleAttr("Searchix "+sourceNameAndType(nil)), + Href(joinPath("opensearch.xml")), + ), + g.Map(tdata.Sources, func(source *config.Source) g.Node { + return Link( + Rel("search"), + Type("application/opensearchdescription+xml"), + TitleAttr("Searchix "+sourceNameAndType(source)), + Href(joinPath("/", source.Importer.String(), source.Key, "opensearch.xml")), + ) + }), + ), + Body( + Header( + Nav( + H1(A(Href("/"), g.Text("Searchix"))), + A( + c.Classes{ + "current": tdata.Source == nil, + }, + g.If( + tdata.Source == nil, + Href("/"), + Href(joinPathQuery("/", tdata.Query)), + ), + g.Text("All"), + ), + g.Map(tdata.Sources, func(source *config.Source) g.Node { + if tdata.Source != nil && tdata.Source.Name == source.Name { + return A( + Class("current"), + Href( + joinPath( + "/", + source.Importer.String(), + source.Key, + "search", + ), + ), + g.Text(source.Name), + ) + } + + return A( + Href( + joinPathQuery( + joinPath( + "/", + source.Importer.String(), + source.Key, + "search", + ), + tdata.Query, + ), + ), + g.Text(source.Name), + ) + }), + ), + ), + Main(children...), + Footer( + g.If(config.Version != "", + g.Group([]g.Node{ + g.Text("Searchix "), + A( + Href("https://git.sr.ht/~alanpearce/searchix/refs/"+config.Version), + g.Text(config.Version), + ), + }), + ), + g.Text("Made by "), + A(Href("https://alanpearce.eu"), g.Text("Alan Pearce")), + g.Text(". "), + A(Href("https://git.sr.ht/~alanpearce/searchix"), g.Text("Source code")), + A(Href("https://todo.sr.ht/~alanpearce/searchix"), g.Text("Report issues")), + ), + ), + ), + ) +} + +func css(css *frontend.Asset) g.Node { + return Link(Href(css.URL), Rel("stylesheet"), + Integrity("sha256-"+css.Base64SHA256)) +} + +func script(s *frontend.Asset) g.Node { + return Script( + Src(s.URL), + Defer(), + g.Attr("integrity", "sha256-"+s.Base64SHA256), + ) +} + +func sourceNameAndType(source *config.Source) string { + if source == nil { + return "Combined" + } + + switch source.Importer { + case config.Options: + return source.Name + " " + source.Importer.String() + case config.Packages: + return source.Name + } + + return "" +} + +func joinPath(base string, parts ...string) string { + u, err := url.JoinPath(base, parts...) + if err != nil { + panic(err) + } + + return u +} + +func joinPathQuery(path string, query string) string { + if query == "" { + return path + } + + return path + "?query=" + url.QueryEscape(query) +} |