Skip to content

Commit

Permalink
wip: realtime api using feathers.js
Browse files Browse the repository at this point in the history
  • Loading branch information
ianshade committed Sep 20, 2023
1 parent a43a451 commit e794ca7
Show file tree
Hide file tree
Showing 28 changed files with 933 additions and 313 deletions.
6 changes: 6 additions & 0 deletions apps/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
"@babel/core": "^7.22.1",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@feathersjs/errors": "^5.0.8",
"@feathersjs/feathers": "^5.0.8",
"@feathersjs/koa": "^5.0.8",
"@feathersjs/socketio": "^5.0.8",
"@feathersjs/socketio-client": "^5.0.8",
"@fontsource/barlow": "^4.5.9",
"@fontsource/barlow-condensed": "^4.5.9",
"@fontsource/barlow-semi-condensed": "^4.5.10",
Expand Down Expand Up @@ -110,6 +115,7 @@
"react-visibility-sensor": "^5.1.1",
"semver": "^7.5.0",
"short-uuid": "^4.2.2",
"socket.io-client": "^4.7.2",
"superfly-timeline": "^8.3.1",
"timeline-state-resolver-types": "7.5.0-nightly-release47-20221116-134940-9a43f95c5.0",
"tiny-warning": "^1.0.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Project } from '../models/project/Project'
import { MetadataAny, ResourceAny, ResourceId, SerializedProtectedMap, TSRDeviceId } from '@shared/models'
import { Rundown } from '../models/rundown/Rundown'
import { PeripheralStatus } from '../models/project/Peripheral'
import { BrowserWindow } from 'electron'
import { IPCClientMethods, SystemMessageOptions } from '../ipc/IPCAPI'
import { AppData } from '../models/App/AppData'
import { ActiveTriggers } from '../models/rundown/Trigger'
Expand All @@ -12,58 +11,57 @@ import { ActiveAnalog } from '../models/rundown/Analog'
import { AnalogInput } from '../models/project/AnalogInput'
import { BridgeId } from '@shared/api'
import { BridgePeripheralId } from '@shared/lib'
import { EventEmitter } from 'stream'

/** This class is used server-side, to send messages to the client */
export class IPCClient implements IPCClientMethods {
constructor(private mainWindow: BrowserWindow) {}

// --- some of it might be needed, most of it hopefully not
export class ClientEventBus extends EventEmitter implements IPCClientMethods {
close(): void {
// Nothing here
}

systemMessage(message: string, options: SystemMessageOptions): void {
this.mainWindow?.webContents.send('callMethod', 'systemMessage', message, options)
this.emit('callMethod', 'systemMessage', message, options)
}
updateAppData(appData: AppData): void {
this.mainWindow?.webContents.send('callMethod', 'updateAppData', appData)
this.emit('callMethod', 'updateAppData', appData)
}
updateProject(project: Project): void {
this.mainWindow?.webContents.send('callMethod', 'updateProject', project)
this.emit('callMethod', 'updateProject', project)
}
updateRundown(fileName: string, rundown: Rundown): void {
this.mainWindow?.webContents.send('callMethod', 'updateRundown', fileName, rundown)
this.emit('callMethod', 'updateRundown', fileName, rundown)
}
updateResourcesAndMetadata(
resources: Array<{ id: ResourceId; resource: ResourceAny | null }>,
metadata: SerializedProtectedMap<TSRDeviceId, MetadataAny | null>
): void {
this.mainWindow?.webContents.send('callMethod', 'updateResourcesAndMetadata', resources, metadata)
this.emit('callMethod', 'updateResourcesAndMetadata', resources, metadata)
}
updateBridgeStatus(id: BridgeId, status: BridgeStatus | null): void {
this.mainWindow?.webContents.send('callMethod', 'updateBridgeStatus', id, status)
this.emit('callMethod', 'updateBridgeStatus', id, status)
}
updatePeripheral(peripheralId: BridgePeripheralId, peripheral: PeripheralStatus | null): void {
this.mainWindow?.webContents.send('callMethod', 'updatePeripheral', peripheralId, peripheral)
this.emit('callMethod', 'updatePeripheral', peripheralId, peripheral)
}
updatePeripheralTriggers(peripheralTriggers: ActiveTriggers): void {
this.mainWindow?.webContents.send('callMethod', 'updatePeripheralTriggers', peripheralTriggers)
this.emit('callMethod', 'updatePeripheralTriggers', peripheralTriggers)
}
updatePeripheralAnalog(fullIdentifier: string, analog: ActiveAnalog | null): void {
this.mainWindow?.webContents.send('callMethod', 'updatePeripheralAnalog', fullIdentifier, analog)
this.emit('callMethod', 'updatePeripheralAnalog', fullIdentifier, analog)
}
updateDeviceRefreshStatus(deviceId: TSRDeviceId, refreshing: boolean): void {
this.mainWindow?.webContents.send('callMethod', 'updateDeviceRefreshStatus', deviceId, refreshing)
this.emit('callMethod', 'updateDeviceRefreshStatus', deviceId, refreshing)
}
displayAboutDialog(): void {
this.mainWindow?.webContents.send('callMethod', 'displayAboutDialog')
this.emit('callMethod', 'displayAboutDialog')
}
updateDefiningArea(definingArea: DefiningArea | null): void {
this.mainWindow?.webContents.send('callMethod', 'updateDefiningArea', definingArea)
this.emit('callMethod', 'updateDefiningArea', definingArea)
}
updateFailedGlobalTriggers(identifiers: string[]): void {
this.mainWindow?.webContents.send('callMethod', 'updateFailedGlobalTriggers', identifiers)
this.emit('callMethod', 'updateFailedGlobalTriggers', identifiers)
}
updateAnalogInput(fullIdentifier: string, analogInput: AnalogInput | null): void {
this.mainWindow?.webContents.send('callMethod', 'updateAnalogInput', fullIdentifier, analogInput)
this.emit('callMethod', 'updateAnalogInput', fullIdentifier, analogInput)
}
}
118 changes: 0 additions & 118 deletions apps/app/src/electron/HTTPAPI.ts

This file was deleted.

25 changes: 14 additions & 11 deletions apps/app/src/electron/IPCServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ type ConvertToServerSide<T> = {
}

/** This class is used server-side, to handle requests from the client */
export class IPCServer
export class EverythingService
extends (EventEmitter as new () => TypedEmitter<IPCServerEvents>)
implements ConvertToServerSide<IPCServerMethods>
{
Expand Down Expand Up @@ -153,7 +153,7 @@ export class IPCServer
}
) {
super()
for (const methodName of Object.getOwnPropertyNames(IPCServer.prototype)) {
for (const methodName of Object.getOwnPropertyNames(EverythingService.prototype)) {
if (methodName[0] !== '_') {
const fcn = (this as any)[methodName].bind(this)
if (fcn) {
Expand Down Expand Up @@ -324,9 +324,6 @@ export class IPCServer

this.callbacks.onClientConnected()
}
async triggerSendRundown(arg: { rundownId: string }): Promise<void> {
this.storage.triggerEmitRundown(arg.rundownId)
}
async setKeyboardKeys(arg: { activeKeys: ActiveTrigger[] }): Promise<void> {
this.callbacks.setKeyboardKeys(arg.activeKeys)
}
Expand Down Expand Up @@ -415,23 +412,26 @@ export class IPCServer
return this.storage.openProject(arg.projectId)
}

async playPart(arg: { rundownId: string; groupId: string; partId: string }): Promise<void> {
async playPart(arg: { rundownId: string; groupId: string; partId: string }): Promise<Rundown> {
const now = Date.now()
const { rundown, group, part } = this.getPart(arg)

RundownActions.playPart(group, part, now)

this._saveUpdates({ rundownId: arg.rundownId, rundown, group })
return rundown // this should return something more granular (group or part)
}

async pausePart(arg: { rundownId: string; groupId: string; partId: string; time?: number }): Promise<void> {
async pausePart(arg: { rundownId: string; groupId: string; partId: string; time?: number }): Promise<Rundown> {
const now = Date.now()
const { rundown, group, part } = this.getPart(arg)
updateGroupPlayingParts(group)
RundownActions.pausePart(group, part, arg.time, now)

this._saveUpdates({ rundownId: arg.rundownId, rundown, group })
return rundown
}

async pauseParts(arg: { rundownId: string; groupId: string; partIds: string[]; time?: number }): Promise<void> {
const now = Date.now()
const { rundown, group } = this.getGroup({
Expand All @@ -451,14 +451,16 @@ export class IPCServer
this._saveUpdates({ rundownId: arg.rundownId, rundown, group })
}

async stopPart(arg: { rundownId: string; groupId: string; partId: string }): Promise<void> {
async stopPart(arg: { rundownId: string; groupId: string; partId: string }): Promise<Rundown> {
const now = Date.now()
const { rundown, group } = this.getGroup(arg)

RundownActions.stopPart(group, arg.partId, now)

this._saveUpdates({ rundownId: arg.rundownId, rundown, group })
return rundown
}

async setPartTrigger(arg: {
rundownId: string
groupId: string
Expand Down Expand Up @@ -2200,8 +2202,9 @@ export class IPCServer
async updateProject(arg: { id: string; project: Project }): Promise<void> {
this._saveUpdates({ project: arg.project })
}
async newRundown(arg: { name: string }): Promise<UndoableResult<string>> {
const fileName = this.storage.newRundown(arg.name)
async newRundown(arg: { name: string }): Promise<UndoableResult<Rundown>> {
const rundown = this.storage.newRundown(arg.name)
const fileName = rundown.name
this._saveUpdates({})

return {
Expand All @@ -2210,7 +2213,7 @@ export class IPCServer
this._saveUpdates({})
},
description: ActionDescription.NewRundown,
result: fileName,
result: rundown,
}
}
async deleteRundown(arg: { rundownId: string }): Promise<void> {
Expand Down
Loading

0 comments on commit e794ca7

Please sign in to comment.