v0.2.1 c196c81

view.go RawHistoryFolder

1package visual
2
3import (
4	"github.com/bnema/nefergui"
5)
6
7// V1 lock look: black screen, one centered monospace box with a white border,
8// masked input (bullets only). No clock, avatar or widgets. The view sees only
9// the typed-character count, never the secret.
10const (
11	cssScreen = "display:flex;flex-direction:column;align-items:center;justify-content:center;" +
12		"width:100%;height:100%;background-color:#000000;color:#ffffff;font-family:monospace;font-size:18px"
13	cssBox = "display:flex;flex-direction:column;align-items:center;border:2px solid #ffffff;" +
14		"padding:24px;min-width:320px;background-color:#000000"
15	cssLabel = "color:#ffffff"
16	// The input field: a visible white-underlined line, bullets plus a cursor.
17	cssMask = "color:#ffffff;min-height:28px;min-width:280px;margin-top:12px;padding:4px 8px;" +
18		"border-bottom:2px solid #ffffff"
19	cssHint = "color:#ffffff;margin-top:12px;min-height:22px"
20)
21
22// labelFor is the fixed, non-secret caption for the requested credential.
23func labelFor(p promptKind) string {
24	switch p {
25	case promptPIN:
26		return "PIN"
27	case promptFallback:
28		return "Password (PIN unavailable)"
29	case promptUnavailable:
30		return "Authentication unavailable"
31	case promptMore:
32		return "Password (again)"
33	case promptPassword:
34		return "Password"
35	}
36	return "Locked"
37}
38
39// hintFor is the minimal failure/busy line.
40func hintFor(s nefergui.LockStatus) string {
41	switch s {
42	case nefergui.LockBusy:
43		return "..."
44	case nefergui.LockFailed:
45		return "Denied"
46	}
47	return " "
48}
49
50// UnlockBox draws the centered box.
51func UnlockBox(root nefergui.Node, s nefergui.LockState, p promptKind) {
52	box := root.Column(nefergui.Class("box"), nefergui.Inline(cssBox))
53	box.Text(labelFor(p), nefergui.Key("label"), nefergui.Inline(cssLabel))
54	box.Text(s.Bullets()+"_", nefergui.Key("mask"), nefergui.Inline(cssMask))
55	box.Text(hintFor(s.Status), nefergui.Key("hint"), nefergui.Inline(cssHint))
56}
57
58// lockView builds the whole lock screen.
59func lockView(f *nefergui.Frame, s nefergui.LockState, p promptKind) {
60	UnlockBox(f.Root(nefergui.Class("screen"), nefergui.Inline(cssScreen)), s, p)
61}

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 2

Tags 9

↑↓ moveenter openesc close