134 lines
5.4 KiB
TypeScript
134 lines
5.4 KiB
TypeScript
import { z } from 'zod';
|
|
import { BUTTON_SIZE_MIN, MENU_PRIORITY_DEFAULT } from './common/const';
|
|
import { menuBaseSchema } from './elements/custom/menu/base';
|
|
|
|
const MENU_STYLES = [
|
|
'none',
|
|
'hidden',
|
|
'overlay',
|
|
'hover',
|
|
'hover-card',
|
|
'outside',
|
|
] as const;
|
|
const MENU_POSITIONS = ['left', 'right', 'top', 'bottom'] as const;
|
|
const MENU_ALIGNMENTS = MENU_POSITIONS;
|
|
|
|
const baseButtonDefault = {
|
|
alignment: 'matching' as const,
|
|
state_color: true,
|
|
permanent: false,
|
|
priority: MENU_PRIORITY_DEFAULT,
|
|
};
|
|
|
|
const visibleButtonDefault = {
|
|
...baseButtonDefault,
|
|
enabled: true,
|
|
};
|
|
|
|
const hiddenButtonDefault = {
|
|
...baseButtonDefault,
|
|
enabled: false,
|
|
};
|
|
|
|
export const menuConfigDefault = {
|
|
alignment: 'left' as const,
|
|
button_size: 40,
|
|
buttons: {
|
|
// Clone per key so each button has its own default object. This avoids
|
|
// shared nested default references between keys.
|
|
camera_ui: { ...visibleButtonDefault },
|
|
cameras: { ...visibleButtonDefault },
|
|
clips: { ...hiddenButtonDefault },
|
|
ptz_home: { ...hiddenButtonDefault },
|
|
display_mode: { ...visibleButtonDefault },
|
|
download: { ...visibleButtonDefault },
|
|
expand: { ...hiddenButtonDefault },
|
|
folders: { ...visibleButtonDefault },
|
|
iris: { ...visibleButtonDefault },
|
|
fullscreen: { ...visibleButtonDefault },
|
|
image: { ...hiddenButtonDefault },
|
|
info: { ...visibleButtonDefault },
|
|
gallery: { ...visibleButtonDefault },
|
|
live: { ...visibleButtonDefault },
|
|
media_player: { ...visibleButtonDefault },
|
|
microphone: {
|
|
...hiddenButtonDefault,
|
|
type: 'momentary' as const,
|
|
},
|
|
mute: { ...hiddenButtonDefault },
|
|
pip: { ...hiddenButtonDefault },
|
|
play: { ...hiddenButtonDefault },
|
|
ptz_controls: { ...hiddenButtonDefault },
|
|
recordings: { ...hiddenButtonDefault },
|
|
reviews: { ...hiddenButtonDefault },
|
|
set_review: { ...visibleButtonDefault },
|
|
screenshot: { ...hiddenButtonDefault },
|
|
snapshots: { ...hiddenButtonDefault },
|
|
substreams: { ...visibleButtonDefault },
|
|
timeline: { ...visibleButtonDefault },
|
|
},
|
|
position: 'top' as const,
|
|
style: 'hidden' as const,
|
|
};
|
|
|
|
const visibleButtonSchema = menuBaseSchema.extend({
|
|
enabled: menuBaseSchema.shape.enabled.default(visibleButtonDefault.enabled),
|
|
priority: menuBaseSchema.shape.priority.default(visibleButtonDefault.priority),
|
|
});
|
|
|
|
const hiddenButtonSchema = menuBaseSchema.extend({
|
|
enabled: menuBaseSchema.shape.enabled.default(hiddenButtonDefault.enabled),
|
|
priority: menuBaseSchema.shape.priority.default(hiddenButtonDefault.priority),
|
|
});
|
|
|
|
export const menuConfigSchema = z
|
|
.object({
|
|
style: z.enum(MENU_STYLES).default(menuConfigDefault.style),
|
|
position: z.enum(MENU_POSITIONS).default(menuConfigDefault.position),
|
|
alignment: z.enum(MENU_ALIGNMENTS).default(menuConfigDefault.alignment),
|
|
buttons: z
|
|
.object({
|
|
camera_ui: visibleButtonSchema.default(menuConfigDefault.buttons.camera_ui),
|
|
cameras: visibleButtonSchema.default(menuConfigDefault.buttons.cameras),
|
|
clips: hiddenButtonSchema.default(menuConfigDefault.buttons.clips),
|
|
ptz_home: hiddenButtonSchema.default(menuConfigDefault.buttons.ptz_home),
|
|
display_mode: visibleButtonSchema.default(
|
|
menuConfigDefault.buttons.display_mode,
|
|
),
|
|
download: visibleButtonSchema.default(menuConfigDefault.buttons.download),
|
|
expand: hiddenButtonSchema.default(menuConfigDefault.buttons.expand),
|
|
folders: visibleButtonSchema.default(menuConfigDefault.buttons.folders),
|
|
iris: visibleButtonSchema.default(menuConfigDefault.buttons.iris),
|
|
fullscreen: visibleButtonSchema.default(menuConfigDefault.buttons.fullscreen),
|
|
image: hiddenButtonSchema.default(menuConfigDefault.buttons.image),
|
|
info: visibleButtonSchema.default(menuConfigDefault.buttons.info),
|
|
gallery: visibleButtonSchema.default(menuConfigDefault.buttons.gallery),
|
|
live: visibleButtonSchema.default(menuConfigDefault.buttons.live),
|
|
media_player: visibleButtonSchema.default(
|
|
menuConfigDefault.buttons.media_player,
|
|
),
|
|
microphone: hiddenButtonSchema
|
|
.extend({
|
|
type: z
|
|
.enum(['momentary', 'toggle'])
|
|
.default(menuConfigDefault.buttons.microphone.type),
|
|
})
|
|
.default(menuConfigDefault.buttons.microphone),
|
|
mute: hiddenButtonSchema.default(menuConfigDefault.buttons.mute),
|
|
pip: hiddenButtonSchema.default(menuConfigDefault.buttons.pip),
|
|
play: hiddenButtonSchema.default(menuConfigDefault.buttons.play),
|
|
ptz_controls: hiddenButtonSchema.default(menuConfigDefault.buttons.ptz_controls),
|
|
recordings: hiddenButtonSchema.default(menuConfigDefault.buttons.recordings),
|
|
reviews: hiddenButtonSchema.default(menuConfigDefault.buttons.reviews),
|
|
set_review: visibleButtonSchema.default(menuConfigDefault.buttons.set_review),
|
|
screenshot: hiddenButtonSchema.default(menuConfigDefault.buttons.screenshot),
|
|
snapshots: hiddenButtonSchema.default(menuConfigDefault.buttons.snapshots),
|
|
substreams: visibleButtonSchema.default(menuConfigDefault.buttons.substreams),
|
|
timeline: visibleButtonSchema.default(menuConfigDefault.buttons.timeline),
|
|
})
|
|
.default(menuConfigDefault.buttons),
|
|
button_size: z.number().min(BUTTON_SIZE_MIN).default(menuConfigDefault.button_size),
|
|
})
|
|
.default(menuConfigDefault);
|
|
export type MenuConfig = z.infer<typeof menuConfigSchema>;
|