v0.20.1 d9a391f

ConfigShell.svelte RawHistoryFolder

1<script lang="ts">
2  import { onMount } from 'svelte';
3  import { Home } from '@lucide/svelte';
4
5  interface Props {
6    children?: import('svelte').Snippet;
7  }
8
9  let { children }: Props = $props();
10
11  function navigateWithViewTransition(url: string) {
12    const doc = document as any;
13
14    if (typeof doc?.startViewTransition !== 'function') {
15      window.location.href = url;
16      return;
17    }
18
19    const transition = doc.startViewTransition(() => {
20      document.documentElement.dataset.vt = 'leaving';
21    });
22
23    transition.finished.finally(() => {
24      window.location.href = url;
25    });
26  }
27
28  onMount(() => {
29    // Avoid default WebKit focus rings.
30    document.documentElement.dataset.vt = 'ready';
31  });
32</script>
33
34<svelte:head>
35  <title>dumb://config</title>
36  <meta name="description" content="Dumber Browser - Settings" />
37  {@html `<style>
38    html, body { margin: 0; padding: 0; }
39    html { background: var(--background, #0a0a0a); }
40    body { background: var(--background, #0a0a0a); color: var(--foreground, #e5e5e5); }
41    *:focus { outline: none !important; }
42    *:focus-visible { outline: none !important; }
43    button:focus, input:focus, a:focus { outline: none !important; box-shadow: none !important; }
44    * { -webkit-overflow-scrolling: touch; }
45  </style>`}
46</svelte:head>
47
48<div class="config-shell browser-ui">
49  <div class="terminal-frame">
50    <header class="terminal-header">
51      <div class="header-left">
52        <span class="terminal-path">dumb://config</span>
53      </div>
54      <div class="header-right">
55        <button
56          class="action-button"
57          type="button"
58          onclick={() => navigateWithViewTransition('dumb://home')}
59          title="Back to Home"
60        >
61          <Home size={14} strokeWidth={2} />
62          <span class="button-text">HOME</span>
63        </button>
64      </div>
65    </header>
66
67    <main class="terminal-body scrollable">
68      {#if children}
69        {@render children()}
70      {/if}
71    </main>
72
73    <footer class="terminal-footer">
74      <span class="footer-text">Dumber Browser</span>
75    </footer>
76  </div>
77</div>
78
79<style>
80  :global(html),
81  :global(body) {
82    height: 100%;
83  }
84
85  :global(body) {
86    overflow: hidden;
87    overscroll-behavior: contain;
88  }
89
90  .config-shell {
91    height: 100vh;
92    min-height: 100vh;
93    display: flex;
94    flex-direction: column;
95    font-family: ui-monospace, 'Fira Code', 'Cascadia Code', Menlo, Monaco, Consolas, monospace;
96    line-height: 1.5;
97    color: var(--foreground);
98    background: var(--background);
99    overflow: hidden;
100  }
101
102  .terminal-frame {
103    flex: 1;
104    display: grid;
105    grid-template-rows: auto 1fr auto;
106    width: 100%;
107    height: 100%;
108    background: color-mix(in srgb, var(--card) 60%, var(--background) 40%);
109  }
110
111  :global(.dark) .terminal-frame {
112    box-shadow: 0 24px 48px -12px rgb(0 0 0 / 0.5);
113  }
114
115  .terminal-header {
116    display: flex;
117    align-items: center;
118    justify-content: space-between;
119    gap: 1rem;
120    padding: 0.75rem 1rem;
121    min-height: 3.5rem;
122    border-bottom: 1px solid var(--border);
123    background: color-mix(in srgb, var(--background) 90%, var(--card) 10%);
124    position: sticky;
125    top: 0;
126    z-index: 5;
127  }
128
129  .header-left {
130    display: flex;
131    align-items: center;
132    gap: 1.5rem;
133  }
134
135  .terminal-path {
136    font-size: 0.8rem;
137    font-weight: 600;
138    color: var(--primary, #4ade80);
139    letter-spacing: 0.05em;
140  }
141
142  .header-right {
143    display: flex;
144    align-items: center;
145    gap: 0.5rem;
146  }
147
148  .action-button {
149    display: flex;
150    align-items: center;
151    gap: 0.5rem;
152    padding: 0.4rem 0.75rem;
153    font-size: 0.7rem;
154    font-weight: 500;
155    letter-spacing: 0.08em;
156    color: var(--muted-foreground);
157    background: transparent;
158    border-width: 1px;
159    border-style: solid;
160    border-color: var(--border);
161    cursor: pointer;
162    transition: all 120ms ease;
163  }
164
165  .action-button:hover,
166  .action-button:focus-visible {
167    color: var(--foreground);
168    border-color: color-mix(in srgb, var(--border) 50%, var(--foreground) 50%);
169    background: color-mix(in srgb, var(--card) 30%, transparent);
170    outline: none;
171  }
172
173  .terminal-body {
174    display: flex;
175    flex-direction: column;
176    min-height: 0;
177    overflow: hidden;
178    background: var(--background);
179  }
180
181  .terminal-body.scrollable {
182    overflow-y: auto;
183    -webkit-overflow-scrolling: touch;
184    touch-action: pan-y;
185  }
186
187  .terminal-footer {
188    display: flex;
189    align-items: center;
190    justify-content: center;
191    padding: 0.75rem 1rem;
192    border-top: 1px solid var(--border);
193    background: color-mix(in srgb, var(--background) 92%, var(--card) 8%);
194  }
195
196  .footer-text {
197    font-size: 0.7rem;
198    letter-spacing: 0.08em;
199    color: var(--muted-foreground);
200  }
201
202  /* View Transition helpers */
203  :global(html[data-vt='leaving']) {
204    view-transition-name: config-root;
205  }
206
207  :global(::view-transition-old(config-root)) {
208    animation: vt-fade-out 180ms ease both;
209  }
210
211  :global(::view-transition-new(config-root)) {
212    animation: vt-fade-in 220ms ease both;
213  }
214
215  @keyframes vt-fade-out {
216    to {
217      opacity: 0;
218      transform: translateY(6px);
219    }
220  }
221
222  @keyframes vt-fade-in {
223    from {
224      opacity: 0;
225      transform: translateY(-6px);
226    }
227  }
228</style>

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 8

Tags 42

↑↓ moveenter openesc close