Shorter in-app hints in the interface: what a setting does and what it needs

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
digital-garbage
2026-11-09 13:32:42 +02:00
co-authored by Claude Sonnet 5.5
parent f5050a4574
commit b7aefbac23
7 changed files with 7 additions and 7 deletions
+1 -1
View File
@@ -68,7 +68,7 @@ export default {
const offFocus = [app.dom.onPage("focusin", onFocus), app.dom.onPage("focusout", onBlur)];
app.editorSettings.push(() => c.region.stack({ gap: "sm", children: [
c.toggle.default({ label: "Shortcut ideas", hint: "Shows a 💡 beside the Story and Prompt boxes while you are in them. Click it for shortcuts to insert: pairings you use, what usually follows the previous shot, and categories this prompt does not use yet.",
c.toggle.default({ label: "Shortcut ideas", hint: "Shows a 💡 beside the Story and Prompt boxes with shortcut suggestions to insert, based on what you use.",
checked: on(), onChange: (v) => { p.setPref("suggestions", v); if (!v) closeBulb(); } })] }));
return () => { closeBulb(); clearTimeout(hold); offFocus.forEach((f) => f()); };
},
+1 -1
View File
@@ -46,7 +46,7 @@ export function sceneRows(p, app) {
...(isSubclip(sc) ? [c.hint.default({ text: "This is a cut: its prompt and source belong to the first part." })] : [card(
c.field.default({ label: "Prompt", control: c.textarea.md({ label: "Prompt", value: sc.text || "", rows: 4, onInput: (v) => p.setText(sc.id, v) }) }))]),
c.label.section({ text: "Pictures" }),
card(mediaField(app, p, sc, { label: "Aspect ratio source", hint: "The scene's picture (or a video's first frame). Its shape sets this scene's aspect ratio (the project's Width/Height set the scale). It is the shape only for models that start from the scene's References (LTX image-to-video); a workflow that has its own start-picture input gets this picture there. The prompt enhancer can read it.",
card(mediaField(app, p, sc, { label: "Aspect ratio source", hint: "The scene's picture (or a video's first frame). Its shape sets the scene's aspect ratio; the project's Width and Height set the scale. The prompt enhancer can read it.",
key: "source_image", multiple: false, kinds: ["image", "video"], empty: "— choose aspect ratio source —" }),
mediaField(app, p, sc, { label: "References", key: "references", multiple: true, kinds: ["image", "video", "audio"], empty: "+ Add reference" })),
c.label.section({ text: "Length" }),
+1 -1
View File
@@ -36,7 +36,7 @@ export default {
}
app.editorSettings.push(() => c.region.stack({ gap: "md", children: [
c.label.section({ text: "Render" }),
c.toggle.default({ label: "Keep the clips' own frame rate", hint: "Off: the final video plays at the project's frame rate. On: it plays at the fastest rate the clips really have, for example after Interpolate, so no frames are dropped.",
c.toggle.default({ label: "Keep the clips' own frame rate", hint: "Off: the final video uses the project's frame rate. On: it uses the fastest rate among the clips (for example after Interpolate), so no frames are dropped.",
checked: p.pref("renderRealFps", false) === true, onChange: (v) => p.setPref("renderRealFps", v) })] }));
draw();
const offered = offer(app, { id: "render-final", label: "Render", icon: "⧉", run: () => { if (!busy && p.project) render(); } });
+1 -1
View File
@@ -47,7 +47,7 @@ export const modules = (app) => function mount() {
};
const isOff = (m) => control[m.id].quarantine || ps.isOff(m.id);
const notes = ps.saveNotes();
const master = c.toggle.default({ label: "Disable all enhancements", hint: "Every module above sits out, and so do shot camera's rewrites and continuity. Your choices are kept — switch it back off to restore them. Values typed into a node in Models & Pipeline (negative erase, int8, SLA…) are not touched. Handy for an A/B test of whether a feature does anything.",
const master = c.toggle.default({ label: "Disable all enhancements", hint: "Switches every feature above off at once, so you can compare with and without them. Your choices are kept; switch it back off to restore them.",
checked: ps.allOff(), onChange: (on) => ps.setAllOff(on).then(draw) });
const section = (label, rows) => rows.length ? [c.label.section({ text: label }), ...rows] : [];
const installed = mine.filter((m) => !isOff(m));
+1 -1
View File
@@ -22,7 +22,7 @@ export const shotMemory = (app) => function mount() {
const words = data.words || [], views = data.views || [];
const details = data.details || [];
const infusion = data.infusion || [];
if (!words.length && !views.length && !(data.arms || []).length && !details.length && !infusion.length) return page.set([c.emptyState.default({ icon: "◎", title: "Nothing learned yet", hint: "In a pipeline with the Shot camera node, turn on camera moves, shot views or liked details in Engine, then rate renders: the camera remembers which words, views and details you liked." })]);
if (!words.length && !views.length && !(data.arms || []).length && !details.length && !infusion.length) return page.set([c.emptyState.default({ icon: "◎", title: "Nothing learned yet", hint: "Learns which words, views and details you liked. Needs the Shot camera node with camera moves, shot views or liked details on in Engine, then rate your renders." })]);
page.set([c.hint.default({ text: `${data.prompts} prompts seen · ${data.shots} shots reviewed. Forget anything that taught it the wrong thing.` }),
...(details.length ? [c.label.section({ text: "Liked details" }), ...details.map((d) => row(d.phrase, `${d.kept ? "will be added" : "dropped"} · liked ${d.good.toFixed(1)} · disliked ${d.bad.toFixed(1)}`, "detail", d.phrase))] : []),
...(views.length ? [c.label.section({ text: "Views" }), ...views.map((v) => row(v.view, `liked ${v.good.toFixed(1)} · disliked ${v.bad.toFixed(1)}`, "view", v.view))] : []),
+1 -1
View File
@@ -152,7 +152,7 @@ export const taste = (app) => function mount() {
c.label.section({ text: "Block map" }),
mapState && mapState.error ? c.banner.warn({ text: `Could not read the block map: ${mapState.error}` }) : null,
mapState && mapState.problem ? c.banner.warn({ text: mapState.problem }) : null,
c.toggle.default({ label: "Profile the blocks on the next run", hint: "On: the next generation takes extra model calls on three of its steps and measures how much each group of blocks can take. It turns itself off once the map is saved.",
c.toggle.default({ label: "Profile the blocks on the next run", hint: "Measures how much each group of blocks can take. The next generation takes extra model calls on three steps, then this turns itself off.",
checked: !!(mapState && mapState.enabled),
onChange: async (on) => { try { await app.api.setBlockMap(on); } catch (err) { tell(err.message); } refreshMap(); } }),
c.settingsRow.default({ label: "Saved maps", hint: "One per model size. Features follow a map when one exists for the loaded model.",
+1 -1
View File
@@ -103,7 +103,7 @@ export function dataStep({ app, session, go, ui }) {
ratedNote.setText((n ? `${n} rated result${n > 1 ? "s" : ""} found in your projects. ${p ? `${p} picked: only those are added.` : "None picked: all are added."}` : "None found yet. Rate results in your projects and they appear here.") + left);
addRated.node.disabled = !n || !open;
}
const include = c.field.default({ label: "Captions include", hint: "What goes into the caption from each result's prompt. Shortcuts are expanded. Variables are filled in only when ticked, otherwise $name stays as written. Nothing ticked adds them with no caption.",
const include = c.field.default({ label: "Captions include", hint: "What goes into each caption from the result's prompt. Shortcuts are expanded; variables are filled in only when ticked, otherwise $name stays as written.",
control: c.checklist.default({ label: "Captions include", items: INCLUDE, values: ui.include, onChange: async (v) => {
ui.include = v;
try { ui.rated = await app.api.trainRated(v.length ? v : ["none"]); } catch { /* the old captions stay */ }