Release 0.5.0
This commit is contained in:
1 parent
4042fe6a64
commit
5a9d7735d4
26 files changed
+1855
-113
No files matched your search
+125
-13
@@ -1,15 +1,127 @@
|
||||
import { getShow } from '#lib/server/previews.js';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { error, fail } from '@sveltejs/kit';
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
import { requireUser } from '#lib/server/auth.js';
|
||||
import {
|
||||
completeCurrent,
|
||||
getLiveView,
|
||||
goBack,
|
||||
issuePresentationAccess,
|
||||
moveOpenUsage,
|
||||
presentUsage,
|
||||
skipCurrent,
|
||||
startOrResumeLive
|
||||
} from '#lib/server/live.js';
|
||||
import { listShows } from '#lib/server/shows.js';
|
||||
|
||||
export function load({ url }) {
|
||||
const show = getShow(url.searchParams.get('show') || undefined);
|
||||
const usages = show.sections.flatMap((section) =>
|
||||
section.usages
|
||||
.filter((usage) => !usage.isReserve)
|
||||
.map((usage) => ({ ...usage, section: section.name }))
|
||||
);
|
||||
const currentIndex = Math.max(
|
||||
0,
|
||||
usages.findIndex((usage) => usage.status === 'current')
|
||||
);
|
||||
return { show, current: usages[currentIndex] ?? null, next: usages[currentIndex + 1] ?? null };
|
||||
function text(data: FormData, name: string) {
|
||||
return String(data.get(name) || '');
|
||||
}
|
||||
|
||||
function actionError(cause: unknown) {
|
||||
const code = cause instanceof Error ? cause.message : '';
|
||||
if (code === 'CONFLICT')
|
||||
return {
|
||||
status: 409,
|
||||
error: 'Der Live-Stand wurde bereits geändert. Die Ansicht wurde erneuert.'
|
||||
};
|
||||
if (code === 'NO_CURRENT') return { status: 409, error: 'Es ist kein aktuelles Piece aktiv.' };
|
||||
if (code === 'NO_PREVIOUS') return { status: 409, error: 'Es gibt kein vorheriges Piece.' };
|
||||
if (code === 'LIVE_ORDER_LOCKED')
|
||||
return {
|
||||
status: 409,
|
||||
error: 'Nur offene Pieces hinter dem aktuellen Stand können sortiert werden.'
|
||||
};
|
||||
if (code === 'SHOW_COMPLETED')
|
||||
return { status: 409, error: 'Abgeschlossene Sendungen können nicht live gesteuert werden.' };
|
||||
if (code === 'NOT_FOUND')
|
||||
return { status: 404, error: 'Sendung oder Piece wurde nicht gefunden.' };
|
||||
if (code.startsWith('INVALID_')) return { status: 400, error: 'Die Live-Aktion ist ungültig.' };
|
||||
return { status: 500, error: 'Die Live-Aktion konnte nicht gespeichert werden.' };
|
||||
}
|
||||
|
||||
function attempt(intent: string, operation: () => unknown) {
|
||||
try {
|
||||
return { intent, success: true, result: operation() };
|
||||
} catch (cause) {
|
||||
const problem = actionError(cause);
|
||||
return fail(problem.status, { intent, ...problem });
|
||||
}
|
||||
}
|
||||
|
||||
export const load: PageServerLoad = ({ locals, url }) => {
|
||||
requireUser(locals.user);
|
||||
const showId = url.searchParams.get('show') || listShows()[0]?.id;
|
||||
if (!showId) error(404, 'Keine Sendung vorhanden');
|
||||
try {
|
||||
return { live: getLiveView(showId), commandId: randomUUID() };
|
||||
} catch (cause) {
|
||||
if (cause instanceof Error && cause.message === 'NOT_FOUND')
|
||||
error(404, 'Sendung nicht gefunden');
|
||||
throw cause;
|
||||
}
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
start: async ({ locals, request }) => {
|
||||
requireUser(locals.user);
|
||||
const data = await request.formData();
|
||||
return attempt('start', () =>
|
||||
startOrResumeLive(text(data, 'showId'), text(data, 'commandId'), Number(data.get('revision')))
|
||||
);
|
||||
},
|
||||
complete: async ({ locals, request }) => {
|
||||
requireUser(locals.user);
|
||||
const data = await request.formData();
|
||||
return attempt('complete', () =>
|
||||
completeCurrent(text(data, 'showId'), text(data, 'commandId'), Number(data.get('revision')))
|
||||
);
|
||||
},
|
||||
skip: async ({ locals, request }) => {
|
||||
requireUser(locals.user);
|
||||
const data = await request.formData();
|
||||
return attempt('skip', () =>
|
||||
skipCurrent(text(data, 'showId'), text(data, 'commandId'), Number(data.get('revision')))
|
||||
);
|
||||
},
|
||||
back: async ({ locals, request }) => {
|
||||
requireUser(locals.user);
|
||||
const data = await request.formData();
|
||||
return attempt('back', () =>
|
||||
goBack(text(data, 'showId'), text(data, 'commandId'), Number(data.get('revision')))
|
||||
);
|
||||
},
|
||||
present: async ({ locals, request }) => {
|
||||
requireUser(locals.user);
|
||||
const data = await request.formData();
|
||||
return attempt('present', () =>
|
||||
presentUsage(
|
||||
text(data, 'showId'),
|
||||
text(data, 'usageId') || null,
|
||||
text(data, 'commandId'),
|
||||
Number(data.get('revision'))
|
||||
)
|
||||
);
|
||||
},
|
||||
moveUsage: async ({ locals, request }) => {
|
||||
requireUser(locals.user);
|
||||
const data = await request.formData();
|
||||
return attempt('moveUsage', () =>
|
||||
moveOpenUsage(text(data, 'showId'), text(data, 'usageId'), Number(data.get('showRevision')), {
|
||||
sectionId: text(data, 'sectionId') || null,
|
||||
position: Number(data.get('position'))
|
||||
})
|
||||
);
|
||||
},
|
||||
createOutput: async ({ locals, request }) => {
|
||||
requireUser(locals.user);
|
||||
const data = await request.formData();
|
||||
try {
|
||||
const token = issuePresentationAccess(text(data, 'showId'));
|
||||
return { intent: 'createOutput', success: true, outputUrl: `/heinzlive/${token}` };
|
||||
} catch (cause) {
|
||||
const problem = actionError(cause);
|
||||
return fail(problem.status, { intent: 'createOutput', ...problem });
|
||||
}
|
||||
}
|
||||
} satisfies Actions;
|
||||
Reference in new issue
Block a user