Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions app/lib/broadcast.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<BroadcastResult> => {
const prisma = getPrisma()

const z = await prisma.zone.findFirstOrThrow({
Expand All @@ -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({
Expand All @@ -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}
}
9 changes: 8 additions & 1 deletion app/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
8 changes: 7 additions & 1 deletion app/locales/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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ę',
Expand Down
43 changes: 37 additions & 6 deletions app/routes/broadcast.finish.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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}})
Expand All @@ -61,7 +83,7 @@ export const action = async ({request}: ActionFunctionArgs) => {
})
}*/

return {queue, zone}
return {queue, zone, error: null}
}

const BroadcastFinish = () => {
Expand All @@ -73,11 +95,13 @@ const BroadcastFinish = () => {
return <div>{t('common.error')}</div>
}

const {queue, zone} = data
const {queue, zone, error} = data

return (
<Page title={t('broadcast.pageTitle')}>
<div className="box mb-4">{t('broadcast.finish.message')}</div>
<div className={`box mb-4 ${error ? 'bg-red-300' : ''}`}>
{error ? error : t('broadcast.finish.message')}
</div>
<form method="post">
<input type="hidden" name="queue" value={queue} />
<input type="hidden" name="zone" value={zone} />
Expand All @@ -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'
}
])
]}
/>
</form>
Expand Down
27 changes: 25 additions & 2 deletions app/routes/broadcast.zone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,26 @@ const BroadcastZone = () => {

const {queue, zones, count} = data

if (zones.length === 0) {
return (
<Page title={t('broadcast.zone.pageTitle')}>
<div className="box mb-4 bg-red-300">{t('broadcast.zone.noZones')}</div>
<Actions
actions={[
{
label: t('button.back'),
color: 'bg-stone-200',
onClick: e => {
e.preventDefault()
navigate('/broadcast')
}
}
]}
/>
</Page>
)
}

return (
<Page title={t('broadcast.zone.pageTitle')}>
<div className="w-full bg-gray-100 rounded-3xl h-1.5 my-4 ">
Expand All @@ -72,8 +92,11 @@ const BroadcastZone = () => {
label={t('broadcast.zone.field.zone.label')}
helperText={t('broadcast.zone.field.zone.helper')}
>
<select name="zone" className={INPUT_CLASSES} defaultValue="_">
<option value="_">{t('broadcast.zone.noneOption')}</option>
<select
name="zone"
className={INPUT_CLASSES}
defaultValue={zones[0].id}
>
{zones.map(({id, name}) => {
return (
<option key={id} value={id}>
Expand Down
Loading