fix(ui): restore background after playlist reset

This commit is contained in:
DCCONSTRUCTIONS
2026-07-29 15:30:35 +03:00
parent 32c5d0dda5
commit 6180c3b8b7
3 changed files with 96 additions and 13 deletions
@@ -8,9 +8,10 @@ import {
} from "@nodedc/ui-react"; } from "@nodedc/ui-react";
import { import {
createEnvironmentMediaItem, appendEnvironmentMediaItem,
inferEnvironmentMediaKind, inferEnvironmentMediaKind,
maxEnvironmentMediaItems, maxEnvironmentMediaItems,
removeEnvironmentMediaItem,
type EnvironmentBackground, type EnvironmentBackground,
type EnvironmentMediaItem, type EnvironmentMediaItem,
type EnvironmentSurfaceId, type EnvironmentSurfaceId,
@@ -135,10 +136,7 @@ export function EnvironmentMediaPlaylistEditor({
<IconButton <IconButton
label="Добавить медиаконтент" label="Добавить медиаконтент"
disabled={disabled || background.items.length >= maxEnvironmentMediaItems} disabled={disabled || background.items.length >= maxEnvironmentMediaItems}
onClick={() => onChange({ onClick={() => onChange(appendEnvironmentMediaItem(background))}
...background,
items: [...background.items, createEnvironmentMediaItem()],
})}
> >
<Icon name="plus" /> <Icon name="plus" />
</IconButton> </IconButton>
@@ -202,14 +200,7 @@ export function EnvironmentMediaPlaylistEditor({
disabled={disabled || uploadingIds.has(item.id)} disabled={disabled || uploadingIds.has(item.id)}
onClick={() => { onClick={() => {
setItemError(item.id); setItemError(item.id);
const items = background.items.filter( onChange(removeEnvironmentMediaItem(background, item.id));
(candidate) => candidate.id !== item.id,
);
onChange({
...background,
enabled: items.length ? background.enabled : false,
items,
});
}} }}
> >
<Icon name="trash" /> <Icon name="trash" />
@@ -75,6 +75,36 @@ export function createEnvironmentMediaItem(): EnvironmentMediaItem {
}; };
} }
export function appendEnvironmentMediaItem(
background: EnvironmentBackground,
item: EnvironmentMediaItem = createEnvironmentMediaItem(),
): EnvironmentBackground {
if (
background.items.length >= maxEnvironmentMediaItems
|| background.items.some((candidate) => candidate.id === item.id)
) {
return background;
}
return {
...background,
enabled: background.items.length === 0 ? true : background.enabled,
items: [...background.items, item],
};
}
export function removeEnvironmentMediaItem(
background: EnvironmentBackground,
itemId: string,
): EnvironmentBackground {
const items = background.items.filter((item) => item.id !== itemId);
if (items.length === background.items.length) return background;
return {
...background,
enabled: items.length > 0 && background.enabled,
items,
};
}
export function inferEnvironmentMediaKind(url: string): EnvironmentMediaKind { export function inferEnvironmentMediaKind(url: string): EnvironmentMediaKind {
return /\.(mp4|webm|mov)(?:[?#].*)?$/i.test(url) ? "video" : "image"; return /\.(mp4|webm|mov)(?:[?#].*)?$/i.test(url) ? "video" : "image";
} }
@@ -143,3 +143,65 @@ test("editing a cloned page cannot mutate accepted settings", () => {
assert.equal(accepted.pages.fleet.background.enabled, false); assert.equal(accepted.pages.fleet.background.enabled, false);
assert.equal(accepted.pages.fleet.background.items.length, 0); assert.equal(accepted.pages.fleet.background.items.length, 0);
}); });
test("repopulating an emptied playlist restores its background lifecycle", () => {
const original = {
enabled: true,
imageDurationSeconds: 10,
items: [
{
id: "media-original",
source: "url",
url: "https://example.test/original.mp4",
mediaKind: "video",
fileName: null,
},
],
};
const emptied = environment.removeEnvironmentMediaItem(
original,
"media-original",
);
const replacement = {
id: "media-replacement",
source: "file",
url: null,
mediaKind: null,
fileName: null,
};
const repopulated = environment.appendEnvironmentMediaItem(
emptied,
replacement,
);
assert.equal(emptied.enabled, false);
assert.equal(emptied.items.length, 0);
assert.equal(repopulated.enabled, true);
assert.deepEqual(repopulated.items, [replacement]);
});
test("adding to an intentionally disabled nonempty playlist keeps it disabled", () => {
const disabled = {
enabled: false,
imageDurationSeconds: 10,
items: [
{
id: "media-hidden",
source: "url",
url: "https://example.test/hidden.png",
mediaKind: "image",
fileName: null,
},
],
};
const next = environment.appendEnvironmentMediaItem(disabled, {
id: "media-second",
source: "file",
url: null,
mediaKind: null,
fileName: null,
});
assert.equal(next.enabled, false);
assert.equal(next.items.length, 2);
});