diff --git a/app/ui/features/menus/index.js b/app/ui/features/menus/index.js index 9f1431d5..f1f5d5be 100644 --- a/app/ui/features/menus/index.js +++ b/app/ui/features/menus/index.js @@ -50,6 +50,7 @@ export default { add: () => { const sc = p.edit((pr) => edits.addScene(pr)); if (sc) p.select(sc.id); }, del: () => sel.ids.forEach((id) => p.edit((pr) => edits.removeScene(pr, id))), left: () => move(-1), right: () => move(1), + refresh: () => app.say("preview.refresh"), reset: () => app.resetLayout(), welcome: () => app.say("welcome.open"), exclude: () => { const sc = p.selected; if (sc) p.setScene(sc.id, "excluded", !sc.excluded); }, @@ -66,7 +67,7 @@ export default { { id: "add", label: "Add Scene", disabled: !p.project }, { id: "del", label: "Delete Scene", disabled: !sel.ids.length }, { separator: true }, { id: "left", label: "Move Clip Left", hint: "timeline cut", disabled: !sel.focus }, { id: "right", label: "Move Clip Right", hint: "timeline cut", disabled: !sel.focus }, { separator: true }, { id: "exclude", label: "Toggle Exclude", disabled: !sel.focus }], - View: () => [soon("Refresh Preview", ""), { id: "reset", label: "Reset Layout" }], + View: () => [{ id: "refresh", label: "Refresh Preview" }, { id: "reset", label: "Reset Layout" }], Help: () => [soon("Restart tour", ""), soon("Skip to FAQ", ""), soon("Exit tour", ""), { separator: true }, { id: "welcome", label: "Welcome tour…" }], }; const pick = (id) => (id.startsWith("open:") ? p.open(id.slice(5)) : actions[id] && actions[id]()); diff --git a/app/ui/features/preview/index.js b/app/ui/features/preview/index.js index 37106b50..2d0abe59 100644 --- a/app/ui/features/preview/index.js +++ b/app/ui/features/preview/index.js @@ -104,6 +104,7 @@ export default { else if (what === "play.toggle") (playing ? pause() : start()); else if (what === "play.start") start(); else if (what === "play.pause") pause(); + else if (what === "preview.refresh") { shown = ""; sync(); } // show the clip again from its file else if (what === "open") { pause(); head.set(0); } // another project: nothing carries over else sync(); })]; diff --git a/app/ui/features/welcome/index.js b/app/ui/features/welcome/index.js index a4adf996..7cf22e55 100644 --- a/app/ui/features/welcome/index.js +++ b/app/ui/features/welcome/index.js @@ -1,5 +1,6 @@ // The welcome screen: shown the first time this browser opens the app, and from Help ▸ Welcome tour. import { composer as c } from "../../composer/composer.js"; +import { list } from "../../shell/project.js"; const SEEN = "funpack_welcomed"; const card = (title, hint, onClick) => c.field.default({ label: title, hint, control: c.button.sm({ label: title, tone: "ghost", onClick }) }); @@ -12,6 +13,13 @@ export default { let win = null; const seen = () => { try { return localStorage.getItem(SEEN) === "1"; } catch { return true; } }; const markSeen = () => { try { localStorage.setItem(SEEN, "1"); } catch { /* private window */ } }; + const load = async () => { + let all; try { all = await list(); } catch (err) { return c.toast.warn({ text: err.message }); } + if (!all.length) return c.toast.warn({ text: "There are no saved projects yet." }); + const id = await c.modal.choice({ title: "Load a project", items: all.map((r) => ({ id: r.id, label: r.name })) }).result; + if (!id) return; + 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; @@ -22,7 +30,7 @@ export default { c.hint.default({ text: "Multi-scene video on a real timeline." }), c.button.lg({ label: "Begin", tone: "primary", onClick: done }), ...(recent ? [c.button.sm({ label: `Continue with “${recent.name}”`, tone: "ghost", onClick: done })] : []), - c.button.sm({ label: "Load an existing project", tone: "ghost", disabled: true }), + c.button.sm({ label: "Load an existing project", tone: "ghost", onClick: load }), c.toolbar.default({ items: [card("Update", "Check this install for a newer version", () => 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())] }), ] }),