From 5512836472e7ca35e43d61231135e9e28e499897 Mon Sep 17 00:00:00 2001
From: Jan Starzak
Date: Thu, 18 Jan 2024 16:37:17 +0100
Subject: [PATCH] feat: whenConnected helper method on RootAppStore
---
.../src/CurrentRundown/CurrentRundown.tsx | 9 ++++
.../client/src/RundownList/RundownList.tsx | 2 +
.../src/components/AlertBar/AlertBar.tsx | 14 ++++++
.../SystemStatusAlertBars.tsx | 16 +++++++
.../apps/client/src/stores/RootAppStore.ts | 33 ++++++++++++-
.../apps/client/src/stores/RundownStore.ts | 46 +++++++++++++------
6 files changed, 105 insertions(+), 15 deletions(-)
create mode 100644 packages/apps/client/src/components/AlertBar/AlertBar.tsx
create mode 100644 packages/apps/client/src/components/SystemStatusAlertBars/SystemStatusAlertBars.tsx
diff --git a/packages/apps/client/src/CurrentRundown/CurrentRundown.tsx b/packages/apps/client/src/CurrentRundown/CurrentRundown.tsx
index f06de74..a735d9d 100644
--- a/packages/apps/client/src/CurrentRundown/CurrentRundown.tsx
+++ b/packages/apps/client/src/CurrentRundown/CurrentRundown.tsx
@@ -6,6 +6,7 @@ import { Segment } from './Segment'
import { Button } from 'react-bootstrap'
import classes from './CurrentRundown.module.scss'
import { useNavigate } from 'react-router-dom'
+import { SystemStatusAlertBars } from '../components/SystemStatusAlertBars/SystemStatusAlertBars'
const CurrentRundown = observer((): React.JSX.Element => {
const openRundown = RootAppStore.rundownStore.openRundown
@@ -20,6 +21,10 @@ const CurrentRundown = observer((): React.JSX.Element => {
navigate('/')
})
+ const onSendToOutput = action(() => {
+ RootAppStore.rundownStore.sendRundownToOutput(openRundown.id)
+ })
+
return (
<>
{openRundown.name}
@@ -27,7 +32,11 @@ const CurrentRundown = observer((): React.JSX.Element => {
+
+
{openRundown.segmentsInOrder.map((segment) => (
-
diff --git a/packages/apps/client/src/RundownList/RundownList.tsx b/packages/apps/client/src/RundownList/RundownList.tsx
index aacb940..55d44fd 100644
--- a/packages/apps/client/src/RundownList/RundownList.tsx
+++ b/packages/apps/client/src/RundownList/RundownList.tsx
@@ -4,12 +4,14 @@ import { observer } from 'mobx-react-lite'
import { RootAppStore } from '../stores/RootAppStore'
import { UIRundownId } from '../model/UIRundown'
import { RundownEntry } from './RundownEntry'
+import { SystemStatusAlertBars } from '../components/SystemStatusAlertBars/SystemStatusAlertBars'
export const RundownList = observer((): React.JSX.Element => {
const allRundownIds = keys(RootAppStore.rundownStore.allRundowns)
return (
<>
+
{allRundownIds.map((rundownId) => (
-
diff --git a/packages/apps/client/src/components/AlertBar/AlertBar.tsx b/packages/apps/client/src/components/AlertBar/AlertBar.tsx
new file mode 100644
index 0000000..5e97c6c
--- /dev/null
+++ b/packages/apps/client/src/components/AlertBar/AlertBar.tsx
@@ -0,0 +1,14 @@
+import React from 'react'
+import { Alert } from 'react-bootstrap'
+
+export function AlertBar({
+ children,
+ variant,
+}: {
+ children?: React.ReactNode
+ variant?: AlertVariants
+}): React.JSX.Element {
+ return {children}
+}
+
+type AlertVariants = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark'
diff --git a/packages/apps/client/src/components/SystemStatusAlertBars/SystemStatusAlertBars.tsx b/packages/apps/client/src/components/SystemStatusAlertBars/SystemStatusAlertBars.tsx
new file mode 100644
index 0000000..cf5a22a
--- /dev/null
+++ b/packages/apps/client/src/components/SystemStatusAlertBars/SystemStatusAlertBars.tsx
@@ -0,0 +1,16 @@
+import { observer } from 'mobx-react-lite'
+import React from 'react'
+import { RootAppStore } from '../../stores/RootAppStore'
+import { AlertBar } from '../AlertBar/AlertBar'
+
+export const SystemStatusAlertBars = observer(function SystemStatusAlertBars(): React.JSX.Element {
+ const isAPIConnected = RootAppStore.connected
+ const isSofieConnected = RootAppStore.sofieConnected
+ return (
+ <>
+ {!isAPIConnected ? Prompter is having network troubles : null}
+ {isSofieConnected ? Prompter is having network troubles : null}
+ >
+ )
+})
+SystemStatusAlertBars.displayName = 'SystemStatusAlertBars'
diff --git a/packages/apps/client/src/stores/RootAppStore.ts b/packages/apps/client/src/stores/RootAppStore.ts
index 6f1283f..3101d5f 100644
--- a/packages/apps/client/src/stores/RootAppStore.ts
+++ b/packages/apps/client/src/stores/RootAppStore.ts
@@ -1,5 +1,5 @@
import type EventEmitter from 'eventemitter3'
-import { action, makeObservable, observable } from 'mobx'
+import { IReactionDisposer, action, makeObservable, observable, reaction } from 'mobx'
import { RundownStore } from './RundownStore.ts'
import { MockConnection } from '../mocks/MockConnection.ts'
import { UIStore } from './UIStore.ts'
@@ -22,6 +22,7 @@ const USE_MOCK_CONNECTION = false
class RootAppStoreClass {
connected = false
+ sofieConnected = false
connection: APIConnection
rundownStore: RundownStore
outputSettingsStore: OutputSettingsStore
@@ -30,6 +31,7 @@ class RootAppStoreClass {
constructor() {
makeObservable(this, {
connected: observable,
+ sofieConnected: observable,
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -42,15 +44,44 @@ class RootAppStoreClass {
this.connection.on('disconnected', this.onDisconnected)
this.connection.on('connected', this.onConnected)
+
+ this.connection.systemStatus.subscribe()
+ this.connection.systemStatus.on('updated', this.onSystemStatusUpdated)
+
+ this.connection.systemStatus.get('').then(this.onSystemStatusUpdated)
}
+ onSystemStatusUpdated = action(
+ 'onSystemStatusUpdated',
+ (systemStatus: { statusMessage: string | null; connectedToCore: boolean }) => {
+ console.log(systemStatus)
+ this.sofieConnected = systemStatus.connectedToCore
+ }
+ )
+
onConnected = action('onConnected', () => {
+ console.log('Backend connected')
this.connected = true
})
onDisconnected = action('onDisconnected', () => {
+ console.log('Backend disconnected')
this.connected = false
})
+
+ whenConnected = (clb: () => void | Promise): IReactionDisposer => {
+ return reaction(
+ () => this.connected,
+ async (connected) => {
+ if (!connected) return
+
+ await clb()
+ },
+ {
+ fireImmediately: true,
+ }
+ )
+ }
}
export const RootAppStore = new RootAppStoreClass()
diff --git a/packages/apps/client/src/stores/RundownStore.ts b/packages/apps/client/src/stores/RundownStore.ts
index 3f0deb9..4f606f8 100644
--- a/packages/apps/client/src/stores/RundownStore.ts
+++ b/packages/apps/client/src/stores/RundownStore.ts
@@ -1,5 +1,5 @@
import { observable, action, flow, makeObservable, IReactionDisposer, reaction } from 'mobx'
-import { RundownPlaylist, RundownPlaylistId } from '@sofie-prompter-editor/shared-model'
+import { OutputSettings, RundownPlaylist, RundownPlaylistId } from '@sofie-prompter-editor/shared-model'
import { APIConnection, RootAppStore } from './RootAppStore'
import { UIRundown } from '../model/UIRundown'
import { UIRundownEntry } from '../model/UIRundownEntry'
@@ -10,33 +10,42 @@ export class RundownStore {
allRundowns = observable.map()
openRundown: UIRundown | null = null
+ outputSettings: OutputSettings | null = null
+
reactions: IReactionDisposer[] = []
constructor(public appStore: typeof RootAppStore, public connection: APIConnection) {
makeObservable(this, {
openRundown: observable,
showingOnlyScripts: observable,
+ outputSettings: observable,
})
// get all rundowns
this.setupUIRundownDataSubscriptions()
this.loadAllUIRundownData()
+
+ this.setupOutputSettingsSubscription()
+ this.loadOutputSettingsData()
}
+ setupOutputSettingsSubscription = action(() => {
+ this.reactions.push(this.appStore.whenConnected(() => this.connection.outputSettings.subscribeToController()))
+
+ this.connection.outputSettings.on('created', this.onOutputSettingsUpdated)
+ this.connection.outputSettings.on('updated', this.onOutputSettingsUpdated)
+ })
+
+ private onOutputSettingsUpdated = action('onOutputSettingsUpdated', (outputSettings: OutputSettings) => {
+ this.outputSettings = outputSettings
+ })
+
+ loadOutputSettingsData = action(() => {
+ this.connection.outputSettings.get('').then(this.onOutputSettingsUpdated)
+ })
+
setupUIRundownDataSubscriptions = action(() => {
- this.reactions.push(
- reaction(
- () => this.appStore.connected,
- async (connected) => {
- if (!connected) return
-
- await this.connection.playlist.subscribeToPlaylists()
- },
- {
- fireImmediately: true,
- }
- )
- )
+ this.reactions.push(this.appStore.whenConnected(() => this.connection.playlist.subscribeToPlaylists()))
this.connection.playlist.on('created', this.onPlaylistCreated)
// Note: updated and removed events are handled by the UIRundownEntry's themselves
@@ -86,6 +95,15 @@ export class RundownStore {
this.openRundown = newRundown
})
+ sendRundownToOutput = (id: RundownPlaylistId) => {
+ if (!this.outputSettings) return
+ // TODO: This really shouldn't require the entire outputSettings object to be available first
+ this.connection.outputSettings.update('', {
+ ...this.outputSettings,
+ activeRundownPlaylistId: id,
+ })
+ }
+
destroy = () => {
this.reactions.forEach((dispose) => dispose())
}