Reference marks numbered per kind: the first sound is R1
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tw9fjX7o2YfeGQE18MEtPu
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
### Fixed
|
||||
|
||||
- **A project opens with scene Source values that no longer exist (image, empty, mixed...) as the default**, so Continuity carries again for those scenes. **Generate (and the Training preview) is refused while an upscale model is running**, also after a page reload or in a second tab (they share ComfyUI's model memory). **The Fast & Simple R2V preset decodes with None when the Sol-H3 VAE is not installed**, instead of being refused. **The tour callout follows its button when it is redrawn or renamed (Generate becomes Generating…).** **Upscale "Always" tries again after a running generation, for the same project and render only.** **The timeline header is one row from 1024px wide.**
|
||||
- **Reference marks on the media tiles are numbered per kind**: the first sound is R1 even when a picture holds the first slot (it was R2), as the model's inputs are numbered.
|
||||
- **Settings of a module that no longer exists are cleared from a project when it opens** (such as the removed Video detail), and saved at once, so the Log stops warning about them. Nothing is cleared while a module failed to load, and a module a model merely hides keeps its settings.
|
||||
- **Save Video carries the sampler's own last picture to the next shot** (it was carrying the Post-processed one). **Interpolate keeps the full length at 3 and 4 times** (it ended up to 75 ms short of the sound). **LoRA training refuses a model it cannot copy with the reason** (MXFP8 or int8 conversion in the loader), and a ticked MXFP8 that was skipped no longer blocks training. LoRA files that spell their matrices lora_down and lora_up load like lora_A and lora_B.
|
||||
- **Model Loader: no more reload on every run, and no half-way eviction.** Two loaders of one file in one graph no longer reload the model each run. When the same file comes back with other settings (SLA method, attention...), ComfyUI frees the earlier copy when the run ends instead of evicting it half way. A ComfyUI that cannot free the earlier copy is said in the Log.
|
||||
|
||||
@@ -240,3 +240,14 @@ test("Delete after picking files ends Select mode, and the bin's controls are pi
|
||||
assert.equal(btn("Delete (0)").hidden, true);
|
||||
host.remove();
|
||||
});
|
||||
|
||||
test("references are numbered per kind: the first sound is R1 even when a picture holds the first slot", async () => {
|
||||
const doc = { scenes: [{ id: "s1", references: ["m1", "m2", "m3"] }] };
|
||||
const project = { selected: doc.scenes[0], project: doc, setScene() {}, edit: (fn) => fn(doc) };
|
||||
const api = { media: async () => ({ media: [{ id: "m1", name: "cat.png", kind: "image" }, { id: "m2", name: "song.wav", kind: "audio" }, { id: "m3", name: "dog.png", kind: "image" }] }) };
|
||||
const host = document.createElement("div");
|
||||
hub.setup({ host, app: { project, api, mediaPeek: {}, say: () => {}, on: () => () => {} } });
|
||||
await new Promise((r) => setTimeout(r, 10));
|
||||
const flag = (n) => [...[...host.querySelectorAll(".cx-cell")].find((x) => x.textContent.includes(n)).querySelectorAll(".cx-cell-flag")].map((x) => x.textContent).join();
|
||||
assert.deepEqual([flag("cat.png"), flag("song.wav"), flag("dog.png")], ["R1", "R1", "R2"]);
|
||||
});
|
||||
|
||||
@@ -178,9 +178,12 @@ export default {
|
||||
shelf.set([g]);
|
||||
if (g.setCols) g.setCols(Number(show.cols));
|
||||
tileSize.node.hidden = !g.setCols;
|
||||
// Numbered per kind, as the model's inputs are: the first sound is R1 even when a picture holds the first slot.
|
||||
const kindOf = (id) => (items.find((m) => m.id === id) || {}).kind;
|
||||
const ordinal = (id) => { const i = refs.indexOf(id); return refs.filter((r, j) => nums[j] <= nums[i] && kindOf(r) === kindOf(id)).length; };
|
||||
// what the selected scene uses is marked on its tile, so a reference can be told from the rest
|
||||
const flags = (m) => [sc && sc.source_image === m.id ? { text: "◐", title: "The selected scene's aspect ratio source" } : null,
|
||||
refs.includes(m.id) ? { text: `${plan.pins[m.id] ? "📌" : ""}R${nums[refs.indexOf(m.id)]}`, title: `Reference slot ${nums[refs.indexOf(m.id)]} for the selected scene${plan.pins[m.id] ? ", pinned to every scene" : ""}` } : null].filter(Boolean);
|
||||
refs.includes(m.id) ? { text: `${plan.pins[m.id] ? "📌" : ""}R${ordinal(m.id)}`, title: `${m.kind === "image" ? "Reference" : m.kind[0].toUpperCase() + m.kind.slice(1) + " reference"} ${ordinal(m.id)} for the selected scene${plan.pins[m.id] ? ", pinned to every scene" : ""}` } : null].filter(Boolean);
|
||||
g.setItems(shown.map((m) => ({ id: m.id, label: m.name, thumb: m.kind === "audio" ? undefined : `${base(m.id)}/thumb`, badge: m.kind, flags: flags(m) })));
|
||||
g.setValue(selecting ? [...chosen] : sc ? [sc.source_image, ...refs].filter(Boolean) : []);
|
||||
selectBtn.setLabel(selecting ? "Done" : "Select");
|
||||
|
||||
Reference in New Issue
Block a user