import { HubConnectionBuilder } from "@microsoft/signalr/dist/browser/signalr"; import { Inject } from "@web-atoms/core/dist/di/Inject"; import { AtomViewModel, Receive, Watch } from "@web-atoms/core/dist/view-model/AtomViewModel"; import Load from "@web-atoms/core/dist/view-model/Load"; import Channels from "../../Channels"; import EditorIDService from "../../services/EditorIDService"; import SourceService from "../../services/SourceService"; export interface IDevice { id: string; name: string; } export interface IDebugSession { id: string; device?: IDevice; logs?: any[]; } export default class MessagesViewModel extends AtomViewModel { public views = [ { label: "Problems", value: "problems" }, { label: "Storage", value: "storage" } ]; public selectedView: string = "problems"; @Watch public get selectedLogs(): any[] { const selectedView = this.selectedView; if (selectedView === "problems") { return undefined; } return this.sessionCache[this.selectedView].logs; } @Inject public sourceService: SourceService; @Inject public editorIDService: EditorIDService; public sessions: IDebugSession[] = [ { id: "storage", device: { id: "storage", name: "Storage" }, logs: [] } ]; private sessionCache: {[key: string]: IDebugSession} = { storage: this.sessions[0] }; private connection: any; @Receive(Channels.Log) public receiveLog(name: string, data: any) { const c = this.sessionCache.storage; c.logs.add(data); this.selectedView = "storage"; } @Load({ init: true, watch: true }) public async loadSignalR() { if (!this.sourceService.folder) { return; } if (this.connection) { // do only once.. return; } const folder = this.sourceService.folder.root; const eid = this.editorIDService.getID(folder); this.connection = (new HubConnectionBuilder()) .withUrl("/play-console") .withAutomaticReconnect() .build(); this.connection.on("log", (id, log) => { this.updateSession([log]); }); this.connection.on("sessions", (id, logs) => { this.editorIDService.setID(folder, id); this.updateSession(logs); }); await this.connection.start(); await this.connection.send("init", eid); } private updateSession(logs: any[]) { let lastID = null; for (const iterator of logs) { const device = this.getSession(iterator.id); if (device.device) { lastID = device.device.id; } if (iterator.type) { device.device = iterator; this.views.add({ label: device.device.name, value: device.id }); lastID = device.id; } else { for (const log of iterator.logs) { device.logs.add(log); } } } if (lastID) { this.selectedView = lastID; } } private getSession(id) { let device = this.sessionCache[id]; if (!device) { device = { id, logs: [] }; this.sessionCache[id] = device; this.sessions.add(device); } return device; } }