dont automatically reconnect, add dc layer with option to reconnect
This commit is contained in:
parent
9f7ac8d111
commit
6d59a713a3
8 changed files with 179 additions and 191 deletions
|
|
@ -1,35 +1,65 @@
|
||||||
"use strict"
|
"use strict"
|
||||||
|
|
||||||
import WsClient from './WsClient.js'
|
import { logger } from '../common/Util.js'
|
||||||
import Protocol from './../common/Protocol.js'
|
import Protocol from './../common/Protocol.js'
|
||||||
|
|
||||||
/** @type WsClient */
|
const log = logger('Communication.js')
|
||||||
let conn
|
|
||||||
|
const CODE_GOING_AWAY = 1001
|
||||||
|
const CODE_CUSTOM_DISCONNECT = 4000
|
||||||
|
|
||||||
|
const CONN_STATE_NOT_CONNECTED = 0 // not connected yet
|
||||||
|
const CONN_STATE_DISCONNECTED = 1 // not connected, but was connected before
|
||||||
|
const CONN_STATE_CONNECTED = 2 // connected
|
||||||
|
const CONN_STATE_CONNECTING = 3 // connecting
|
||||||
|
const CONN_STATE_CLOSED = 4 // not connected (closed on purpose)
|
||||||
|
|
||||||
|
/** @type WebSocket */
|
||||||
|
let ws
|
||||||
let changesCallback = () => {}
|
let changesCallback = () => {}
|
||||||
let connectionLostCallback = () => {}
|
let connectionStateChangeCallback = () => {}
|
||||||
|
|
||||||
// TODO: change these to something like on(EVT, cb)
|
// TODO: change these to something like on(EVT, cb)
|
||||||
function onServerChange(callback) {
|
function onServerChange(callback) {
|
||||||
changesCallback = callback
|
changesCallback = callback
|
||||||
}
|
}
|
||||||
function onConnectionLost(callback) {
|
function onConnectionStateChange(callback) {
|
||||||
connectionLostCallback = callback
|
connectionStateChangeCallback = callback
|
||||||
}
|
}
|
||||||
|
|
||||||
function send(message) {
|
let connectionState = CONN_STATE_NOT_CONNECTED
|
||||||
conn.send(JSON.stringify(message))
|
const setConnectionState = (v) => {
|
||||||
|
if (connectionState !== v) {
|
||||||
|
connectionState = v
|
||||||
|
connectionStateChangeCallback(v)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
function send(message) {
|
||||||
|
if (connectionState === CONN_STATE_CONNECTED) {
|
||||||
|
try {
|
||||||
|
ws.send(JSON.stringify(message))
|
||||||
|
} catch (e) {
|
||||||
|
log.info('unable to send message.. maybe because ws is invalid?')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
let clientSeq
|
let clientSeq
|
||||||
let events
|
let events
|
||||||
function connect(address, gameId, clientId) {
|
function connect(address, gameId, clientId) {
|
||||||
clientSeq = 0
|
clientSeq = 0
|
||||||
events = {}
|
events = {}
|
||||||
conn = new WsClient(address, clientId + '|' + gameId)
|
setConnectionState(CONN_STATE_CONNECTING)
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
conn.connect()
|
ws = new WebSocket(address, clientId + '|' + gameId)
|
||||||
conn.onSocket('message', async ({ data }) => {
|
ws.onopen = (e) => {
|
||||||
const msg = JSON.parse(data)
|
setConnectionState(CONN_STATE_CONNECTED)
|
||||||
|
connectionStateChangeCallback()
|
||||||
|
send([Protocol.EV_CLIENT_INIT])
|
||||||
|
}
|
||||||
|
ws.onmessage = (e) => {
|
||||||
|
const msg = JSON.parse(e.data)
|
||||||
const msgType = msg[0]
|
const msgType = msg[0]
|
||||||
if (msgType === Protocol.EV_SERVER_INIT) {
|
if (msgType === Protocol.EV_SERVER_INIT) {
|
||||||
const game = msg[1]
|
const game = msg[1]
|
||||||
|
|
@ -46,22 +76,36 @@ function connect(address, gameId, clientId) {
|
||||||
} else {
|
} else {
|
||||||
throw `[ 2021-05-09 invalid connect msgType ${msgType} ]`
|
throw `[ 2021-05-09 invalid connect msgType ${msgType} ]`
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
conn.onclose(() => {
|
|
||||||
connectionLostCallback()
|
ws.onerror = (e) => {
|
||||||
})
|
setConnectionState(CONN_STATE_DISCONNECTED)
|
||||||
send([Protocol.EV_CLIENT_INIT])
|
throw `[ 2021-05-15 onerror ]`
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.onclose = (e) => {
|
||||||
|
if (e.code === CODE_CUSTOM_DISCONNECT || e.code === CODE_GOING_AWAY) {
|
||||||
|
setConnectionState(CONN_STATE_CLOSED)
|
||||||
|
} else {
|
||||||
|
setConnectionState(CONN_STATE_DISCONNECTED)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TOOD: change replay stuff
|
||||||
function connectReplay(address, gameId, clientId) {
|
function connectReplay(address, gameId, clientId) {
|
||||||
clientSeq = 0
|
clientSeq = 0
|
||||||
events = {}
|
events = {}
|
||||||
conn = new WsClient(address, clientId + '|' + gameId)
|
setConnectionState(CONN_STATE_CONNECTING)
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
conn.connect()
|
ws = new WebSocket(address, clientId + '|' + gameId)
|
||||||
conn.onSocket('message', async ({ data }) => {
|
ws.onopen = (e) => {
|
||||||
const msg = JSON.parse(data)
|
setConnectionState(CONN_STATE_CONNECTED)
|
||||||
|
send([Protocol.EV_CLIENT_INIT_REPLAY])
|
||||||
|
}
|
||||||
|
ws.onmessage = (e) => {
|
||||||
|
const msg = JSON.parse(e.data)
|
||||||
const msgType = msg[0]
|
const msgType = msg[0]
|
||||||
if (msgType === Protocol.EV_SERVER_INIT_REPLAY) {
|
if (msgType === Protocol.EV_SERVER_INIT_REPLAY) {
|
||||||
const game = msg[1]
|
const game = msg[1]
|
||||||
|
|
@ -70,14 +114,26 @@ function connectReplay(address, gameId, clientId) {
|
||||||
} else {
|
} else {
|
||||||
throw `[ 2021-05-09 invalid connectReplay msgType ${msgType} ]`
|
throw `[ 2021-05-09 invalid connectReplay msgType ${msgType} ]`
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
send([Protocol.EV_CLIENT_INIT_REPLAY])
|
|
||||||
|
ws.onerror = (e) => {
|
||||||
|
setConnectionState(CONN_STATE_DISCONNECTED)
|
||||||
|
throw `[ 2021-05-15 onerror ]`
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.onclose = (e) => {
|
||||||
|
if (e.code === CODE_CUSTOM_DISCONNECT || e.code === CODE_GOING_AWAY) {
|
||||||
|
setConnectionState(CONN_STATE_CLOSED)
|
||||||
|
} else {
|
||||||
|
setConnectionState(CONN_STATE_DISCONNECTED)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function disconnect() {
|
function disconnect() {
|
||||||
if (conn) {
|
if (ws) {
|
||||||
conn.disconnect()
|
ws.close(CODE_CUSTOM_DISCONNECT)
|
||||||
}
|
}
|
||||||
clientSeq = 0
|
clientSeq = 0
|
||||||
events = {}
|
events = {}
|
||||||
|
|
@ -97,5 +153,12 @@ export default {
|
||||||
disconnect,
|
disconnect,
|
||||||
sendClientEvent,
|
sendClientEvent,
|
||||||
onServerChange,
|
onServerChange,
|
||||||
onConnectionLost,
|
onConnectionStateChange,
|
||||||
|
CODE_CUSTOM_DISCONNECT,
|
||||||
|
|
||||||
|
CONN_STATE_NOT_CONNECTED,
|
||||||
|
CONN_STATE_DISCONNECTED,
|
||||||
|
CONN_STATE_CLOSED,
|
||||||
|
CONN_STATE_CONNECTED,
|
||||||
|
CONN_STATE_CONNECTING,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
"use strict"
|
|
||||||
|
|
||||||
import Time from '../common/Time.js'
|
|
||||||
|
|
||||||
const CODE_CUSTOM_DISCONNECT = 4000
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper around ws that
|
|
||||||
* - buffers 'send' until a connection is available
|
|
||||||
* - automatically tries to reconnect on close
|
|
||||||
*/
|
|
||||||
export default class WsClient {
|
|
||||||
// actual ws handle
|
|
||||||
handle = null
|
|
||||||
|
|
||||||
// timeout for automatic reconnect
|
|
||||||
reconnectTimeout = null
|
|
||||||
|
|
||||||
// buffer for 'send'
|
|
||||||
sendBuffer = []
|
|
||||||
|
|
||||||
constructor(addr, protocols) {
|
|
||||||
this.addr = addr
|
|
||||||
this.protocols = protocols
|
|
||||||
|
|
||||||
this.onopen = () => {}
|
|
||||||
this.onclose = () => {}
|
|
||||||
this.onmessage = () => {}
|
|
||||||
|
|
||||||
this._on = {}
|
|
||||||
this.onopen = (e) => {
|
|
||||||
this._dispatch('socket', 'open', e)
|
|
||||||
}
|
|
||||||
this.onmessage = (e) => {
|
|
||||||
this._dispatch('socket', 'message', e)
|
|
||||||
if (!!this._on['message']) {
|
|
||||||
const d = this._parseMessageData(e.data)
|
|
||||||
if (d.event) {
|
|
||||||
this._dispatch('message', d.event, d.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.onclose = (e) => {
|
|
||||||
this._dispatch('socket', 'close', e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
send (txt) {
|
|
||||||
if (this.handle) {
|
|
||||||
this.handle.send(txt)
|
|
||||||
} else {
|
|
||||||
this.sendBuffer.push(txt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
connect() {
|
|
||||||
let ws = new WebSocket(this.addr, this.protocols)
|
|
||||||
ws.onopen = (e) => {
|
|
||||||
if (this.reconnectTimeout) {
|
|
||||||
clearTimeout(this.reconnectTimeout)
|
|
||||||
}
|
|
||||||
this.handle = ws
|
|
||||||
// should have a queue worker
|
|
||||||
while (this.sendBuffer.length > 0) {
|
|
||||||
this.handle.send(this.sendBuffer.shift())
|
|
||||||
}
|
|
||||||
this.onopen(e)
|
|
||||||
}
|
|
||||||
ws.onmessage = (e) => {
|
|
||||||
this.onmessage(e)
|
|
||||||
}
|
|
||||||
ws.onerror = (e) => {
|
|
||||||
this.handle = null
|
|
||||||
this.reconnectTimeout = setTimeout(() => { this.connect() }, 1 * Time.SEC)
|
|
||||||
this.onclose(e)
|
|
||||||
}
|
|
||||||
ws.onclose = (e) => {
|
|
||||||
this.handle = null
|
|
||||||
if (e.code !== CODE_CUSTOM_DISCONNECT) {
|
|
||||||
this.reconnectTimeout = setTimeout(() => { this.connect() }, 1 * Time.SEC)
|
|
||||||
}
|
|
||||||
this.onclose(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnect() {
|
|
||||||
if (this.handle) {
|
|
||||||
this.handle.close(CODE_CUSTOM_DISCONNECT)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onSocket(tag, callback) {
|
|
||||||
this.addEventListener('socket', tag, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
onMessage(tag, callback) {
|
|
||||||
this.addEventListener('message', tag, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
addEventListener(type, tag, callback) {
|
|
||||||
const tags = Array.isArray(tag) ? tag : [tag]
|
|
||||||
this._on[type] = this._on[type] || {}
|
|
||||||
for (const t of tags) {
|
|
||||||
this._on[type][t] = this._on[type][t] || []
|
|
||||||
this._on[type][t].push(callback)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_parseMessageData(data) {
|
|
||||||
try {
|
|
||||||
const d = JSON.parse(data)
|
|
||||||
if (d.event) {
|
|
||||||
return {event: d.event, data: d.data || null}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
}
|
|
||||||
return {event: null, data: null}
|
|
||||||
}
|
|
||||||
|
|
||||||
_dispatch(type, tag, ...args) {
|
|
||||||
const t = this._on[type] || {}
|
|
||||||
const callbacks = (t[tag] || [])
|
|
||||||
if (callbacks.length === 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const callback of callbacks) {
|
|
||||||
callback(...args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
34
public/components/ConnectionOverlay.vue.js
Normal file
34
public/components/ConnectionOverlay.vue.js
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
"use strict"
|
||||||
|
|
||||||
|
import Communication from './../Communication.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'connection-overlay',
|
||||||
|
template: `
|
||||||
|
<div class="overlay connection-lost" v-if="show">
|
||||||
|
<div class="overlay-content" v-if="lostConnection">
|
||||||
|
<div>⁉️ LOST CONNECTION ⁉️</div>
|
||||||
|
<span class="btn" @click="$emit('reconnect')">Reconnect</span>
|
||||||
|
</div>
|
||||||
|
<div class="overlay-content" v-if="connectionState === 3">
|
||||||
|
<div>Connecting...</div>
|
||||||
|
</div>
|
||||||
|
</div>`,
|
||||||
|
emits: {
|
||||||
|
reconnect: null,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
connectionState: Number,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
lostConnection () {
|
||||||
|
return this.connectionState === Communication.CONN_STATE_DISCONNECTED
|
||||||
|
},
|
||||||
|
connecting () {
|
||||||
|
return this.connectionState === Communication.CONN_STATE_CONNECTING
|
||||||
|
},
|
||||||
|
show () {
|
||||||
|
return this.lostConnection || this.connecting
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
export default {
|
export default {
|
||||||
name: 'help-overlay',
|
name: 'help-overlay',
|
||||||
template: `<div class="overlay transparent" @click="$emit('bgclick')">
|
template: `<div class="overlay transparent" @click="$emit('bgclick')">
|
||||||
<table class="help" @click.stop="">
|
<table class="overlay-content help" @click.stop="">
|
||||||
<tr><td>⬆️ Move up:</td><td><div><kbd>W</kbd>/<kbd>↑</kbd>/🖱️</div></td></tr>
|
<tr><td>⬆️ Move up:</td><td><div><kbd>W</kbd>/<kbd>↑</kbd>/🖱️</div></td></tr>
|
||||||
<tr><td>⬇️ Move down:</td><td><div><kbd>S</kbd>/<kbd>↓</kbd>/🖱️</div></td></tr>
|
<tr><td>⬇️ Move down:</td><td><div><kbd>S</kbd>/<kbd>↓</kbd>/🖱️</div></td></tr>
|
||||||
<tr><td>⬅️ Move left:</td><td><div><kbd>A</kbd>/<kbd>←</kbd>/🖱️</div></td></tr>
|
<tr><td>⬅️ Move left:</td><td><div><kbd>A</kbd>/<kbd>←</kbd>/🖱️</div></td></tr>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export default {
|
||||||
name: 'settings-overlay',
|
name: 'settings-overlay',
|
||||||
template: `
|
template: `
|
||||||
<div class="overlay transparent" @click="$emit('bgclick')">
|
<div class="overlay transparent" @click="$emit('bgclick')">
|
||||||
<table class="settings" @click.stop="">
|
<table class="overlay-content settings" @click.stop="">
|
||||||
<tr>
|
<tr>
|
||||||
<td><label>Background: </label></td>
|
<td><label>Background: </label></td>
|
||||||
<td><input type="color" v-model="modelValue.background" /></td>
|
<td><input type="color" v-model="modelValue.background" /></td>
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import fireworksController from './Fireworks.js'
|
||||||
import Protocol from '../common/Protocol.js'
|
import Protocol from '../common/Protocol.js'
|
||||||
import Time from '../common/Time.js'
|
import Time from '../common/Time.js'
|
||||||
|
|
||||||
const log = logger('game.js')
|
// const log = logger('game.js')
|
||||||
|
|
||||||
export const MODE_PLAY = 'play'
|
export const MODE_PLAY = 'play'
|
||||||
export const MODE_REPLAY = 'replay'
|
export const MODE_REPLAY = 'replay'
|
||||||
|
|
@ -174,7 +174,14 @@ function EventAdapter (canvas, window, viewport) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function main(gameId, clientId, wsAddress, MODE, TARGET_EL, HUD) {
|
export async function main(
|
||||||
|
gameId,
|
||||||
|
clientId,
|
||||||
|
wsAddress,
|
||||||
|
MODE,
|
||||||
|
TARGET_EL,
|
||||||
|
HUD
|
||||||
|
) {
|
||||||
if (typeof DEBUG === 'undefined') window.DEBUG = false
|
if (typeof DEBUG === 'undefined') window.DEBUG = false
|
||||||
|
|
||||||
const shouldDrawPlayerText = (player) => {
|
const shouldDrawPlayerText = (player) => {
|
||||||
|
|
@ -219,18 +226,19 @@ export async function main(gameId, clientId, wsAddress, MODE, TARGET_EL, HUD) {
|
||||||
gameStartTs: null,
|
gameStartTs: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Communication.onConnectionStateChange((state) => {
|
||||||
Communication.onConnectionLost(() => {
|
HUD.setConnectionState(state)
|
||||||
log('connection lost ... should reload / hit reconnect button / etc.')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
let TIME
|
let TIME
|
||||||
|
const connect = async () => {
|
||||||
if (MODE === MODE_PLAY) {
|
if (MODE === MODE_PLAY) {
|
||||||
const game = await Communication.connect(wsAddress, gameId, clientId)
|
const game = await Communication.connect(wsAddress, gameId, clientId)
|
||||||
const gameObject = Util.decodeGame(game)
|
const gameObject = Util.decodeGame(game)
|
||||||
Game.setGame(gameObject.id, gameObject)
|
Game.setGame(gameObject.id, gameObject)
|
||||||
TIME = () => Time.timestamp()
|
TIME = () => Time.timestamp()
|
||||||
} else if (MODE === MODE_REPLAY) {
|
} else if (MODE === MODE_REPLAY) {
|
||||||
|
// TODO: change how replay connect is done...
|
||||||
const {game, log} = await Communication.connectReplay(wsAddress, gameId, clientId)
|
const {game, log} = await Communication.connectReplay(wsAddress, gameId, clientId)
|
||||||
const gameObject = Util.decodeGame(game)
|
const gameObject = Util.decodeGame(game)
|
||||||
Game.setGame(gameObject.id, gameObject)
|
Game.setGame(gameObject.id, gameObject)
|
||||||
|
|
@ -243,6 +251,12 @@ export async function main(gameId, clientId, wsAddress, MODE, TARGET_EL, HUD) {
|
||||||
throw '[ 2020-12-22 MODE invalid, must be play|replay ]'
|
throw '[ 2020-12-22 MODE invalid, must be play|replay ]'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rerender after (re-)connect
|
||||||
|
RERENDER = true
|
||||||
|
}
|
||||||
|
|
||||||
|
await connect()
|
||||||
|
|
||||||
const TILE_DRAW_OFFSET = Game.getTileDrawOffset(gameId)
|
const TILE_DRAW_OFFSET = Game.getTileDrawOffset(gameId)
|
||||||
const TILE_DRAW_SIZE = Game.getTileDrawSize(gameId)
|
const TILE_DRAW_SIZE = Game.getTileDrawSize(gameId)
|
||||||
const PUZZLE_WIDTH = Game.getPuzzleWidth(gameId)
|
const PUZZLE_WIDTH = Game.getPuzzleWidth(gameId)
|
||||||
|
|
@ -653,5 +667,6 @@ export async function main(gameId, clientId, wsAddress, MODE, TARGET_EL, HUD) {
|
||||||
name: playerName(),
|
name: playerName(),
|
||||||
},
|
},
|
||||||
disconnect: Communication.disconnect,
|
disconnect: Communication.disconnect,
|
||||||
|
connect: connect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ input:focus {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.help {
|
.overlay-content {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|
@ -145,16 +145,9 @@ input:focus {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings {
|
.connection-lost .overlay-content {
|
||||||
position: absolute;
|
padding: 20px;
|
||||||
left: 50%;
|
text-align: center;
|
||||||
top: 50%;
|
|
||||||
transform: translate(-50%,-50%);
|
|
||||||
background: var(--bg-color);
|
|
||||||
padding: 5px;
|
|
||||||
border: solid 1px black;
|
|
||||||
box-shadow: 0 0 10px 0 rgba(0,0,0,.7);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview {
|
.preview {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import Scores from './../components/Scores.vue.js'
|
||||||
import PuzzleStatus from './../components/PuzzleStatus.vue.js'
|
import PuzzleStatus from './../components/PuzzleStatus.vue.js'
|
||||||
import SettingsOverlay from './../components/SettingsOverlay.vue.js'
|
import SettingsOverlay from './../components/SettingsOverlay.vue.js'
|
||||||
import PreviewOverlay from './../components/PreviewOverlay.vue.js'
|
import PreviewOverlay from './../components/PreviewOverlay.vue.js'
|
||||||
|
import ConnectionOverlay from './../components/ConnectionOverlay.vue.js'
|
||||||
import HelpOverlay from './../components/HelpOverlay.vue.js'
|
import HelpOverlay from './../components/HelpOverlay.vue.js'
|
||||||
|
|
||||||
import { main, MODE_PLAY } from './../game.js'
|
import { main, MODE_PLAY } from './../game.js'
|
||||||
|
|
@ -15,6 +16,7 @@ export default {
|
||||||
Scores,
|
Scores,
|
||||||
SettingsOverlay,
|
SettingsOverlay,
|
||||||
PreviewOverlay,
|
PreviewOverlay,
|
||||||
|
ConnectionOverlay,
|
||||||
HelpOverlay,
|
HelpOverlay,
|
||||||
},
|
},
|
||||||
template: `<div id="game">
|
template: `<div id="game">
|
||||||
|
|
@ -22,6 +24,11 @@ export default {
|
||||||
<preview-overlay v-show="overlay === 'preview'" @bgclick="toggle('preview', false)" :img="g.previewImageUrl" />
|
<preview-overlay v-show="overlay === 'preview'" @bgclick="toggle('preview', false)" :img="g.previewImageUrl" />
|
||||||
<help-overlay v-show="overlay === 'help'" @bgclick="toggle('help', true)" />
|
<help-overlay v-show="overlay === 'help'" @bgclick="toggle('help', true)" />
|
||||||
|
|
||||||
|
<connection-overlay
|
||||||
|
:connectionState="connectionState"
|
||||||
|
@reconnect="reconnect"
|
||||||
|
/>
|
||||||
|
|
||||||
<puzzle-status
|
<puzzle-status
|
||||||
:finished="finished"
|
:finished="finished"
|
||||||
:duration="duration"
|
:duration="duration"
|
||||||
|
|
@ -52,6 +59,8 @@ export default {
|
||||||
|
|
||||||
overlay: null,
|
overlay: null,
|
||||||
|
|
||||||
|
connectionState: 0,
|
||||||
|
|
||||||
g: {
|
g: {
|
||||||
player: {
|
player: {
|
||||||
background: '',
|
background: '',
|
||||||
|
|
@ -64,6 +73,7 @@ export default {
|
||||||
onColorChange: () => {},
|
onColorChange: () => {},
|
||||||
onNameChange: () => {},
|
onNameChange: () => {},
|
||||||
disconnect: () => {},
|
disconnect: () => {},
|
||||||
|
connect: () => {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -93,6 +103,7 @@ export default {
|
||||||
setDuration: (v) => { this.duration = v },
|
setDuration: (v) => { this.duration = v },
|
||||||
setPiecesDone: (v) => { this.piecesDone = v },
|
setPiecesDone: (v) => { this.piecesDone = v },
|
||||||
setPiecesTotal: (v) => { this.piecesTotal = v },
|
setPiecesTotal: (v) => { this.piecesTotal = v },
|
||||||
|
setConnectionState: (v) => { this.connectionState = v },
|
||||||
togglePreview: () => { this.toggle('preview', false) },
|
togglePreview: () => { this.toggle('preview', false) },
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -101,6 +112,9 @@ export default {
|
||||||
this.g.disconnect()
|
this.g.disconnect()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
reconnect() {
|
||||||
|
this.g.connect()
|
||||||
|
},
|
||||||
toggle(overlay, affectsHotkeys) {
|
toggle(overlay, affectsHotkeys) {
|
||||||
if (this.overlay === null) {
|
if (this.overlay === null) {
|
||||||
this.overlay = overlay
|
this.overlay = overlay
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue