Files
NTSH-Control/frontend/views/control/ts/main.ts

190 lines
4.2 KiB
TypeScript

import { io } from 'socket.io-client';
import { Menu } from './menu';
import { Checklist } from './checklist';
import { Calibration } from './calibration';
import { ce, MorphComponent, MorphFeature } from 'morphux';
import { OutOfServiceMode } from './outOfServiceMode';
import { Timer } from './timer';
import { Lighting } from './lighting';
import { Sound } from './sound';
const socket = io('/');
export class Main {
Menu = new Menu();
CheckList = new Checklist(this);
Calibration = new Calibration(this);
OutOfServiceMode = new OutOfServiceMode(this);
Timer = new Timer(this);
Lighting = new Lighting(this);
Sound = new Sound(this);
socket = socket;
supportButton: HTMLDivElement = document.querySelector('.ntsh-support img');
supportNumber: string = '';
constructor() {
this.registerListeners();
}
private registerListeners() {
this.supportButton.onclick = () => this.showSupport();
socket.on('status', (data) => {
this.CheckList.update(data);
});
socket.on('supportNumber', (number: string) => {
this.supportNumber = number;
});
socket.on('unityWebSocketState', (state: UnityWebSocketStatus) => {
this.OutOfServiceMode.input.checked =
state?.parameters?.outOfService ?? false;
this.OutOfServiceMode.state =
state?.parameters?.outOfService ?? false;
this.Lighting.update(state);
this.Sound.update(state);
});
socket.on('timer', (data) => {
this.Timer.update(data);
});
}
async executeCommand(
command: string,
message: string,
type: 'unityRunner' | 'unityWebSocket' = 'unityRunner',
): Promise<boolean> {
return new Promise<boolean>(async (resolve) => {
const confirmed = await MorphFeature.Confirm({
title: 'Are you sure?',
message,
});
if (!confirmed) return resolve(false);
MorphFeature.Loader({
active: true,
message: `Dispatching command...`,
});
socket.emit(
type,
command,
(response: { succeed: boolean; message?: string }) => {
MorphFeature.Loader({ active: false });
if (!response.succeed)
return MorphFeature.Alert({
title: 'Error',
message: response.message,
});
MorphFeature.Notification({
level: 'success',
message: `Dispatched command`,
});
},
);
resolve(true);
});
}
async showSupport() {
const dialog = new MorphComponent.Dialog({
title: 'Contact Support',
width: 'medium',
height: 'auto',
okButtonVisible: false,
cancelButtonVisible: false,
});
this.supportNumber.slice();
const callAnchor = ce(
'a',
'ntsh_callanchor',
{ href: `tel:${this.supportNumber}` },
`+${this.supportNumber}`,
);
dialog.content.appendChild(callAnchor);
setTimeout(() => callAnchor.click(), 100);
}
}
const _Main = new Main();
export type ServiceState =
| 'CONNECTING'
| 'CONNECTED'
| 'DISCONNECTED'
| 'FAILED';
export interface UnityWebSocketStatus {
state: ServiceState;
message?: string;
error?: string;
parameters: UnityParameters;
}
interface UnityParameters {
timelineWatching: boolean;
timelineStanding: boolean;
timelineProgress: number;
zedPath: string;
zedReady: boolean;
zedFPS: string;
outOfService: boolean;
sliders: UnityParameterSlider[];
advancedSliders: UnityParameterSlider[];
// dataSliders: UnityParameterSlider[];
// dataAdvancedSliders: UnityParameterSlider[];
sensors: UnitySocketMessageHeartbeat['heartbeat']['dataSensors'];
}
type UnityHeartbeatSlider =
UnitySocketMessageHeartbeat['heartbeat']['dataSliders'][number];
interface UnityParameterSlider extends UnityHeartbeatSlider {
visualMultiplier: number;
decimalPlaces: number;
}
interface UnitySocketMessageBase {
type: string;
timestamp: number;
}
interface UnitySocketMessageHeartbeat extends UnitySocketMessageBase {
type: 'heartbeat_data';
heartbeat: {
dataSensors: {
sensorIndex: number;
deviceName: string;
outputValue: number;
}[];
dataSliders: {
sliderIndex: number;
sliderName: string;
outputValue: number;
min: number;
max: number;
unit: string;
}[];
dataTimeline: {
isStanding: boolean;
isWatching: boolean;
timelineProgress: number;
};
zedCamera: {
cameraFPS: string;
isZedReady: boolean;
streamInputIP: string;
streamInputPort: number;
zedGrabError: number;
};
showOutOfService?: boolean;
};
}