neko/src/component/internal/messages.ts

225 lines
7.0 KiB
TypeScript
Raw Normal View History

2020-12-30 08:50:49 +13:00
import Vue from 'vue'
import * as EVENT from '../types/events'
import * as message from '../types/messages'
import EventEmitter from 'eventemitter3'
2021-01-16 05:17:49 +13:00
import { Logger } from '../utils/logger'
2020-12-30 08:50:49 +13:00
import { NekoWebSocket } from './websocket'
import NekoState from '../types/state'
export interface NekoEvents {
2021-02-01 02:25:17 +13:00
// connection events
['connection.websocket']: (state: 'connected' | 'connecting' | 'disconnected') => void
['connection.webrtc']: (state: 'connected' | 'connecting' | 'disconnected') => void
['connection.disconnect']: (message: string) => void
// drag and drop events
2021-01-09 09:36:59 +13:00
['upload.drop.started']: () => void
['upload.drop.progress']: (progressEvent: ProgressEvent) => void
['upload.drop.finished']: (error: Error | null) => void
2021-02-01 02:25:17 +13:00
// upload dialog events
['upload.dialog.requested']: () => void
['upload.dialog.overlay']: (id: string) => void
['upload.dialog.closed']: () => void
// custom messages events
['receive.unicast']: (sender: string, subject: string, body: any) => void
['receive.broadcast']: (sender: string, subject: string, body: any) => void
// member events
2020-12-30 08:50:49 +13:00
['member.created']: (id: string) => void
['member.deleted']: (id: string) => void
2021-02-01 02:25:17 +13:00
['member.updated']: (id: string) => void
// room events
['room.control.host']: (hasHost: boolean, hostID: string | undefined) => void
['room.screen.updated']: (width: number, height: number, rate: number) => void
['room.clipboard.updated']: (text: string) => void
['room.broadcast.status']: (isActive: boolean, url: string | undefined) => void
2020-12-30 08:50:49 +13:00
}
export class NekoMessages extends EventEmitter<NekoEvents> {
2021-01-16 05:17:49 +13:00
private state: NekoState
private _log: Logger
2020-12-30 08:50:49 +13:00
constructor(websocket: NekoWebSocket, state: NekoState) {
super()
2021-01-16 05:17:49 +13:00
this._log = new Logger('messages')
2020-12-30 08:50:49 +13:00
this.state = state
websocket.on('message', async (event: string, payload: any) => {
// @ts-ignore
if (typeof this[event] === 'function') {
// @ts-ignore
this[event](payload)
} else {
2021-01-16 05:17:49 +13:00
this._log.warn(`unhandled websocket event '${event}':`, payload)
2020-12-30 08:50:49 +13:00
}
})
}
/////////////////////////////
// System Events
/////////////////////////////
protected [EVENT.SYSTEM_INIT](conf: message.SystemInit) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.SYSTEM_INIT')
2020-12-30 08:50:49 +13:00
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)
2021-01-11 00:41:51 +13:00
if (conf.cursor_image) {
this[EVENT.CURSOR_IMAGE](conf.cursor_image)
}
2020-12-30 08:50:49 +13:00
}
protected [EVENT.SYSTEM_ADMIN]({ screen_sizes_list, broadcast_status }: message.SystemAdmin) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.SYSTEM_ADMIN')
2020-12-30 08:50:49 +13:00
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) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.SYSTEM_DISCONNECT')
2021-02-01 02:25:17 +13:00
this.emit('connection.disconnect', message)
2020-12-30 08:50:49 +13:00
// TODO: Handle.
}
2021-01-11 00:34:08 +13:00
protected [EVENT.CURSOR_IMAGE]({ uri, width, height, x, y }: message.CursorImage) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.CURSOR_IMAGE')
2021-01-11 00:34:08 +13:00
Vue.set(this.state.control, 'cursor', { uri, width, height, x, y })
2021-01-10 11:28:56 +13:00
}
2020-12-30 08:50:49 +13:00
/////////////////////////////
// Signal Events
/////////////////////////////
protected [EVENT.SIGNAL_PROVIDE]({ event }: message.SignalProvide) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.SIGNAL_PROVIDE')
2020-12-30 08:50:49 +13:00
// TODO: Handle.
}
/////////////////////////////
// Member Events
/////////////////////////////
protected [EVENT.MEMBER_CREATED]({ id, ...data }: message.MemberData) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.MEMBER_CREATED', id)
2020-12-30 08:50:49 +13:00
Vue.set(this.state.members, id, data)
this.emit('member.created', id)
}
protected [EVENT.MEMBER_DELETED]({ id }: message.MemberID) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.MEMBER_DELETED', id)
2020-12-30 08:50:49 +13:00
Vue.delete(this.state.members, id)
this.emit('member.deleted', id)
}
protected [EVENT.MEMBER_PROFILE]({ id, ...profile }: message.MemberProfile) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.MEMBER_PROFILE', id)
2020-12-30 08:50:49 +13:00
Vue.set(this.state.members[id], 'profile', profile)
2021-02-01 02:25:17 +13:00
this.emit('member.updated', id)
2020-12-30 08:50:49 +13:00
}
protected [EVENT.MEMBER_STATE]({ id, ...state }: message.MemberState) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.MEMBER_STATE', id)
2020-12-30 08:50:49 +13:00
Vue.set(this.state.members[id], 'state', state)
2021-02-01 02:25:17 +13:00
this.emit('member.updated', id)
2020-12-30 08:50:49 +13:00
}
/////////////////////////////
// Control Events
/////////////////////////////
protected [EVENT.CONTROL_HOST]({ has_host, host_id }: message.ControlHost) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.CONTROL_HOST')
2020-12-30 08:50:49 +13:00
if (has_host && host_id) {
Vue.set(this.state.control, 'host_id', host_id)
} else {
Vue.set(this.state.control, 'host_id', null)
}
2021-02-01 02:25:17 +13:00
this.emit('room.control.host', has_host, host_id)
2020-12-30 08:50:49 +13:00
}
/////////////////////////////
// Screen Events
/////////////////////////////
protected [EVENT.SCREEN_UPDATED]({ width, height, rate }: message.ScreenSize) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.SCREEN_UPDATED')
2020-12-30 08:50:49 +13:00
Vue.set(this.state.screen, 'size', { width, height, rate })
2021-02-01 02:25:17 +13:00
this.emit('room.screen.updated', width, height, rate)
2020-12-30 08:50:49 +13:00
}
/////////////////////////////
// Clipboard Events
/////////////////////////////
protected [EVENT.CLIPBOARD_UPDATED]({ text }: message.ClipboardData) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.CLIPBOARD_UPDATED')
2020-12-30 08:50:49 +13:00
Vue.set(this.state.control, 'clipboard', { text })
2021-02-01 02:25:17 +13:00
this.emit('room.clipboard.updated', text)
2020-12-30 08:50:49 +13:00
}
/////////////////////////////
// Broadcast Events
/////////////////////////////
protected [EVENT.BORADCAST_STATUS]({ event, url, is_active }: message.BroadcastStatus) {
2021-01-16 05:17:49 +13:00
this._log.debug('EVENT.BORADCAST_STATUS')
2020-12-30 08:50:49 +13:00
// TODO: Handle.
2021-02-01 02:25:17 +13:00
this.emit('room.broadcast.status', is_active, url)
2020-12-30 08:50:49 +13:00
}
2021-01-21 11:59:32 +13:00
2021-01-29 04:08:17 +13:00
/////////////////////////////
// Send Events
/////////////////////////////
protected [EVENT.SEND_UNICAST]({ sender, subject, body }: message.SendMessage) {
this._log.debug('EVENT.SEND_UNICAST')
this.emit('receive.unicast', sender, subject, body)
}
protected [EVENT.SEND_BROADCAST]({ sender, subject, body }: message.SendMessage) {
this._log.debug('EVENT.BORADCAST_STATUS')
this.emit('receive.broadcast', sender, subject, body)
}
2021-01-21 11:59:32 +13:00
/////////////////////////////
// FileChooserDialog Events
/////////////////////////////
protected [EVENT.FILE_CHOOSER_DIALOG_OPENED]({ id }: message.MemberID) {
this._log.debug('EVENT.FILE_CHOOSER_DIALOG_OPENED')
if (id == this.state.member_id) {
2021-02-01 02:25:17 +13:00
this.emit('upload.dialog.requested')
2021-01-21 11:59:32 +13:00
} else {
2021-02-01 02:25:17 +13:00
this.emit('upload.dialog.overlay', id)
2021-01-21 11:59:32 +13:00
}
}
protected [EVENT.FILE_CHOOSER_DIALOG_CLOSED]({ id }: message.MemberID) {
this._log.debug('EVENT.FILE_CHOOSER_DIALOG_CLOSED')
2021-02-01 02:25:17 +13:00
this.emit('upload.dialog.closed')
2021-01-21 11:59:32 +13:00
}
2020-12-30 08:50:49 +13:00
}