diff --git a/package.json b/package.json index adcdd43..32751b3 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,11 @@ "file": "scoreboard/main.html", "width": 1920, "height": 1080 + }, + { + "file": "commentary/main.html", + "width": 1920, + "height": 1080 } ] }, diff --git a/schemas/commentary.json b/schemas/commentary.json new file mode 100644 index 0000000..455a223 --- /dev/null +++ b/schemas/commentary.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + "leftCommentator": { + "type": "string", + "default": "" + }, + "rightCommentator": { + "type": "string", + "default": "" + } + }, + "required": [ + "leftCommentator", + "rightCommentator" + ], + "default": { + "leftCommentator": "", + "rightCommentator": "" + } +} diff --git a/src/browser_shared/replicants.ts b/src/browser_shared/replicants.ts index 667914d..d986f9c 100644 --- a/src/browser_shared/replicants.ts +++ b/src/browser_shared/replicants.ts @@ -12,3 +12,5 @@ const thisBundle = 'scoreko-dev'; export const exampleReplicant = useReplicant('exampleReplicant', thisBundle); export const playersReplicant = useReplicant('players', thisBundle); export const scoreboardReplicant = useReplicant('scoreboard', thisBundle); + +export const commentaryReplicant = useReplicant('commentary', thisBundle); diff --git a/src/dashboard/example/components/CommentaryPanel.vue b/src/dashboard/example/components/CommentaryPanel.vue new file mode 100644 index 0000000..dc0454c --- /dev/null +++ b/src/dashboard/example/components/CommentaryPanel.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/src/dashboard/example/stores/commentary.ts b/src/dashboard/example/stores/commentary.ts new file mode 100644 index 0000000..9ae5b4d --- /dev/null +++ b/src/dashboard/example/stores/commentary.ts @@ -0,0 +1,84 @@ +import { defineStore } from 'pinia'; +import { computed, ref, watch } from 'vue'; +import { commentaryReplicant } from '../../../browser_shared/replicants'; +import type { Schemas } from '../../../types'; + +type Commentary = Schemas.Commentary; + +const defaultCommentary: Commentary = { + leftCommentator: '', + rightCommentator: '', +}; + +const normalizeCommentary = (input: unknown): Commentary => { + const candidate = typeof input === 'object' && input !== null ? (input as Record) : {}; + return { + leftCommentator: typeof candidate.leftCommentator === 'string' ? candidate.leftCommentator : '', + rightCommentator: typeof candidate.rightCommentator === 'string' ? candidate.rightCommentator : '', + }; +}; + +export const useCommentaryStore = defineStore('commentary', () => { + const commentary = ref({ ...defaultCommentary }); + const replicant = commentaryReplicant; + const isApplyingReplicant = ref(false); + + watch( + () => replicant?.data, + (value) => { + if (!value) { + return; + } + isApplyingReplicant.value = true; + commentary.value = normalizeCommentary(value); + isApplyingReplicant.value = false; + }, + { deep: true, immediate: true }, + ); + + watch( + commentary, + (value) => { + if (isApplyingReplicant.value || !replicant) { + return; + } + replicant.data = normalizeCommentary(value); + replicant.save(); + }, + { deep: true, flush: 'sync' }, + ); + + const leftCommentator = computed({ + get: () => commentary.value.leftCommentator, + set: (value: string) => { + commentary.value = { + ...commentary.value, + leftCommentator: value, + }; + }, + }); + + const rightCommentator = computed({ + get: () => commentary.value.rightCommentator, + set: (value: string) => { + commentary.value = { + ...commentary.value, + rightCommentator: value, + }; + }, + }); + + const swapCommentators = () => { + commentary.value = { + leftCommentator: commentary.value.rightCommentator, + rightCommentator: commentary.value.leftCommentator, + }; + }; + + return { + commentary, + leftCommentator, + rightCommentator, + swapCommentators, + }; +}); diff --git a/src/dashboard/example/views/Dashboard.vue b/src/dashboard/example/views/Dashboard.vue index bc84282..60dbdeb 100644 --- a/src/dashboard/example/views/Dashboard.vue +++ b/src/dashboard/example/views/Dashboard.vue @@ -1,6 +1,7 @@ + + + + diff --git a/src/types/schemas.d.ts b/src/types/schemas.d.ts index e1dc2ec..0ec0ae0 100644 --- a/src/types/schemas.d.ts +++ b/src/types/schemas.d.ts @@ -4,6 +4,7 @@ * Also see index.d.ts for a "grouped" re-export of this as well. */ +export type { Commentary } from './schemas/commentary.d.ts'; export type { Configschema } from './schemas/configschema.d.ts'; export type { ExampleReplicant } from './schemas/exampleReplicant.d.ts'; export type { Players } from './schemas/players.d.ts'; diff --git a/src/types/schemas/commentary.d.ts b/src/types/schemas/commentary.d.ts new file mode 100644 index 0000000..4515a7f --- /dev/null +++ b/src/types/schemas/commentary.d.ts @@ -0,0 +1,12 @@ +/* prettier-ignore */ +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + +export interface Commentary { + leftCommentator: string; + rightCommentator: string; +}