1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
package components
import (
"time"
g "go.alanpearce.eu/gomponents"
. "go.alanpearce.eu/gomponents/html"
"go.alanpearce.eu/searchix/internal/config"
)
func SearchForm(tdata TemplateData, r ResultData) g.Node {
return Search(Form(
ID("search"),
FieldSet(
Legend(
ID("legend"),
H2(g.Textf("%s search", sourceNameAndType(tdata.Source))),
),
Input(
ID("query"),
Aria("labelledby", "legend"),
Name("query"),
Type("search"),
Value(r.Query),
AutoFocus(),
g.Attr("spellcheck", "false"),
g.Attr("autocapitalize", "none"),
),
Button(g.Text("Search")),
),
))
}
func SearchPage(tdata TemplateData, r ResultData, children ...g.Node) g.Node {
return Page(
tdata,
P(
g.Text("Search Nix packages and options from "),
MapCommaList(tdata.Sources, func(source *config.Source) g.Node {
return A(Href(source.Repo.String()), g.Text(source.Name))
}),
),
g.If(Indexing.InProgress,
P(Class("notice"),
g.Text("Indexing in progress, started "),
Time(
DateTime(Indexing.StartedAt.Format(time.RFC3339)),
Title(Indexing.StartedAt.Format(time.RFC3339)),
g.Text(time.Since(Indexing.StartedAt).Round(time.Second).String()),
),
g.Text(" ago. "),
g.If(!Indexing.FinishedAt.IsZero(),
g.Text("Last run took "),
Time(
DateTime(Indexing.FinishedAt.Format(time.RFC3339)),
Title(Indexing.FinishedAt.Format(time.RFC3339)),
g.Text(time.Since(Indexing.FinishedAt).Round(time.Minute).String()),
),
),
),
P(
g.Text("Indexing last ran "),
Time(
DateTime(Indexing.FinishedAt.Format(time.RFC3339)),
Title(Indexing.FinishedAt.Format(time.RFC3339)),
g.Text(time.Since(Indexing.FinishedAt).Round(time.Minute).String()),
),
g.Text(" ago, will run again in "),
Time(
DateTime(Indexing.NextRun.Format(time.RFC3339)),
Title(Indexing.NextRun.Format(time.RFC3339)),
g.Text(time.Until(Indexing.NextRun).Round(time.Minute).String()),
),
g.Text("."),
),
),
script(tdata.Assets.ByPath["/static/search.js"]),
SearchForm(tdata, r),
Section(
ID("results"),
Role("list"),
Aria("label", "search results"),
g.Group(children),
),
Dialog(
ID("dialog"),
Button(AutoFocus(), g.Text("Close")),
),
NoScript(
P(
Class("notice"),
g.Text("Everything should work fine without JavaScript. If that is not the case, "),
A(Href("https://todo.sr.ht/~alanpearce/searchix"), g.Text("report an issue")),
),
),
)
}
func MapCommaList[T any](items []T, fn func(T) g.Node) g.Node {
out := make([]g.Node, (len(items) * 2))
j := 0
last := len(items) - 2
for i := range items {
out[j] = fn(items[i])
j++
if i <= last {
if i == last {
out[j] = g.Text(" and ")
} else {
out[j] = g.Text(", ")
}
}
j++
}
return g.Group(out)
}
|