v0.23.0 333c710

components.templ RawHistoryFolder

1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package web
4
5// Facts is a key/value block on an 11ch key column.
6templ Facts(facts []Fact) {
7	<dl class="kv">
8		for _, f := range facts {
9			<dt>{ f.Key }</dt>
10			@FactValue(f)
11		}
12	</dl>
13}
14
15// CloneBlock is a block of copyable shell lines; each has its own [copy]
16// button, whose label says "copied" for 1.5 s.
17templ CloneBlock(c Clone) {
18	<div class="clone" id={ c.ID }>
19		for _, line := range c.Lines {
20			<div class="clone-line">
21				<span class="mute" aria-hidden="true">$ </span><code>{ line }</code>
22				<button
23					type="button"
24					class="btn copy"
25					data-js
26					data-label="Copy"
27					aria-label={ "copy: " + line }
28					hx-on:click="ermite.copy(this)"
29				>Copy</button>
30			</div>
31		}
32	</div>
33}
34
35// HomeRowView is the row of a repository in the home list: what it is, its
36// latest run, and its newest commits. Its id is the target of SSE swaps; the
37// name link comes first, `enter` follows it.
38templ HomeRowView(r HomeRow) {
39	<li id={ r.ID } class="repo" data-cursor?={ r.Cursor }>
40		<div class="repo-main">
41			<h2 class="repo-name">
42				<a href={ templ.SafeURL(r.Href) }>{ r.Name }</a>
43				if r.Private {
44					<span class="pill">private</span>
45				}
46				if r.Fresh {
47					<span class="pill new">new push</span>
48				}
49			</h2>
50			if r.Desc != "" {
51				<p class="repo-desc">{ r.Desc }</p>
52			} else {
53				<p class="repo-desc mute">no description</p>
54			}
55			<dl class="repo-stats" aria-label={ "Figures of " + r.Name }>
56				if s := r.Stats; s != nil {
57					<div><dt>commits</dt><dd>{ s.Commits }</dd></div>
58					<div><dt>last 30 days</dt><dd>{ s.Recent }</dd></div>
59					if s.Tag != "" {
60						<div>
61							<dt>latest tag</dt>
62							if s.TagHref != "" {
63								<dd><a href={ templ.SafeURL(s.TagHref) } title={ "made " + s.TagWhen }>{ s.Tag }</a></dd>
64							} else {
65								<dd title={ "made " + s.TagWhen }>{ s.Tag }</dd>
66							}
67						</div>
68					}
69				}
70				<div>
71					<dt>last activity</dt>
72					if r.ActiveAt != "" {
73						<dd><time datetime={ r.ActiveAt } title={ r.ActiveAt }>{ r.Active }</time></dd>
74					} else {
75						<dd class="mute">never</dd>
76					}
77				</div>
78			</dl>
79		</div>
80		if r.CI != nil {
81			<a class="repo-ci" href={ templ.SafeURL(r.CI.Href) } title={ r.CI.Title }>
82				<span class={ "ck", "ck-" + r.CI.Kind } aria-hidden="true"></span>
83				<span class="sr">CI: </span>{ r.CI.Label }
84			</a>
85		}
86		if len(r.Commits) > 0 {
87			<ul class="repo-commits" aria-label={ "Recent commits of " + r.Name }>
88				for _, c := range r.Commits {
89					<li>
90						<a class="rc-sha" href={ templ.SafeURL(c.CHref) }>{ c.Short }</a>
91						<span class="rc-subject" title={ c.Subject }>{ c.Subject }</span>
92						if c.WhenAt != "" {
93							<time class="dim" datetime={ c.WhenAt } title={ c.WhenAt }>{ c.When }</time>
94						}
95					</li>
96				}
97			</ul>
98		} else if r.NoCommits {
99			<p class="repo-commits mute">no commits yet</p>
100		}
101	</li>
102}
103
104// Outline is the README outline; levels indent by 2ch, the h1 is bold.
105templ Outline(headings []Heading) {
106	<nav class="outline" aria-label="Outline">
107		for _, h := range headings {
108			<a class={ "l" + itoa(h.Level) } href={ templ.SafeURL("#" + h.ID) }>{ h.Text }</a>
109		}
110	</nav>
111}
112
113// ReadmeCard is a README in a card whose header names the file.
114templ ReadmeCard(r Readme) {
115	<section class="card readme" aria-labelledby="readme-h">
116		<h2 class="card-h" id="readme-h">
117			<span class="ico i-file" aria-hidden="true"></span>
118			{ r.Name }
119		</h2>
120		@ReadmeView(r)
121	</section>
122}
123
124// ReadmeView is a rendered README. Its HTML comes from the Markdown
125// renderer, which drops raw HTML and filters URLs.
126templ ReadmeView(r Readme) {
127	<article class="prose" aria-label={ r.Name } hx-ignore>
128		if r.Note != "" {
129			<p class="dim">{ r.Note }</p>
130		} else {
131			@templ.Raw(r.HTML)
132		}
133	</article>
134}
135
136// CommitRows is a cursor table of commits: sha, subject with inline refs,
137// author, relative date (absolute in the title).
138templ CommitRows(rows []CommitRow) {
139	<table class="list commits" aria-label="Commits">
140		<tbody data-rows>
141			for _, c := range rows {
142				<tr
143					if c.ID != "" {
144						id={ c.ID }
145					}
146					data-cursor?={ c.Cursor }
147				>
148					<td class="c-sha mute">{ c.Short }</td>
149					<td class="c-subject">
150						<a href={ templ.SafeURL(c.CHref) }>{ c.Subject }</a>
151						if c.Merge {
152							<span class="pill">merge</span>
153						}
154						for _, b := range c.Branches {
155							<span class="pill">{ b }</span>
156						}
157						for _, t := range c.Tags {
158							<span class="pill tag"><span class="sr">tag </span>{ t }</span>
159						}
160					</td>
161					<td class="c-ck">@CommitChecks(c.Checks)</td>
162					<td class="c-who dim">{ c.Author }</td>
163					<td class="c-when nowrap dim"><time datetime={ c.WhenAt } title={ c.WhenAt }>{ c.When }</time></td>
164				</tr>
165			}
166		</tbody>
167	</table>
168}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 4

Tags 45

↑↓ moveenter openesc close