diff --git a/client/src/components/connect.vue b/client/src/components/connect.vue index 17dbd32..c109da7 100644 --- a/client/src/components/connect.vue +++ b/client/src/components/connect.vue @@ -9,7 +9,7 @@ Please Login - + Connect @@ -147,17 +147,24 @@ diff --git a/client/src/components/settings.vue b/client/src/components/settings.vue index 95c7273..f684bf1 100644 --- a/client/src/components/settings.vue +++ b/client/src/components/settings.vue @@ -35,6 +35,9 @@ + + Logout + @@ -69,6 +72,22 @@ line-height: 24px; } + button { + cursor: pointer; + border-radius: 5px; + padding: 4px; + background: $style-primary; + color: $text-normal; + text-align: center; + text-transform: uppercase; + font-weight: bold; + line-height: 30px; + margin: 5px 0; + border: none; + display: block; + width: 100%; + } + .switch { justify-self: flex-end; position: relative; @@ -173,6 +192,10 @@ @Component({ name: 'neko-settings' }) export default class extends Vue { + get connected() { + return this.$accessor.connected + } + get scroll() { return this.$accessor.settings.scroll.toString() } @@ -212,5 +235,9 @@ set chat_sound(value: boolean) { this.$accessor.settings.setSound(value) } + + logout() { + this.$accessor.logout() + } } diff --git a/client/src/neko/base.ts b/client/src/neko/base.ts index 534694b..75072b0 100644 --- a/client/src/neko/base.ts +++ b/client/src/neko/base.ts @@ -73,6 +73,28 @@ export abstract class BaseClient extends EventEmitter { } } + protected disconnect() { + if (this._timeout) { + clearTimeout(this._timeout) + } + + if (this.socketOpen) { + try { + this._ws!.close() + } catch (err) {} + this._ws = undefined + } + + if (this.peerConnected) { + try { + this._peer!.close() + } catch (err) {} + this._peer = undefined + } + + this._state = 'disconnected' + } + public sendData(event: 'wheel' | 'mousemove', data: { x: number; y: number }): void public sendData(event: 'mousedown' | 'mouseup' | 'keydown' | 'keyup', data: { key: number }): void public sendData(event: string, data: any) { @@ -165,14 +187,6 @@ export abstract class BaseClient extends EventEmitter { } } - this._peer.onsignalingstatechange = event => { - this.emit('debug', `peer signal state chagned: ${this._peer!.signalingState}`) - } - - this._peer.onconnectionstatechange = event => { - this.emit('debug', `peer connection state chagned: ${this._peer!.connectionState}`) - } - this._peer.oniceconnectionstatechange = event => { this._state = this._peer!.iceConnectionState @@ -213,7 +227,7 @@ export abstract class BaseClient extends EventEmitter { private setRemoteDescription(payload: SignalPayload) { if (this.peerConnected) { - this.emit('warn', `received ${event} with no peer!`) + this.emit('warn', `attempting to set remote description while peer connected`, payload) return } this._peer!.setRemoteDescription({ type: 'answer', sdp: payload.sdp }) @@ -292,24 +306,7 @@ export abstract class BaseClient extends EventEmitter { } protected onDisconnected(reason?: Error) { - if (this._timeout) { - clearTimeout(this._timeout) - } - - if (this.socketOpen) { - try { - this._ws!.close() - } catch (err) {} - this._ws = undefined - } - - if (this.peerConnected) { - try { - this._peer!.close() - } catch (err) {} - this._peer = undefined - } - + this.disconnect() this.emit('debug', `disconnected:`, reason) this[EVENT.DISCONNECTED](reason) } diff --git a/client/src/neko/index.ts b/client/src/neko/index.ts index 7643e58..267053e 100644 --- a/client/src/neko/index.ts +++ b/client/src/neko/index.ts @@ -28,22 +28,40 @@ export class NekoClient extends BaseClient implements EventEmitter { private $vue!: Vue private $accessor!: typeof accessor + private get id() { + return this.$accessor.user.id + } + init(vue: Vue) { this.$vue = vue this.$accessor = vue.$accessor } - connect(password: string, username: string) { + private cleanup() { + this.$accessor.setConnected(false) + this.$accessor.remote.reset() + this.$accessor.user.reset() + this.$accessor.video.reset() + this.$accessor.chat.reset() + } + + login(password: string, username: string) { const url = process.env.NODE_ENV === 'development' ? `ws://${location.host.split(':')[0]}:${process.env.VUE_APP_SERVER_PORT}/` : `${/https/gi.test(location.protocol) ? 'wss' : 'ws'}://${location.host}/` - super.connect(url, password, username) + this.connect(url, password, username) } - private get id() { - return this.$accessor.user.id + logout() { + this.disconnect() + this.cleanup() + this.$vue.$swal({ + title: 'You have logged out!', + icon: 'info', + confirmButtonText: 'ok', + }) } ///////////////////////////// @@ -67,13 +85,7 @@ export class NekoClient extends BaseClient implements EventEmitter { } protected [EVENT.DISCONNECTED](reason?: Error) { - this.$accessor.setConnected(false) - - this.$accessor.remote.reset() - this.$accessor.user.reset() - this.$accessor.video.reset() - this.$accessor.chat.reset() - + this.cleanup() this.$vue.$notify({ group: 'neko', type: 'error', diff --git a/client/src/store/index.ts b/client/src/store/index.ts index da202fd..b9f6ac7 100644 --- a/client/src/store/index.ts +++ b/client/src/store/index.ts @@ -1,6 +1,7 @@ import Vue from 'vue' import Vuex from 'vuex' import { useAccessor, mutationTree, actionTree } from 'typed-vuex' +import { get, set } from '~/utils/localstorage' import * as video from './video' import * as chat from './chat' @@ -11,12 +12,19 @@ import * as client from './client' import * as emoji from './emoji' export const state = () => ({ + username: get('username', ''), + password: get('password', ''), connecting: false, connected: false, locked: false, }) export const mutations = mutationTree(state, { + setLogin(state, { username, password }: { username: string; password: string }) { + state.username = username + state.password = password + }, + setLocked(state, locked: boolean) { state.locked = locked }, @@ -29,20 +37,30 @@ export const mutations = mutationTree(state, { setConnected(state, connected: boolean) { state.connected = connected state.connecting = false + if (connected) { + set('username', state.username) + set('password', state.password) + } }, }) export const actions = actionTree( { state, mutations }, { - // initialise(store) { accessor.emoji.initialise() }, - // - connect(store, { username, password }: { username: string; password: string }) { - $client.connect(password, username) + login({ state }, { username, password }: { username: string; password: string }) { + accessor.setLogin({ username, password }) + $client.login(password, username) + }, + + logout({ state }) { + accessor.setLogin({ username: '', password: '' }) + set('username', '') + set('password', '') + $client.logout() }, }, )