diff --git a/app/lib/broadcast.server.ts b/app/lib/broadcast.server.ts index 7401813..c50f3fb 100644 --- a/app/lib/broadcast.server.ts +++ b/app/lib/broadcast.server.ts @@ -3,13 +3,20 @@ import {asyncForEach} from '@arcath/utils' import {getPrisma} from './prisma.server' import {addJob} from './queues.server' +export type BroadcastResult = + | {sent: true} + | {sent: false; reason: 'emptyQueue' | 'noPlayableSounds'} + /** * * @param zone The ID of the Zone to broadcase to * @param sounds An array as a JSON string of IDS to play. - * @returns + * @returns Whether the broadcast was queued and, if not, the reason why. */ -export const broadcast = async (zone: string, sounds: string) => { +export const broadcast = async ( + zone: string, + sounds: string +): Promise => { const prisma = getPrisma() const z = await prisma.zone.findFirstOrThrow({ @@ -27,7 +34,9 @@ export const broadcast = async (zone: string, sounds: string) => { } if (soundQueue.length === 0) { - return + console.warn(`Broadcast to zone ${zone} skipped, the sound queue is empty.`) + + return {sent: false, reason: 'emptyQueue'} } const audio = await prisma.audio.findMany({ @@ -43,14 +52,20 @@ export const broadcast = async (zone: string, sounds: string) => { }) if (filteredQueue.length === 0) { - return + console.warn( + `Broadcast to zone ${zone} skipped, none of the queued sounds have a file.` + ) + + return {sent: false, reason: 'noPlayableSounds'} } - return asyncForEach(z.sounders, async ({sounder}) => { + await asyncForEach(z.sounders, async ({sounder}) => { await addJob('broadcast', { ip: sounder.ip, key: sounder.key, sounds: JSON.stringify(filteredQueue) }) }) + + return {sent: true} } diff --git a/app/locales/en.ts b/app/locales/en.ts index 527911f..7594003 100644 --- a/app/locales/en.ts +++ b/app/locales/en.ts @@ -94,10 +94,17 @@ export const en = { 'broadcast.zone.pageTitle': 'Broadcast (Zone)', 'broadcast.zone.field.zone.label': 'Zone', 'broadcast.zone.field.zone.helper': 'The zone to broadcast the sound to.', - 'broadcast.zone.noneOption': 'None', + 'broadcast.zone.noZones': + 'There are no zones yet. Add a zone before broadcasting.', 'broadcast.zone.submit': 'Broadcast!', 'broadcast.finish.metaTitle': 'Finished', 'broadcast.finish.message': 'Broadcast sent!', + 'broadcast.finish.error.noZone': + 'Nothing was sent. Pick a zone to broadcast to.', + 'broadcast.finish.error.emptyQueue': + 'Nothing was sent. Add at least one sound to the queue.', + 'broadcast.finish.error.noPlayableSounds': + 'Nothing was sent. None of the selected sounds have a file to play.', 'broadcast.finish.startAgain': 'Start again', 'broadcast.finish.rebroadcast': 'Re-broadcast', 'broadcast.tts.metaTitle': 'Text to Speech', diff --git a/app/locales/pl.ts b/app/locales/pl.ts index 0d2e795..4833039 100644 --- a/app/locales/pl.ts +++ b/app/locales/pl.ts @@ -83,10 +83,16 @@ export const pl = { 'broadcast.zone.field.zone.label': 'Strefa', 'broadcast.zone.field.zone.helper': 'Strefa urządzeń, do której ma zostać nadany dźwięk.', - 'broadcast.zone.noneOption': 'Brak', + 'broadcast.zone.noZones': + 'Nie ma jeszcze żadnej strefy. Dodaj strefę przed nadawaniem.', 'broadcast.zone.submit': 'Nadaj!', 'broadcast.finish.metaTitle': 'Zakończono', 'broadcast.finish.message': 'Transmisja wysłana!', + 'broadcast.finish.error.noZone': 'Nic nie wysłano. Wybierz strefę nadawania.', + 'broadcast.finish.error.emptyQueue': + 'Nic nie wysłano. Dodaj do kolejki co najmniej jeden dźwięk.', + 'broadcast.finish.error.noPlayableSounds': + 'Nic nie wysłano. Żaden z wybranych dźwięków nie ma pliku do odtworzenia.', 'broadcast.finish.startAgain': 'Rozpocznij ponownie', 'broadcast.finish.rebroadcast': 'Nadaj ponownie', 'broadcast.tts.metaTitle': 'Tekst na mowę', diff --git a/app/routes/broadcast.finish.tsx b/app/routes/broadcast.finish.tsx index e3b4d12..03de956 100644 --- a/app/routes/broadcast.finish.tsx +++ b/app/routes/broadcast.finish.tsx @@ -13,6 +13,7 @@ import {pageTitle} from '~/lib/utils' import {useTranslation} from '~/lib/i18n' import {translate} from '~/lib/i18n.shared' import {getRootI18n} from '~/lib/i18n.meta' +import {initTranslations} from '~/lib/i18n.server' export const meta: MetaFunction = ({matches}) => { const {messages} = getRootI18n(matches) @@ -33,6 +34,8 @@ export const action = async ({request}: ActionFunctionArgs) => { return redirect('/login') } + const {messages} = initTranslations(request) + const formData = await request.formData() const queue = formData.get('queue') as string | undefined @@ -43,8 +46,27 @@ export const action = async ({request}: ActionFunctionArgs) => { invariant(zone) //invariant(desktopGroup) - if (zone !== '_') { - await broadcast(zone, queue) + if (zone === '' || zone === '_') { + return { + queue, + zone, + error: translate(messages, 'broadcast.finish.error.noZone') + } + } + + const broadcastResult = await broadcast(zone, queue) + + if (!broadcastResult.sent) { + return { + queue, + zone, + error: translate( + messages, + broadcastResult.reason === 'emptyQueue' + ? 'broadcast.finish.error.emptyQueue' + : 'broadcast.finish.error.noPlayableSounds' + ) + } } /*if (desktopGroup !== '_') { const audio = await prisma.audio.findFirstOrThrow({where: {id: sound}}) @@ -61,7 +83,7 @@ export const action = async ({request}: ActionFunctionArgs) => { }) }*/ - return {queue, zone} + return {queue, zone, error: null} } const BroadcastFinish = () => { @@ -73,11 +95,13 @@ const BroadcastFinish = () => { return
{t('common.error')}
} - const {queue, zone} = data + const {queue, zone, error} = data return ( -
{t('broadcast.finish.message')}
+
+ {error ? error : t('broadcast.finish.message')} +
@@ -91,7 +115,14 @@ const BroadcastFinish = () => { navigate('/broadcast') } }, - {label: t('broadcast.finish.rebroadcast'), color: 'bg-green-300'} + ...(error + ? [] + : [ + { + label: t('broadcast.finish.rebroadcast'), + color: 'bg-green-300' + } + ]) ]} />
diff --git a/app/routes/broadcast.zone.tsx b/app/routes/broadcast.zone.tsx index 47871aa..fe9d3be 100644 --- a/app/routes/broadcast.zone.tsx +++ b/app/routes/broadcast.zone.tsx @@ -58,6 +58,26 @@ const BroadcastZone = () => { const {queue, zones, count} = data + if (zones.length === 0) { + return ( + +
{t('broadcast.zone.noZones')}
+ { + e.preventDefault() + navigate('/broadcast') + } + } + ]} + /> +
+ ) + } + return (
@@ -72,8 +92,11 @@ const BroadcastZone = () => { label={t('broadcast.zone.field.zone.label')} helperText={t('broadcast.zone.field.zone.helper')} > - {zones.map(({id, name}) => { return (