From 0b9f9269d06be925f62950528fd7fa3811dd4b63 Mon Sep 17 00:00:00 2001
From: Konrad Mohrfeldt <konrad.mohrfeldt@farbdev.org>
Date: Tue, 28 May 2024 00:29:01 +0200
Subject: [PATCH] feat: use radio settings for tank line-in inputs

refs aura/aura#242
refs #282
refs #283
---
 src/components/playlist/AInputUrlDialog.vue | 14 +++++++++++---
 src/stores/index.ts                         |  1 +
 src/stores/playout.ts                       | 15 +++++++--------
 src/stores/radio-settings.ts                | 17 +++++++++++++++++
 src/types.ts                                |  1 +
 5 files changed, 37 insertions(+), 11 deletions(-)
 create mode 100644 src/stores/radio-settings.ts

diff --git a/src/components/playlist/AInputUrlDialog.vue b/src/components/playlist/AInputUrlDialog.vue
index c5acb351..50ede69b 100644
--- a/src/components/playlist/AInputUrlDialog.vue
+++ b/src/components/playlist/AInputUrlDialog.vue
@@ -2,8 +2,9 @@
   <AEditDialog
     ref="dialog"
     :title="t('playlist.editor.addInputDialog.title')"
+    :can-save="canSave"
     :save-label="t('playlist.editor.addInputDialog.saveLabel')"
-    :save="() => emit('save', selectedInput)"
+    :save="() => emit('save', selectedInput as string)"
     class="tw-w-min"
   >
     <div class="tw-flex tw-flex-col tw-gap-2 tw-w-96">
@@ -33,7 +34,7 @@
 </template>
 
 <script setup lang="ts">
-import { onMounted, ref } from 'vue'
+import { computed, onMounted, ref, watchEffect } from 'vue'
 
 import { useI18n } from '@/i18n'
 import { usePlayoutStore } from '@/stores'
@@ -46,8 +47,15 @@ const emit = defineEmits<{
 const { t } = useI18n()
 const playout = usePlayoutStore()
 
-const selectedInput = ref(playout.inputs[0].uri)
+const selectedInput = ref<string>()
+const canSave = computed(() => playout.inputs.some((i) => i.uri === selectedInput.value))
 const dialog = ref()
 
 onMounted(() => dialog.value.open())
+
+watchEffect(() => {
+  if (!selectedInput.value && playout.inputs.length > 0) {
+    selectedInput.value = playout.inputs[0].uri
+  }
+})
 </script>
diff --git a/src/stores/index.ts b/src/stores/index.ts
index d88d77e0..8ce6e37b 100644
--- a/src/stores/index.ts
+++ b/src/stores/index.ts
@@ -22,6 +22,7 @@ export { usePlayoutStore } from '@/stores/playout'
 export { useScheduleStore } from '@/stores/schedules'
 export { useShowStore } from '@/stores/shows'
 export { useTimeSlotStore } from '@/stores/timeslots'
+export { useRadioSettingsStore } from '@/stores/radio-settings'
 export { useRRuleStore } from '@/stores/rrules'
 
 export const useFundingCategoryStore = createUnpaginatedAPIStore<FundingCategory>(
diff --git a/src/stores/playout.ts b/src/stores/playout.ts
index f26ca345..5b15c803 100644
--- a/src/stores/playout.ts
+++ b/src/stores/playout.ts
@@ -1,5 +1,6 @@
 import { defineStore } from 'pinia'
 import { computed, MaybeRefOrGetter, toValue } from 'vue'
+import { useCurrentRadioSettings } from '@/stores/radio-settings'
 
 type Input = {
   uri: string
@@ -13,14 +14,12 @@ export function useInput(uri: MaybeRefOrGetter<string>) {
 }
 
 export const usePlayoutStore = defineStore('playout', () => {
-  // These are hard-coded in engine-core as well
-  // See playout config: https://gitlab.servus.at/aura/engine-core/-/blob/40e7c86373a0029e4db9fd98295997017a92a9e3/config/sample.engine-core.ini#L73
-  // see playout source: https://gitlab.servus.at/aura/engine-core/-/blob/40e7c86373a0029e4db9fd98295997017a92a9e3/src/in_soundcard.liq#L83-105
-  const inputs: Input[] = [
-    { uri: 'line://0', label: 'Studio' },
-    { uri: 'line://1', label: 'Pre-Production' },
-    { uri: 'line://2', label: 'Line 2' },
-  ]
+  const radioSettings = useCurrentRadioSettings()
+
+  const inputs = computed<Input[]>(() => {
+    const inputs = Object.entries(radioSettings.value?.playout?.lineInChannels ?? {})
+    return inputs.map(([id, label]) => ({ uri: `line://${id}`, label }))
+  })
 
   return {
     inputs,
diff --git a/src/stores/radio-settings.ts b/src/stores/radio-settings.ts
new file mode 100644
index 00000000..2262d8ac
--- /dev/null
+++ b/src/stores/radio-settings.ts
@@ -0,0 +1,17 @@
+import { createUnpaginatedAPIStore } from '@/stores/util'
+import { RadioSettings } from '@/types'
+import { createSteeringURL } from '@/api'
+import { steeringAuthInit } from '@/stores/auth'
+import { computed } from 'vue'
+
+export const useRadioSettingsStore = createUnpaginatedAPIStore<RadioSettings>(
+  'radio-settings',
+  createSteeringURL.prefix('settings'),
+  steeringAuthInit,
+  { syncOnAuth: true },
+)
+
+export function useCurrentRadioSettings() {
+  const radioStore = useRadioSettingsStore()
+  return computed<RadioSettings | null>(() => radioStore.items?.[0] ?? null)
+}
diff --git a/src/types.ts b/src/types.ts
index 30cdf15f..c91641d3 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -57,6 +57,7 @@ export type Topic = Required<steeringComponents['schemas']['Topic']>
 export type License = Required<steeringComponents['schemas']['License']>
 export type LinkType = Required<steeringComponents['schemas']['LinkType']>
 export type Link = { typeId: LinkType['id'] | null; url: string }
+export type RadioSettings = Required<steeringComponents['schemas']['RadioSettings']>
 export type RRule = Required<
   Omit<steeringComponents['schemas']['RRule'], 'byWeekdays'> & {
     // this is an extension to ease testing
-- 
GitLab