diff --git a/src/component/internal/messages.ts b/src/component/internal/messages.ts index e69de29b..ff88fde3 100644 --- a/src/component/internal/messages.ts +++ b/src/component/internal/messages.ts @@ -0,0 +1,162 @@ +import Vue from 'vue' +import * as EVENT from '../types/events' +import * as message from '../types/messages' + +import EventEmitter from 'eventemitter3' +import { NekoWebSocket } from './websocket' +import NekoState from '../types/state' + +export interface NekoEvents { + ['internal.websocket']: (state: 'connected' | 'connecting' | 'disconnected') => void + ['internal.webrtc']: (state: 'connected' | 'connecting' | 'disconnected') => void + ['system.disconnect']: (message: string) => void + ['member.created']: (id: string) => void + ['member.deleted']: (id: string) => void + ['member.profile']: (id: string) => void + ['member.state']: (id: string) => void + ['control.host']: (hasHost: boolean, hostID: string | undefined) => void + ['screen.updated']: (width: number, height: number, rate: number) => void + ['clipboard.updated']: (text: string) => void + ['broadcast.status']: (isActive: boolean, url: string | undefined) => void +} + +export class NekoMessages extends EventEmitter { + state: NekoState + + constructor(websocket: NekoWebSocket, state: NekoState) { + super() + + this.state = state + websocket.on('message', async (event: string, payload: any) => { + // @ts-ignore + if (typeof this[event] === 'function') { + // @ts-ignore + this[event](payload) + } else { + console.log(`unhandled websocket event '${event}':`, payload) + } + }) + } + + ///////////////////////////// + // System Events + ///////////////////////////// + + protected [EVENT.SYSTEM_INIT](conf: message.SystemInit) { + console.log('EVENT.SYSTEM_INIT') + Vue.set(this.state, 'member_id', conf.member_id) + Vue.set(this.state.control, 'implicit_hosting', conf.implicit_hosting) + + for (const id in conf.members) { + this[EVENT.MEMBER_CREATED](conf.members[id]) + } + + this[EVENT.SCREEN_UPDATED](conf.screen_size) + this[EVENT.CONTROL_HOST](conf.control_host) + } + + protected [EVENT.SYSTEM_ADMIN]({ screen_sizes_list, broadcast_status }: message.SystemAdmin) { + console.log('EVENT.SYSTEM_ADMIN') + + const list = screen_sizes_list.sort((a, b) => { + if (b.width === a.width && b.height == a.height) { + return b.rate - a.rate + } else if (b.width === a.width) { + return b.height - a.height + } + return b.width - a.width + }) + + Vue.set(this.state.screen, 'configurations', list) + + this[EVENT.BORADCAST_STATUS](broadcast_status) + } + + protected [EVENT.SYSTEM_DISCONNECT]({ message }: message.SystemDisconnect) { + console.log('EVENT.SYSTEM_DISCONNECT') + this.emit('system.disconnect', message) + // TODO: Handle. + } + + ///////////////////////////// + // Signal Events + ///////////////////////////// + + protected [EVENT.SIGNAL_PROVIDE]({ event }: message.SignalProvide) { + console.log('EVENT.SIGNAL_PROVIDE') + // TODO: Handle. + } + + ///////////////////////////// + // Member Events + ///////////////////////////// + + protected [EVENT.MEMBER_CREATED]({ id, ...data }: message.MemberData) { + console.log('EVENT.MEMBER_CREATED', id) + Vue.set(this.state.members, id, data) + this.emit('member.created', id) + } + + protected [EVENT.MEMBER_DELETED]({ id }: message.MemberID) { + console.log('EVENT.MEMBER_DELETED', id) + Vue.delete(this.state.members, id) + this.emit('member.deleted', id) + } + + protected [EVENT.MEMBER_PROFILE]({ id, ...profile }: message.MemberProfile) { + console.log('EVENT.MEMBER_PROFILE', id) + Vue.set(this.state.members[id], 'profile', profile) + this.emit('member.profile', id) + } + + protected [EVENT.MEMBER_STATE]({ id, ...state }: message.MemberState) { + console.log('EVENT.MEMBER_STATE', id) + Vue.set(this.state.members[id], 'state', state) + this.emit('member.state', id) + } + + ///////////////////////////// + // Control Events + ///////////////////////////// + + protected [EVENT.CONTROL_HOST]({ has_host, host_id }: message.ControlHost) { + console.log('EVENT.CONTROL_HOST') + + if (has_host && host_id) { + Vue.set(this.state.control, 'host_id', host_id) + } else { + Vue.set(this.state.control, 'host_id', null) + } + + this.emit('control.host', has_host, host_id) + } + + ///////////////////////////// + // Screen Events + ///////////////////////////// + + protected [EVENT.SCREEN_UPDATED]({ width, height, rate }: message.ScreenSize) { + console.log('EVENT.SCREEN_UPDATED') + Vue.set(this.state.screen, 'size', { width, height, rate }) + this.emit('screen.updated', width, height, rate) + } + ///////////////////////////// + // Clipboard Events + ///////////////////////////// + + protected [EVENT.CLIPBOARD_UPDATED]({ text }: message.ClipboardData) { + console.log('EVENT.CLIPBOARD_UPDATED') + Vue.set(this.state.control, 'clipboard', { text }) + this.emit('clipboard.updated', text) + } + + ///////////////////////////// + // Broadcast Events + ///////////////////////////// + + protected [EVENT.BORADCAST_STATUS]({ event, url, is_active }: message.BroadcastStatus) { + console.log('EVENT.BORADCAST_STATUS') + // TODO: Handle. + this.emit('broadcast.status', is_active, url) + } +} diff --git a/src/component/main.vue b/src/component/main.vue index 2c8bc625..58e90a52 100644 --- a/src/component/main.vue +++ b/src/component/main.vue @@ -226,6 +226,15 @@ this.websocket.send('screen/set', { width, height, rate }) } + public async initBrowser() { + const tabs = await this.api.browser.tabsGetAll() + + Vue.set(this.state, 'browser', { + connected: true, + tabs, + }) + } + public get room(): RoomApi { return this.api.room } @@ -234,12 +243,6 @@ return this.api.members } - // TODO: Refactor. - tabHander?: (event: string, payload: any) => any - public tabSubscribe(func: (event: string, payload: any) => any) { - this.tabHander = func - } - ///////////////////////////// // Component lifecycle ///////////////////////////// @@ -266,11 +269,6 @@ } catch (e) {} break } - - // TODO: Refactor. - if (event.match(/^tabs\//) && this.tabHander) { - this.tabHander(event, payload.payload) - } }) this.websocket.on('connecting', () => { Vue.set(this.state.connection, 'websocket', 'connecting')