Old project/workflow names and browser settings migrate on load; /funpack redirects to /fun. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016acRss69eH1235eRdFTZHY
52 lines
2.9 KiB
JavaScript
52 lines
2.9 KiB
JavaScript
// The welcome screen: shown the first time this browser opens the app, and from Help ▸ Welcome window.
|
|
import { composer as c } from "../../composer/composer.js";
|
|
import { list } from "../../shell/project.js";
|
|
|
|
const SEEN = "funui_welcomed";
|
|
const card = (title, sub, onClick) => c.tile.action({ title, sub, onClick });
|
|
|
|
export default {
|
|
id: "welcome",
|
|
mount: "menubar.right",
|
|
needs: ["project", "maintenance"],
|
|
setup({ app }) {
|
|
let win = null;
|
|
const seen = () => { try { return localStorage.getItem(SEEN) === "1"; } catch { return true; } };
|
|
const markSeen = () => { try { localStorage.setItem(SEEN, "1"); } catch { /* private window */ } };
|
|
// Saved projects, or a project file from disk: the same two ways File ▸ Load and Open recent offer.
|
|
const load = async () => {
|
|
let all = []; try { all = await list(); } catch (err) { return c.toast.warn({ text: err.message }); }
|
|
const items = [{ id: "__import__", label: "Import a project file…" }, ...all.map((r) => ({ id: r.id, label: r.name }))];
|
|
const id = await c.modal.choice({ title: "Load a project", items }).result;
|
|
if (!id) return;
|
|
if (id === "__import__") {
|
|
markSeen(); if (win) win.close("done");
|
|
return app.say("project.load");
|
|
}
|
|
try { await app.project.open(id); markSeen(); if (win) win.close("done"); } catch (err) { c.toast.warn({ text: err.message }); }
|
|
};
|
|
const open = () => {
|
|
if (win) return;
|
|
const recent = app.project.project;
|
|
const done = () => { markSeen(); if (win) win.close("done"); };
|
|
const tiles = c.grid.pair({ children: [
|
|
card("Update", "Pull the newest version from origin, install missing requirements and restart ComfyUI (after a running generation finishes)", () => app.maintenance.update()), card("Switch branch", "Pick another branch", () => app.maintenance.switchBranch()),
|
|
card("Restart ComfyUI", "Reload the server without updating", () => app.maintenance.restart()), card("Rollback update", "Undo the last update", () => app.maintenance.rollback())] });
|
|
win = c.modal.generic({
|
|
title: "Welcome to FunUI", size: "lg",
|
|
body: c.region.stack({ gap: "md", children: [
|
|
c.hint.default({ text: "Multi-scene video on a real timeline." }),
|
|
c.button.lg({ label: "Begin", tone: "primary", onClick: done }),
|
|
...(recent ? [c.button.md({ label: `Continue with “${recent.name}”`, onClick: done })] : []),
|
|
c.button.md({ label: "Load an existing project", tone: "ghost", onClick: load }),
|
|
tiles,
|
|
] }),
|
|
onClose: () => { markSeen(); win = null; },
|
|
});
|
|
};
|
|
const timer = seen() ? 0 : setTimeout(open, 600); // after the first paint, so the screen it sits over is already there
|
|
const off = app.on((what) => { if (what === "welcome.open") open(); });
|
|
return () => { clearTimeout(timer); off(); };
|
|
},
|
|
};
|