From f0f81c19b610cdec8c141a2576f146136446ce7a Mon Sep 17 00:00:00 2001 From: Johan Nyman Date: Wed, 24 Jan 2024 09:09:49 +0100 Subject: [PATCH] fix: restore timelines upon startup. closes #185 --- apps/app/src/electron/SuperConductor.ts | 18 ++++++++++++ apps/app/src/electron/bridgeHandler.ts | 38 ++++++++++++++++++------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/apps/app/src/electron/SuperConductor.ts b/apps/app/src/electron/SuperConductor.ts index 749493a0..dd82ea78 100644 --- a/apps/app/src/electron/SuperConductor.ts +++ b/apps/app/src/electron/SuperConductor.ts @@ -33,6 +33,8 @@ import { ActiveAnalog } from '../models/rundown/Analog' import { AnalogHandler } from './analogHandler' import { AnalogInput } from '../models/project/AnalogInput' import { SystemMessageOptions } from '../ipc/IPCAPI' +import { getTimelineForGroup } from '../lib/timeline' +import { TSRTimeline } from 'timeline-state-resolver-types' export class SuperConductor { ipcServer: IPCServer @@ -256,6 +258,8 @@ export class SuperConductor { } else { this.httpAPI = new HTTPAPI(this.internalHttpApiPort, this.ipcServer, this.log) } + + this._restoreTimelines() } sendSystemMessage(message: string, options: SystemMessageOptions): void { this.clients.forEach((clients) => clients.ipcClient.systemMessage(message, options)) @@ -509,6 +513,20 @@ export class SuperConductor { return updateTimeline(this.storage, this.bridgeHandler, group) } + private _restoreTimelines() { + const project = this.storage.getProject() + + const openRundowns = this.storage.getAllRundowns() + + for (const openRundown of openRundowns) { + for (const group of openRundown.groups) { + const timeline = getTimelineForGroup(group, group.preparedPlayData, undefined) as TSRTimeline + this.bridgeHandler.updateTimeline(group.id, timeline) + } + } + + this.bridgeHandler.updateMappings(project.mappings) + } /** * Is called when the app is starting to shut down. diff --git a/apps/app/src/electron/bridgeHandler.ts b/apps/app/src/electron/bridgeHandler.ts index 48cb1291..ef25786d 100644 --- a/apps/app/src/electron/bridgeHandler.ts +++ b/apps/app/src/electron/bridgeHandler.ts @@ -25,6 +25,12 @@ export const SERVER_PORT = 5400 type AnyBridgeConnection = WebsocketBridgeConnection | LocalBridgeConnection +interface BridgeHandlerCallbacks { + updatedResources: (deviceId: string, resources: ResourceAny[]) => void + onVersionMismatch: (bridgeId: string, bridgeVersion: string, ourVersion: string) => void + onDeviceRefreshStatus: (deviceId: string, refreshing: boolean) => void +} + /** This handles connected bridges */ export class BridgeHandler { server: WebsocketServer @@ -55,7 +61,7 @@ export class BridgeHandler { private log: LoggerLike, private session: SessionHandler, private storage: StorageHandler, - private callbacks: BridgeConnectionCallbacks + private callbacks: BridgeHandlerCallbacks ) { this.server = new WebsocketServer(this.log, SERVER_PORT, (connection: WebsocketConnection) => { // On connection: @@ -65,7 +71,7 @@ export class BridgeHandler { this.session, this.storage, connection, - this.callbacks + this.getBridgeConnectionCallbacks() ) // Lookup and set the bridgeId, if it is an outgoing @@ -106,7 +112,12 @@ export class BridgeHandler { if (this.closed) return if (project.settings.enableInternalBridge) { if (!this.internalBridge) { - this.internalBridge = new LocalBridgeConnection(this.log, this.session, this.storage, this.callbacks) + this.internalBridge = new LocalBridgeConnection( + this.log, + this.session, + this.storage, + this.getBridgeConnectionCallbacks() + ) this.connectedBridges.push(this.internalBridge) } } else { @@ -292,12 +303,18 @@ export class BridgeHandler { bridgeConnection.refreshResources() } } + private getBridgeConnectionCallbacks(): BridgeConnectionCallbacks { + return { + ...this.callbacks, + getTimelines: () => this.timelines, + getMappings: () => this.mappings, + } + } } -interface BridgeConnectionCallbacks { - updatedResources: (deviceId: string, resources: ResourceAny[]) => void - onVersionMismatch: (bridgeId: string, bridgeVersion: string, ourVersion: string) => void - onDeviceRefreshStatus: (deviceId: string, refreshing: boolean) => void +interface BridgeConnectionCallbacks extends BridgeHandlerCallbacks { + getTimelines: () => { [timelineId: string]: TSRTimeline } + getMappings: () => Mappings } abstract class AbstractBridgeConnection { @@ -399,10 +416,11 @@ abstract class AbstractBridgeConnection { } else { this.log.error(`Error: Settings bridge "${this.bridgeId}" not found`) } - if (this.sentMappings) { - this.setMappings(this.sentMappings, true) + const mappings = this.callbacks.getMappings() + if (mappings) { + this.setMappings(mappings, true) } - for (const [timelineId, timeline] of Object.entries(this.sentTimelines)) { + for (const [timelineId, timeline] of Object.entries(this.callbacks.getTimelines())) { this.addTimeline(timelineId, timeline) } // Sync timelineIds: