Two pieces of the "port v4's exact UI onto v5's backend" plan: - core/contract.py: new optional ModuleSpec.category field (closed set: continuity, guidance, conditioning, sampling, post, system), validated in core/schema.py, threaded through core/registry.py's FIELDS and to_manifest(). Presentation grouping, independent of STAGE (execution order) -- a module can be stage="sampling" and category="guidance" at once. Only the 4 existing modules that actually render a settings panel (alg, sharpen, appearance, full_control) got a category assigned; the other 12 have none to categorize (no SETTINGS block) and stay uncategorised, which is valid. - v4's frontend (movie_editor/frontend/*, ~29k lines, 61 files) copied verbatim into app/legacy/. core/routes.py's "/" route now serves legacy/index.html instead of the composer entry point; a <base> tag in that file resolves its own relative script/link tags against /funpack/app/legacy/ regardless of what URL it's served at, so every file moved as a unit with zero per-file path edits. Verified live: all 61 assets load 200 OK, the real v4 onboarding screen renders pixel-for- pixel (it's the actual DOM/CSS, not a reimplementation), and several v4 API calls (/api/media, /api/projects, /api/git/status) already succeed against v5's real backend by coincidence of shared route naming -- the rest 404/405 as expected, since api.js's ~90 functions haven't been rewired to v5's actual routes yet (next piece of this plan). The old composer entry point (app/index.html, app/composer/**) stays in the tree, unreferenced, until a later cleanup pass once nothing imports it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
66 lines
2.4 KiB
JavaScript
66 lines
2.4 KiB
JavaScript
// Two faces of one app. "simple" is what Easy Gen used to be — prompt, Generate, result,
|
|
// and nothing that needs explaining. "editor" is the full cutting room. Same store, same
|
|
// pipeline, same project file: only what is on screen differs.
|
|
//
|
|
// Stamped on <html> as data-ui-mode so most of the hiding is CSS, and read at render time
|
|
// by the panels that have to build different content rather than hide some of it.
|
|
(function () {
|
|
const KEY = "funpack_ui_mode";
|
|
const MODES = ["simple", "editor"];
|
|
const listeners = new Set();
|
|
|
|
function stored() {
|
|
try {
|
|
const v = localStorage.getItem(KEY);
|
|
return MODES.includes(v) ? v : null;
|
|
} catch (_) { return null; }
|
|
}
|
|
|
|
// No stored choice: the URL decides once, so an Easy Gen bookmark still lands in the
|
|
// mode it promised. Everything after that is the toggle.
|
|
function initial() {
|
|
const s = stored();
|
|
if (s) return s;
|
|
try {
|
|
const q = new URLSearchParams(window.location.search).get("mode");
|
|
if (MODES.includes(q)) return q;
|
|
if (/\/easy\/?$/.test(window.location.pathname)) return "simple";
|
|
} catch (_) {}
|
|
return "editor";
|
|
}
|
|
|
|
let mode = initial();
|
|
|
|
function stamp() { document.documentElement.setAttribute("data-ui-mode", mode); }
|
|
|
|
function get() { return mode; }
|
|
function is(m) { return mode === m; }
|
|
function isSimple() { return mode === "simple"; }
|
|
|
|
function set(next) {
|
|
if (!MODES.includes(next) || next === mode) return mode;
|
|
mode = next;
|
|
stamp();
|
|
try { localStorage.setItem(KEY, mode); } catch (_) {}
|
|
listeners.forEach((fn) => { try { fn(mode); } catch (e) { console.error(e); } });
|
|
try { window.dispatchEvent(new CustomEvent("funpack-ui-mode", { detail: mode })); } catch (_) {}
|
|
// Panels that BUILD different content (rather than hide some of it) redraw off the
|
|
// store, so one notify covers the inspector, timeline and action bar together.
|
|
try { window.Store?.notify?.(); } catch (_) {}
|
|
return mode;
|
|
}
|
|
|
|
function onChange(fn) { listeners.add(fn); return () => listeners.delete(fn); }
|
|
|
|
const WARN_KEY = "funpack_ui_mode_warned";
|
|
function warned() {
|
|
try { return localStorage.getItem(WARN_KEY) === "1"; } catch (_) { return true; }
|
|
}
|
|
function markWarned() {
|
|
try { localStorage.setItem(WARN_KEY, "1"); } catch (_) {}
|
|
}
|
|
|
|
stamp();
|
|
window.FunPackMode = { get, set, is, isSimple, onChange, warned, markWarned, MODES };
|
|
})();
|