switch to typescript
This commit is contained in:
parent
031ca31c7e
commit
23559b1a3b
63 changed files with 7943 additions and 1397 deletions
140
src/frontend/views/Game.vue
Normal file
140
src/frontend/views/Game.vue
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
<template>
|
||||
<div id="game">
|
||||
<settings-overlay v-show="overlay === 'settings'" @bgclick="toggle('settings', true)" v-model="g.player" />
|
||||
<preview-overlay v-show="overlay === 'preview'" @bgclick="toggle('preview', false)" :img="g.previewImageUrl" />
|
||||
<help-overlay v-show="overlay === 'help'" @bgclick="toggle('help', true)" />
|
||||
|
||||
<connection-overlay
|
||||
:connectionState="connectionState"
|
||||
@reconnect="reconnect"
|
||||
/>
|
||||
|
||||
<puzzle-status
|
||||
:finished="finished"
|
||||
:duration="duration"
|
||||
:piecesDone="piecesDone"
|
||||
:piecesTotal="piecesTotal"
|
||||
/>
|
||||
|
||||
<div class="menu">
|
||||
<div class="tabs">
|
||||
<router-link class="opener" :to="{name: 'index'}" target="_blank">🧩 Puzzles</router-link>
|
||||
<div class="opener" @click="toggle('preview', false)">🖼️ Preview</div>
|
||||
<div class="opener" @click="toggle('settings', true)">🛠️ Settings</div>
|
||||
<div class="opener" @click="toggle('help', true)">ℹ️ Help</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<scores :activePlayers="activePlayers" :idlePlayers="idlePlayers" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from 'vue'
|
||||
|
||||
import Scores from './../components/Scores.vue'
|
||||
import PuzzleStatus from './../components/PuzzleStatus.vue'
|
||||
import SettingsOverlay from './../components/SettingsOverlay.vue'
|
||||
import PreviewOverlay from './../components/PreviewOverlay.vue'
|
||||
import ConnectionOverlay from './../components/ConnectionOverlay.vue'
|
||||
import HelpOverlay from './../components/HelpOverlay.vue'
|
||||
|
||||
import { main, MODE_PLAY } from './../game'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'game',
|
||||
components: {
|
||||
PuzzleStatus,
|
||||
Scores,
|
||||
SettingsOverlay,
|
||||
PreviewOverlay,
|
||||
ConnectionOverlay,
|
||||
HelpOverlay,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// TODO: ts Array<Player> type
|
||||
activePlayers: [] as PropType<Array<any>>,
|
||||
idlePlayers: [] as PropType<Array<any>>,
|
||||
|
||||
finished: false,
|
||||
duration: 0,
|
||||
piecesDone: 0,
|
||||
piecesTotal: 0,
|
||||
|
||||
overlay: '',
|
||||
|
||||
connectionState: 0,
|
||||
|
||||
g: {
|
||||
player: {
|
||||
background: '',
|
||||
color: '',
|
||||
name: '',
|
||||
},
|
||||
previewImageUrl: '',
|
||||
setHotkeys: (v: boolean) => {},
|
||||
onBgChange: (v: string) => {},
|
||||
onColorChange: (v: string) => {},
|
||||
onNameChange: (v: string) => {},
|
||||
disconnect: () => {},
|
||||
connect: () => {},
|
||||
},
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
if (!this.$route.params.id) {
|
||||
return
|
||||
}
|
||||
this.$watch(() => this.g.player.background, (value: string) => {
|
||||
this.g.onBgChange(value)
|
||||
})
|
||||
this.$watch(() => this.g.player.color, (value: string) => {
|
||||
this.g.onColorChange(value)
|
||||
})
|
||||
this.$watch(() => this.g.player.name, (value: string) => {
|
||||
this.g.onNameChange(value)
|
||||
})
|
||||
this.g = await main(
|
||||
`${this.$route.params.id}`,
|
||||
// @ts-ignore
|
||||
this.$clientId,
|
||||
// @ts-ignore
|
||||
this.$config.WS_ADDRESS,
|
||||
MODE_PLAY,
|
||||
this.$el,
|
||||
{
|
||||
setActivePlayers: (v: Array<any>) => { this.activePlayers = v },
|
||||
setIdlePlayers: (v: Array<any>) => { this.idlePlayers = v },
|
||||
setFinished: (v: boolean) => { this.finished = v },
|
||||
setDuration: (v: number) => { this.duration = v },
|
||||
setPiecesDone: (v: number) => { this.piecesDone = v },
|
||||
setPiecesTotal: (v: number) => { this.piecesTotal = v },
|
||||
setConnectionState: (v: number) => { this.connectionState = v },
|
||||
togglePreview: () => { this.toggle('preview', false) },
|
||||
}
|
||||
)
|
||||
},
|
||||
unmounted () {
|
||||
this.g.disconnect()
|
||||
},
|
||||
methods: {
|
||||
reconnect(): void {
|
||||
this.g.connect()
|
||||
},
|
||||
toggle(overlay: string, affectsHotkeys: boolean): void {
|
||||
if (this.overlay === '') {
|
||||
this.overlay = overlay
|
||||
if (affectsHotkeys) {
|
||||
this.g.setHotkeys(false)
|
||||
}
|
||||
} else {
|
||||
// could check if overlay was the provided one
|
||||
this.overlay = ''
|
||||
if (affectsHotkeys) {
|
||||
this.g.setHotkeys(true)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
36
src/frontend/views/Index.vue
Normal file
36
src/frontend/views/Index.vue
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1>Running games</h1>
|
||||
<div class="game-teaser-wrap" v-for="(g, idx) in gamesRunning" :key="idx">
|
||||
<game-teaser :game="g" />
|
||||
</div>
|
||||
|
||||
<h1>Finished games</h1>
|
||||
<div class="game-teaser-wrap" v-for="(g, idx) in gamesFinished" :key="idx">
|
||||
<game-teaser :game="g" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import GameTeaser from './../components/GameTeaser.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
GameTeaser,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
gamesRunning: [],
|
||||
gamesFinished: [],
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
const res = await fetch('/api/index-data')
|
||||
const json = await res.json()
|
||||
this.gamesRunning = json.gamesRunning
|
||||
this.gamesFinished = json.gamesFinished
|
||||
},
|
||||
})
|
||||
</script>
|
||||
45
src/frontend/views/NewGame.vue
Normal file
45
src/frontend/views/NewGame.vue
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<template>
|
||||
<div>
|
||||
<new-game-dialog :images="images" @newGame="onNewGame" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
// TODO: maybe move dialog back, now that this is a view on its own
|
||||
import NewGameDialog from './../components/NewGameDialog.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NewGameDialog,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
images: [],
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
const res = await fetch('/api/newgame-data')
|
||||
const json = await res.json()
|
||||
this.images = json.images
|
||||
},
|
||||
methods: {
|
||||
// TODO: ts GameSettings type
|
||||
async onNewGame(gameSettings: any) {
|
||||
const res = await fetch('/newgame', {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(gameSettings),
|
||||
})
|
||||
if (res.status === 200) {
|
||||
const game = await res.json()
|
||||
this.$router.push({ name: 'game', params: { id: game.id } })
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
152
src/frontend/views/Replay.vue
Normal file
152
src/frontend/views/Replay.vue
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
<template>
|
||||
<div id="replay">
|
||||
<settings-overlay v-show="overlay === 'settings'" @bgclick="toggle('settings', true)" v-model="g.player" />
|
||||
<preview-overlay v-show="overlay === 'preview'" @bgclick="toggle('preview', false)" :img="g.previewImageUrl" />
|
||||
<help-overlay v-show="overlay === 'help'" @bgclick="toggle('help', true)" />
|
||||
|
||||
<puzzle-status
|
||||
:finished="finished"
|
||||
:duration="duration"
|
||||
:piecesDone="piecesDone"
|
||||
:piecesTotal="piecesTotal"
|
||||
>
|
||||
<div>
|
||||
<div>{{replayText}}</div>
|
||||
<button class="btn" @click="g.replayOnSpeedUp()">⏫</button>
|
||||
<button class="btn" @click="g.replayOnSpeedDown()">⏬</button>
|
||||
<button class="btn" @click="g.replayOnPauseToggle()">⏸️</button>
|
||||
</div>
|
||||
</puzzle-status>
|
||||
|
||||
<div class="menu">
|
||||
<div class="tabs">
|
||||
<router-link class="opener" :to="{name: 'index'}" target="_blank">🧩 Puzzles</router-link>
|
||||
<div class="opener" @click="toggle('preview', false)">🖼️ Preview</div>
|
||||
<div class="opener" @click="toggle('settings', true)">🛠️ Settings</div>
|
||||
<div class="opener" @click="toggle('help', true)">ℹ️ Help</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<scores :activePlayers="activePlayers" :idlePlayers="idlePlayers" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import Scores from './../components/Scores.vue'
|
||||
import PuzzleStatus from './../components/PuzzleStatus.vue'
|
||||
import SettingsOverlay from './../components/SettingsOverlay.vue'
|
||||
import PreviewOverlay from './../components/PreviewOverlay.vue'
|
||||
import HelpOverlay from './../components/HelpOverlay.vue'
|
||||
|
||||
import { main, MODE_REPLAY } from './../game'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'replay',
|
||||
components: {
|
||||
PuzzleStatus,
|
||||
Scores,
|
||||
SettingsOverlay,
|
||||
PreviewOverlay,
|
||||
HelpOverlay,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activePlayers: [] as Array<any>,
|
||||
idlePlayers: [] as Array<any>,
|
||||
|
||||
finished: false,
|
||||
duration: 0,
|
||||
piecesDone: 0,
|
||||
piecesTotal: 0,
|
||||
|
||||
overlay: '',
|
||||
|
||||
connectionState: 0,
|
||||
|
||||
g: {
|
||||
player: {
|
||||
background: '',
|
||||
color: '',
|
||||
name: '',
|
||||
},
|
||||
previewImageUrl: '',
|
||||
setHotkeys: (v: boolean) => {},
|
||||
onBgChange: (v: string) => {},
|
||||
onColorChange: (v: string) => {},
|
||||
onNameChange: (v: string) => {},
|
||||
replayOnSpeedUp: () => {},
|
||||
replayOnSpeedDown: () => {},
|
||||
replayOnPauseToggle: () => {},
|
||||
disconnect: () => {},
|
||||
},
|
||||
|
||||
replay: {
|
||||
speed: 1,
|
||||
paused: false,
|
||||
},
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
if (!this.$route.params.id) {
|
||||
return
|
||||
}
|
||||
this.$watch(() => this.g.player.background, (value: string) => {
|
||||
this.g.onBgChange(value)
|
||||
})
|
||||
this.$watch(() => this.g.player.color, (value: string) => {
|
||||
this.g.onColorChange(value)
|
||||
})
|
||||
this.$watch(() => this.g.player.name, (value: string) => {
|
||||
this.g.onNameChange(value)
|
||||
})
|
||||
this.g = await main(
|
||||
`${this.$route.params.id}`,
|
||||
// @ts-ignore
|
||||
this.$clientId,
|
||||
// @ts-ignore
|
||||
this.$config.WS_ADDRESS,
|
||||
MODE_REPLAY,
|
||||
this.$el,
|
||||
{
|
||||
setActivePlayers: (v: Array<any>) => { this.activePlayers = v },
|
||||
setIdlePlayers: (v: Array<any>) => { this.idlePlayers = v },
|
||||
setFinished: (v: boolean) => { this.finished = v },
|
||||
setDuration: (v: number) => { this.duration = v },
|
||||
setPiecesDone: (v: number) => { this.piecesDone = v },
|
||||
setPiecesTotal: (v: number) => { this.piecesTotal = v },
|
||||
togglePreview: () => { this.toggle('preview', false) },
|
||||
setConnectionState: (v: number) => { this.connectionState = v },
|
||||
setReplaySpeed: (v: number) => { this.replay.speed = v },
|
||||
setReplayPaused: (v: boolean) => { this.replay.paused = v },
|
||||
}
|
||||
)
|
||||
},
|
||||
unmounted () {
|
||||
this.g.disconnect()
|
||||
},
|
||||
methods: {
|
||||
toggle(overlay: string, affectsHotkeys: boolean): void {
|
||||
if (this.overlay === '') {
|
||||
this.overlay = overlay
|
||||
if (affectsHotkeys) {
|
||||
this.g.setHotkeys(false)
|
||||
}
|
||||
} else {
|
||||
// could check if overlay was the provided one
|
||||
this.overlay = ''
|
||||
if (affectsHotkeys) {
|
||||
this.g.setHotkeys(true)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
replayText (): string {
|
||||
return 'Replay-Speed: ' +
|
||||
(this.replay.speed + 'x') +
|
||||
(this.replay.paused ? ' Paused' : '')
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue