the output is a console, and it clears itself when it worked
pre/code on black. it is quoting a terminal, so it should look like one — as a tinted paragraph it read as part of the form, which is exactly what it is not. IT CLOSES ITSELF ON SUCCESS, after five seconds, and NEVER on failure. a successful clone or update is worth watching and not worth keeping. "74 packages installed" has been read by the time it finishes, and left on screen it becomes furniture that outlives its own truth — still sitting there after the root has been changed underneath it. a failure is the opposite, and gets no timer at all rather than a long one. it is the only copy of why, and a transcript that scrolled past is one somebody has to reproduce in order to read. nothing takes it off the screen except the next attempt. same `useFlash` as the Saved indicator, so there is one timer implementation and one number, and the clear-the-previous-timeout property comes along with it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -35,7 +35,7 @@ import type { PluginManifest } from '@@/plugins/manifest';
|
||||
*/
|
||||
export const manifest: PluginManifest = {
|
||||
publisher: 'officerdev',
|
||||
version: '2026.08.29.11',
|
||||
version: '2026.08.29.12',
|
||||
platform: '>=1.0.0',
|
||||
|
||||
label: 'Fofos',
|
||||
|
||||
+20
-9
@@ -3,6 +3,7 @@ import { CircleAlert, CircleCheck, CircleDashed, DownloadCloud, Loader2, Refresh
|
||||
import { useClient } from 'hooks/useClient';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { readableError } from './errors';
|
||||
import { useFlash } from './useFlash';
|
||||
|
||||
/**
|
||||
* The website checkout under the root location: is it there, clone it, update it.
|
||||
@@ -18,6 +19,15 @@ import { readableError } from './errors';
|
||||
* "Permission denied (publickey)" says exactly what is wrong. Anything this could write in its place
|
||||
* would be a guess at which of a dozen causes it was, and the guess is what sends somebody looking in
|
||||
* the wrong direction.
|
||||
*
|
||||
* ── The console closes itself on success, and never on failure ──
|
||||
*
|
||||
* A successful clone or update is worth WATCHING and not worth keeping: "74 packages installed" has
|
||||
* been read by the time it finishes, and left on screen it becomes furniture that outlives its own
|
||||
* truth — still sitting there after the root has been changed underneath it.
|
||||
*
|
||||
* A failure is the opposite. It stays until something else happens, because it is the only copy of
|
||||
* why, and a transcript that scrolled past is one somebody has to reproduce to read.
|
||||
*/
|
||||
|
||||
type Status = {
|
||||
@@ -42,6 +52,7 @@ export const WebsiteCheckout = ({ rootPath }: { rootPath: string }) => {
|
||||
const [busy, setBusy] = useState<'clone' | 'update' | null>(null);
|
||||
const [output, setOutput] = useState<string | null>(null);
|
||||
const [failed, setFailed] = useState(false);
|
||||
const [showing, show] = useFlash();
|
||||
|
||||
const load = useCallback(async () => {
|
||||
try {
|
||||
@@ -68,6 +79,9 @@ export const WebsiteCheckout = ({ rootPath }: { rootPath: string }) => {
|
||||
setStatus(result.status);
|
||||
setOutput(result.output || null);
|
||||
setFailed(!result.ok);
|
||||
// Only on the way out. A failure has no timer at all rather than a long one — nothing should be
|
||||
// able to take it off the screen except the next attempt.
|
||||
if (result.ok) show();
|
||||
} catch (failure) {
|
||||
// A 400 carries git's own words in the body; `readableError` surfaces them.
|
||||
setOutput(readableError(failure));
|
||||
@@ -129,15 +143,12 @@ export const WebsiteCheckout = ({ rootPath }: { rootPath: string }) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* git's own words, in git's own shape. Scrolled rather than truncated — the useful line of a
|
||||
clone failure is usually the last one. */}
|
||||
{output && (
|
||||
<pre
|
||||
className={`max-h-32 overflow-auto rounded-md border border-border p-2 font-mono text-[11px] whitespace-pre-wrap ${
|
||||
failed ? 'text-destructive' : 'text-muted-foreground'
|
||||
}`}
|
||||
>
|
||||
{output}
|
||||
{/* git's own words, in git's own shape — a console, so it looks like the thing it is quoting
|
||||
rather than like a paragraph of the form. Scrolled, not truncated: the useful line of a
|
||||
failure is usually the last one. */}
|
||||
{output && (failed || showing) && (
|
||||
<pre className="max-h-40 overflow-auto rounded-md border border-border bg-black p-3 font-mono text-[11px] leading-relaxed whitespace-pre-wrap">
|
||||
<code className={failed ? 'text-red-400' : 'text-neutral-200'}>{output}</code>
|
||||
</pre>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user