From 401ee40e6ad8c034e948b9890c0b3eeb4a96f723 Mon Sep 17 00:00:00 2001 From: Jan Starzak Date: Thu, 18 Jan 2024 13:11:17 +0100 Subject: [PATCH] feat(Client): split up RootAppStore and RootOutputStore --- .../src/CurrentRundown/CurrentRundown.tsx | 4 +- .../client/src/CurrentRundown/Segment.tsx | 6 +-- .../client/src/RundownList/RundownEntry.tsx | 4 +- .../client/src/RundownList/RundownList.tsx | 4 +- .../src/RundownScript/RundownScript.tsx | 8 ++-- .../apps/client/src/ScriptEditor/Editor.tsx | 6 +-- .../stores/{AppStore.ts => RootAppStore.ts} | 17 ++++--- .../apps/client/src/stores/RootOutputStore.ts | 48 +++++++++++++++++++ .../apps/client/src/stores/RundownStore.ts | 4 +- packages/apps/client/src/stores/UIStore.ts | 20 +++++--- 10 files changed, 87 insertions(+), 34 deletions(-) rename packages/apps/client/src/stores/{AppStore.ts => RootAppStore.ts} (87%) create mode 100644 packages/apps/client/src/stores/RootOutputStore.ts diff --git a/packages/apps/client/src/CurrentRundown/CurrentRundown.tsx b/packages/apps/client/src/CurrentRundown/CurrentRundown.tsx index b15901e..f06de74 100644 --- a/packages/apps/client/src/CurrentRundown/CurrentRundown.tsx +++ b/packages/apps/client/src/CurrentRundown/CurrentRundown.tsx @@ -1,14 +1,14 @@ import React from 'react' import { action } from 'mobx' import { observer } from 'mobx-react-lite' -import { AppStore } from '../stores/AppStore' +import { RootAppStore } from '../stores/RootAppStore' import { Segment } from './Segment' import { Button } from 'react-bootstrap' import classes from './CurrentRundown.module.scss' import { useNavigate } from 'react-router-dom' const CurrentRundown = observer((): React.JSX.Element => { - const openRundown = AppStore.rundownStore.openRundown + const openRundown = RootAppStore.rundownStore.openRundown const navigate = useNavigate() if (!openRundown) { diff --git a/packages/apps/client/src/CurrentRundown/Segment.tsx b/packages/apps/client/src/CurrentRundown/Segment.tsx index 153c18a..e46f6f8 100644 --- a/packages/apps/client/src/CurrentRundown/Segment.tsx +++ b/packages/apps/client/src/CurrentRundown/Segment.tsx @@ -3,19 +3,19 @@ import { observer } from 'mobx-react-lite' import { UISegment } from '../model/UISegment' import { Line } from './Line' import classes from './CurrentRundown.module.scss' -import { AppStore } from '../stores/AppStore' +import { RootAppStore } from '../stores/RootAppStore' import { UILineId } from '../model/UILine' const Segment = observer(({ segment }: { segment: UISegment }): React.JSX.Element | null => { if (!segment) return null function isSelected(lineId: UILineId) { - return lineId === AppStore.uiStore.selectedLineId + return lineId === RootAppStore.uiStore.selectedLineId } function onClick(e: React.MouseEvent) { const lineId = e.currentTarget.dataset['lineId'] as UILineId - AppStore.uiStore.setSelectedLineId(lineId) + RootAppStore.uiStore.setSelectedLineId(lineId) } return ( diff --git a/packages/apps/client/src/RundownList/RundownEntry.tsx b/packages/apps/client/src/RundownList/RundownEntry.tsx index 2ace4a8..44ccc56 100644 --- a/packages/apps/client/src/RundownList/RundownEntry.tsx +++ b/packages/apps/client/src/RundownList/RundownEntry.tsx @@ -1,12 +1,12 @@ import React from 'react' import { observer } from 'mobx-react-lite' -import { AppStore } from '../stores/AppStore' +import { RootAppStore } from '../stores/RootAppStore' import { UIRundownId } from '../model/UIRundown' import { Button } from 'react-bootstrap' import { useNavigate } from 'react-router-dom' export const RundownEntry = observer(({ rundownId }: { rundownId: UIRundownId }): React.JSX.Element => { - const rundownEntry = AppStore.rundownStore.allRundowns.get(rundownId) + const rundownEntry = RootAppStore.rundownStore.allRundowns.get(rundownId) const navigate = useNavigate() const onOpen = () => { diff --git a/packages/apps/client/src/RundownList/RundownList.tsx b/packages/apps/client/src/RundownList/RundownList.tsx index c1c8022..aacb940 100644 --- a/packages/apps/client/src/RundownList/RundownList.tsx +++ b/packages/apps/client/src/RundownList/RundownList.tsx @@ -1,12 +1,12 @@ import React from 'react' import { keys } from 'mobx' import { observer } from 'mobx-react-lite' -import { AppStore } from '../stores/AppStore' +import { RootAppStore } from '../stores/RootAppStore' import { UIRundownId } from '../model/UIRundown' import { RundownEntry } from './RundownEntry' export const RundownList = observer((): React.JSX.Element => { - const allRundownIds = keys(AppStore.rundownStore.allRundowns) + const allRundownIds = keys(RootAppStore.rundownStore.allRundowns) return ( <> diff --git a/packages/apps/client/src/RundownScript/RundownScript.tsx b/packages/apps/client/src/RundownScript/RundownScript.tsx index 8dddf79..2c6d4f9 100644 --- a/packages/apps/client/src/RundownScript/RundownScript.tsx +++ b/packages/apps/client/src/RundownScript/RundownScript.tsx @@ -5,7 +5,7 @@ import { CurrentRundown } from '../CurrentRundown/CurrentRundown' import { ScriptEditor } from '../ScriptEditor/ScriptEditor' import { Helmet } from 'react-helmet-async' import { RundownPlaylistId, protectString } from '@sofie-prompter-editor/shared-model' -import { AppStore } from '../stores/AppStore' +import { RootAppStore } from '../stores/RootAppStore' import { useParams } from 'react-router-dom' import { SplitPanel } from '../components/SplitPanel/SplitPanel' @@ -17,7 +17,7 @@ const RundownScript = observer((): React.JSX.Element => { useEffect(() => { if (!playlistId) return - AppStore.rundownStore.loadRundown(playlistId) + RootAppStore.rundownStore.loadRundown(playlistId) }, [playlistId]) return ( @@ -27,8 +27,8 @@ const RundownScript = observer((): React.JSX.Element => { AppStore.uiStore.setViewDividerPosition(e.value)} + position={RootAppStore.uiStore.viewDividerPosition} + onChange={(e) => RootAppStore.uiStore.setViewDividerPosition(e.value)} className={classes.RundownScript} childrenBegin={} childrenEnd={} diff --git a/packages/apps/client/src/ScriptEditor/Editor.tsx b/packages/apps/client/src/ScriptEditor/Editor.tsx index 3c3590a..ce351df 100644 --- a/packages/apps/client/src/ScriptEditor/Editor.tsx +++ b/packages/apps/client/src/ScriptEditor/Editor.tsx @@ -14,7 +14,7 @@ import { readOnlyNodeFilter } from './plugins/readOnlyNodeFilter' import { formatingKeymap } from './keymaps' import { deselectAll } from './commands/deselectAll' import { fromMarkdown } from '../lib/prosemirrorDoc' -import { AppStore } from '../stores/AppStore' +import { RootAppStore } from '../stores/RootAppStore' import { IReactionDisposer, reaction } from 'mobx' export function Editor({ @@ -112,7 +112,7 @@ export function Editor({ const mainDisposer = reaction( () => { - const openRundown = AppStore.rundownStore.openRundown + const openRundown = RootAppStore.rundownStore.openRundown if (!openRundown) return null @@ -133,7 +133,7 @@ export function Editor({ console.log(performance.mark('begin')) lineReactionDisposers.forEach((destr) => destr()) - const openRundown = AppStore.rundownStore.openRundown + const openRundown = RootAppStore.rundownStore.openRundown if (!rundown || !editorView.current || !openRundown) return diff --git a/packages/apps/client/src/stores/AppStore.ts b/packages/apps/client/src/stores/RootAppStore.ts similarity index 87% rename from packages/apps/client/src/stores/AppStore.ts rename to packages/apps/client/src/stores/RootAppStore.ts index a6599fd..d494ea9 100644 --- a/packages/apps/client/src/stores/AppStore.ts +++ b/packages/apps/client/src/stores/RootAppStore.ts @@ -1,8 +1,8 @@ import type EventEmitter from 'eventemitter3' import { action, makeObservable, observable } from 'mobx' -import { RundownStore } from './RundownStore' -import { MockConnection } from '../mocks/MockConnection' -import { UIStore } from './UIStore' +import { RundownStore } from './RundownStore.ts' +import { MockConnection } from '../mocks/MockConnection.ts' +import { UIStore } from './UIStore.ts' import { APIConnection as APIConnectionImpl } from '../api/ApiConnection.ts' import { FeathersTypedService } from '../api/lib.ts' import { @@ -19,7 +19,7 @@ import { const USE_MOCK_CONNECTION = false -class AppStoreClass { +class RootAppStoreClass { connected = false connection: APIConnection rundownStore: RundownStore @@ -50,7 +50,7 @@ class AppStoreClass { }) } -export const AppStore = new AppStoreClass() +export const RootAppStore = new RootAppStoreClass() export interface APIConnection extends EventEmitter { readonly connected: boolean @@ -58,15 +58,14 @@ export interface APIConnection extends EventEmitter { readonly port: number readonly systemStatus: FeathersTypedService + readonly controller: FeathersTypedService + readonly outputSettings: FeathersTypedService + readonly viewPort: FeathersTypedService readonly playlist: FeathersTypedService readonly rundown: FeathersTypedService readonly segment: FeathersTypedService readonly part: FeathersTypedService - readonly controllerMessage: FeathersTypedService - readonly outputSettings: FeathersTypedService - readonly viewPort: FeathersTypedService - readonly example: FeathersTypedService } diff --git a/packages/apps/client/src/stores/RootOutputStore.ts b/packages/apps/client/src/stores/RootOutputStore.ts new file mode 100644 index 0000000..a732d5b --- /dev/null +++ b/packages/apps/client/src/stores/RootOutputStore.ts @@ -0,0 +1,48 @@ +import { IReactionDisposer, action, makeObservable, observable, reaction } from 'mobx' +import { APIConnection } from './RootAppStore.js' +import { APIConnection as APIConnectionImpl } from '../api/ApiConnection.js' + +export class OutputStore { + reactions: IReactionDisposer[] = [] + connection: APIConnection + connected = false + + constructor() { + makeObservable(this, { + connected: observable, + }) + + const apiConnection = new APIConnectionImpl() + this.connection = apiConnection + this.connection.on('disconnected', this.onDisconnected) + + this.connection.on('connected', this.onConnected) + } + + onConnected = action('onConnected', () => { + this.connected = true + }) + + onDisconnected = action('onDisconnected', () => { + this.connected = false + }) + + setupUIOutputSubscriptions = action(() => { + this.reactions.push( + reaction( + () => this.connected, + async (connected) => { + if (!connected) return + + await this.connection.viewPort.subscribeToViewPort('') + }, + { + fireImmediately: true, + } + ) + ) + + // this.connection.playlist.on('created', this.onPlaylistCreated) + // Note: updated and removed events are handled by the UIRundownEntry's themselves + }) +} diff --git a/packages/apps/client/src/stores/RundownStore.ts b/packages/apps/client/src/stores/RundownStore.ts index 39810c8..3f0deb9 100644 --- a/packages/apps/client/src/stores/RundownStore.ts +++ b/packages/apps/client/src/stores/RundownStore.ts @@ -1,6 +1,6 @@ import { observable, action, flow, makeObservable, IReactionDisposer, reaction } from 'mobx' import { RundownPlaylist, RundownPlaylistId } from '@sofie-prompter-editor/shared-model' -import { APIConnection, AppStore } from './AppStore' +import { APIConnection, RootAppStore } from './RootAppStore' import { UIRundown } from '../model/UIRundown' import { UIRundownEntry } from '../model/UIRundownEntry' @@ -12,7 +12,7 @@ export class RundownStore { reactions: IReactionDisposer[] = [] - constructor(public appStore: typeof AppStore, public connection: APIConnection) { + constructor(public appStore: typeof RootAppStore, public connection: APIConnection) { makeObservable(this, { openRundown: observable, showingOnlyScripts: observable, diff --git a/packages/apps/client/src/stores/UIStore.ts b/packages/apps/client/src/stores/UIStore.ts index 1483df2..625f7c1 100644 --- a/packages/apps/client/src/stores/UIStore.ts +++ b/packages/apps/client/src/stores/UIStore.ts @@ -1,19 +1,25 @@ -import { makeAutoObservable } from 'mobx' +import { action, makeAutoObservable, makeObservable, observable } from 'mobx' import { UILineId } from '../model/UILine' export class UIStore { - viewDividerPosition: number = 0.5 + viewDividerPosition: number = 0 selectedLineId: UILineId | null = null constructor() { - makeAutoObservable(this) + makeObservable(this, { + viewDividerPosition: observable, + selectedLineId: observable, + }) + + this.viewDividerPosition = Number(window.localStorage.getItem('viewDividerPosition')) || 0.5 } - setViewDividerPosition(value: number) { + setViewDividerPosition = action('setViewDividerPosition', (value: number) => { this.viewDividerPosition = value - } + window.localStorage.setItem('viewDividerPosition', String(value)) + }) - setSelectedLineId(lineId: UILineId | null) { + setSelectedLineId = action('setSelectedLineId', (lineId: UILineId | null) => { this.selectedLineId = lineId - } + }) }