about summary refs log tree commit diff stats
path: root/internal/components/search.go
blob: b4ef7bdf585427b6662737607747ac81ccc0d092 (plain)
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)
}