@wizardingcode/shibaox-tui 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +8188 -0
- package/dist/main.js.map +67 -0
- package/package.json +9 -13
- package/src/app.tsx +0 -300
- package/src/component/dialogs/confirm.tsx +0 -29
- package/src/component/dialogs/diff.tsx +0 -143
- package/src/component/dialogs/help.tsx +0 -99
- package/src/component/dialogs/keys.tsx +0 -201
- package/src/component/dialogs/palette.tsx +0 -95
- package/src/component/dialogs/runs.tsx +0 -115
- package/src/component/dialogs/tiers.tsx +0 -240
- package/src/component/footer.tsx +0 -66
- package/src/component/logo.tsx +0 -29
- package/src/component/prompt/autocomplete.tsx +0 -44
- package/src/component/prompt/index.tsx +0 -213
- package/src/component/reconnecting.tsx +0 -44
- package/src/component/sidebar.tsx +0 -235
- package/src/component/tabs.tsx +0 -116
- package/src/component/too-small.tsx +0 -15
- package/src/context/client.tsx +0 -54
- package/src/context/commands.tsx +0 -44
- package/src/context/config.tsx +0 -22
- package/src/context/data-state.ts +0 -41
- package/src/context/data.tsx +0 -308
- package/src/context/exit.tsx +0 -13
- package/src/context/keys.tsx +0 -70
- package/src/context/poller.ts +0 -352
- package/src/context/prefs.tsx +0 -54
- package/src/context/route.tsx +0 -23
- package/src/main.tsx +0 -55
- package/src/model/format.ts +0 -38
- package/src/model/prompt-commands.ts +0 -315
- package/src/model/status.ts +0 -55
- package/src/model/stream.ts +0 -464
- package/src/motion/animation.ts +0 -235
- package/src/motion/config.tsx +0 -15
- package/src/motion/fade-in-text.tsx +0 -93
- package/src/motion/masked-text.ts +0 -62
- package/src/motion/one-cell-motion.ts +0 -100
- package/src/motion/pulse.ts +0 -38
- package/src/motion/shimmer-text.tsx +0 -78
- package/src/motion/spinner-renderable.ts +0 -171
- package/src/motion/spinner.tsx +0 -100
- package/src/motion/subcell.ts +0 -40
- package/src/routes/home.tsx +0 -365
- package/src/routes/session/approval-bar.tsx +0 -136
- package/src/routes/session/cards.tsx +0 -495
- package/src/routes/session/context-line.tsx +0 -129
- package/src/routes/session/continue.tsx +0 -104
- package/src/routes/session/index.tsx +0 -340
- package/src/routes/session/request.tsx +0 -87
- package/src/routes/session/timeline.tsx +0 -313
- package/src/testing/fake-client.ts +0 -249
- package/src/theme/context.tsx +0 -44
- package/src/theme/resolve.ts +0 -196
- package/src/theme/shibaox.json +0 -159
- package/src/ui/border.ts +0 -20
- package/src/ui/delayed-presence.ts +0 -23
- package/src/ui/dialog.tsx +0 -123
- package/src/ui/layout.ts +0 -23
- package/src/ui/marquee.ts +0 -75
- package/src/ui/pane-resize.ts +0 -77
- package/src/ui/toast.tsx +0 -203
- package/tsconfig.json +0 -19
package/src/ui/toast.tsx
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
// Adapted from opencode (MIT) — https://github.com/anomalyco/opencode
|
|
2
|
-
import { TextAttributes } from '@opentui/core';
|
|
3
|
-
import { useTerminalDimensions } from '@opentui/solid';
|
|
4
|
-
import {
|
|
5
|
-
type Accessor,
|
|
6
|
-
createContext,
|
|
7
|
-
createSignal,
|
|
8
|
-
type JSX,
|
|
9
|
-
onCleanup,
|
|
10
|
-
type ParentProps,
|
|
11
|
-
Show,
|
|
12
|
-
useContext,
|
|
13
|
-
} from 'solid-js';
|
|
14
|
-
import { useTheme } from '../theme/context.js';
|
|
15
|
-
import type { Feedback } from '../theme/resolve.js';
|
|
16
|
-
import { SplitBorder } from './border.js';
|
|
17
|
-
|
|
18
|
-
export interface ToastOptions {
|
|
19
|
-
title?: string;
|
|
20
|
-
message: string;
|
|
21
|
-
variant: Feedback;
|
|
22
|
-
duration: number;
|
|
23
|
-
action?: { label: string; run: () => void };
|
|
24
|
-
}
|
|
25
|
-
export type ToastInput = Omit<ToastOptions, 'duration'> & { duration?: number };
|
|
26
|
-
|
|
27
|
-
export interface ToastApi {
|
|
28
|
-
show(t: ToastInput): void;
|
|
29
|
-
error(e: unknown): void;
|
|
30
|
-
pause(): void;
|
|
31
|
-
resume(): void;
|
|
32
|
-
dismiss(): void;
|
|
33
|
-
activate(): void;
|
|
34
|
-
current: Accessor<ToastOptions | undefined>;
|
|
35
|
-
pending: Accessor<number>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const DEFAULT_MS = 5000;
|
|
39
|
-
|
|
40
|
-
function ToastSurface(props: { toast: ToastOptions; pending: number; api: ToastApi }): JSX.Element {
|
|
41
|
-
const theme = useTheme().surface('toast');
|
|
42
|
-
const dimensions = useTerminalDimensions();
|
|
43
|
-
const [hovered, setHovered] = createSignal(false);
|
|
44
|
-
const hover = (v: boolean) => {
|
|
45
|
-
setHovered(v);
|
|
46
|
-
if (v) props.api.pause();
|
|
47
|
-
else props.api.resume();
|
|
48
|
-
};
|
|
49
|
-
const affordance = () => (
|
|
50
|
-
<text
|
|
51
|
-
flexShrink={0}
|
|
52
|
-
marginLeft={2}
|
|
53
|
-
wrapMode="none"
|
|
54
|
-
attributes={hovered() && props.toast.action ? TextAttributes.BOLD : undefined}
|
|
55
|
-
fg={hovered() ? theme.text.action.primary.selected : theme.text.muted}
|
|
56
|
-
>
|
|
57
|
-
{props.toast.action ? `› ${props.toast.action.label}` : 'x'}
|
|
58
|
-
</text>
|
|
59
|
-
);
|
|
60
|
-
return (
|
|
61
|
-
<box
|
|
62
|
-
position="absolute"
|
|
63
|
-
top={1}
|
|
64
|
-
right={2}
|
|
65
|
-
zIndex={4000}
|
|
66
|
-
maxWidth={Math.min(60, dimensions().width - 6)}
|
|
67
|
-
borderColor={theme.text.feedback[props.toast.variant]}
|
|
68
|
-
border={SplitBorder.border}
|
|
69
|
-
customBorderChars={SplitBorder.customBorderChars}
|
|
70
|
-
onMouseOver={() => hover(true)}
|
|
71
|
-
onMouseOut={() => hover(false)}
|
|
72
|
-
onMouseUp={() => props.api.activate()}
|
|
73
|
-
>
|
|
74
|
-
<box
|
|
75
|
-
width="100%"
|
|
76
|
-
paddingLeft={2}
|
|
77
|
-
paddingRight={2}
|
|
78
|
-
paddingTop={1}
|
|
79
|
-
paddingBottom={1}
|
|
80
|
-
backgroundColor={theme.background.raised.high}
|
|
81
|
-
>
|
|
82
|
-
<Show
|
|
83
|
-
when={props.toast.title}
|
|
84
|
-
fallback={
|
|
85
|
-
<box flexDirection="row" width="100%">
|
|
86
|
-
<text fg={theme.text.base} wrapMode="word" flexGrow={1}>
|
|
87
|
-
{props.toast.message}
|
|
88
|
-
</text>
|
|
89
|
-
{affordance()}
|
|
90
|
-
</box>
|
|
91
|
-
}
|
|
92
|
-
>
|
|
93
|
-
<box flexDirection="row" width="100%" marginBottom={1}>
|
|
94
|
-
<text attributes={TextAttributes.BOLD} fg={theme.text.base}>
|
|
95
|
-
{props.toast.title ?? ''}
|
|
96
|
-
</text>
|
|
97
|
-
<box flexGrow={1} />
|
|
98
|
-
{affordance()}
|
|
99
|
-
</box>
|
|
100
|
-
<text fg={theme.text.base} wrapMode="word" width="100%">
|
|
101
|
-
{props.toast.message}
|
|
102
|
-
</text>
|
|
103
|
-
</Show>
|
|
104
|
-
<Show when={props.pending > 0}>
|
|
105
|
-
<text fg={theme.text.muted} marginTop={1}>{`+${props.pending} more`}</text>
|
|
106
|
-
</Show>
|
|
107
|
-
</box>
|
|
108
|
-
</box>
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/** Draws the current toast (top-right); mount it once, above everything else. */
|
|
113
|
-
export function Toast(): JSX.Element {
|
|
114
|
-
const api = useToast();
|
|
115
|
-
return (
|
|
116
|
-
<Show when={api.current()}>
|
|
117
|
-
{(current) => <ToastSurface toast={current()} pending={api.pending()} api={api} />}
|
|
118
|
-
</Show>
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function init(): ToastApi {
|
|
123
|
-
// signals, not a store: a store would merge the next toast into the current one
|
|
124
|
-
const [current, setCurrent] = createSignal<ToastOptions | undefined>(undefined);
|
|
125
|
-
const [queue, setQueue] = createSignal<ToastOptions[]>([]);
|
|
126
|
-
let timeout: NodeJS.Timeout | undefined;
|
|
127
|
-
let startedAt = 0;
|
|
128
|
-
let remaining = 0;
|
|
129
|
-
let paused = false;
|
|
130
|
-
|
|
131
|
-
const clear = () => {
|
|
132
|
-
if (timeout) clearTimeout(timeout);
|
|
133
|
-
timeout = undefined;
|
|
134
|
-
};
|
|
135
|
-
const start = (duration: number) => {
|
|
136
|
-
clear();
|
|
137
|
-
remaining = duration;
|
|
138
|
-
startedAt = Date.now();
|
|
139
|
-
timeout = setTimeout(() => dismiss(), duration);
|
|
140
|
-
timeout.unref?.();
|
|
141
|
-
};
|
|
142
|
-
const dismiss = () => {
|
|
143
|
-
clear();
|
|
144
|
-
const next = queue()[0];
|
|
145
|
-
setQueue((q) => q.slice(1));
|
|
146
|
-
setCurrent(next);
|
|
147
|
-
if (!next) {
|
|
148
|
-
paused = false;
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
remaining = next.duration;
|
|
152
|
-
if (!paused) start(next.duration);
|
|
153
|
-
};
|
|
154
|
-
const api: ToastApi = {
|
|
155
|
-
show(input) {
|
|
156
|
-
const t: ToastOptions = { ...input, duration: input.duration ?? DEFAULT_MS };
|
|
157
|
-
if (current()) {
|
|
158
|
-
setQueue((q) => [...q, t]);
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
setCurrent(t);
|
|
162
|
-
start(t.duration);
|
|
163
|
-
},
|
|
164
|
-
error(e) {
|
|
165
|
-
api.show({ variant: 'error', message: e instanceof Error ? e.message : String(e) });
|
|
166
|
-
},
|
|
167
|
-
pause() {
|
|
168
|
-
if (!current() || paused) return;
|
|
169
|
-
paused = true;
|
|
170
|
-
remaining = Math.max(0, remaining - (Date.now() - startedAt));
|
|
171
|
-
clear();
|
|
172
|
-
},
|
|
173
|
-
resume() {
|
|
174
|
-
if (!current() || !paused) return;
|
|
175
|
-
paused = false;
|
|
176
|
-
start(remaining);
|
|
177
|
-
},
|
|
178
|
-
dismiss,
|
|
179
|
-
activate() {
|
|
180
|
-
const action = current()?.action;
|
|
181
|
-
paused = false; // the pointer is still over the spot; the next toast must expire on its own
|
|
182
|
-
dismiss();
|
|
183
|
-
action?.run();
|
|
184
|
-
},
|
|
185
|
-
current,
|
|
186
|
-
pending: () => queue().length,
|
|
187
|
-
};
|
|
188
|
-
onCleanup(clear);
|
|
189
|
-
return api;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const Context = createContext<ToastApi>();
|
|
193
|
-
|
|
194
|
-
export function ToastProvider(props: ParentProps): JSX.Element {
|
|
195
|
-
const value = init();
|
|
196
|
-
return <Context.Provider value={value}>{props.children}</Context.Provider>;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
export function useToast(): ToastApi {
|
|
200
|
-
const value = useContext(Context);
|
|
201
|
-
if (!value) throw new Error('useToast outside ToastProvider');
|
|
202
|
-
return value;
|
|
203
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"strict": true,
|
|
5
|
-
"skipLibCheck": true,
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"resolveJsonModule": true,
|
|
8
|
-
"noUncheckedIndexedAccess": true,
|
|
9
|
-
"rootDir": ".",
|
|
10
|
-
"noEmit": true,
|
|
11
|
-
"jsx": "preserve",
|
|
12
|
-
"jsxImportSource": "@opentui/solid",
|
|
13
|
-
"module": "ESNext",
|
|
14
|
-
"moduleResolution": "bundler",
|
|
15
|
-
"types": ["bun", "node"],
|
|
16
|
-
"allowImportingTsExtensions": true
|
|
17
|
-
},
|
|
18
|
-
"include": ["src", "test", "test-vitest"]
|
|
19
|
-
}
|