fix(ui): restore background after playlist reset
This commit is contained in:
@@ -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);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user