prepare use of vue for game/replay

This commit is contained in:
Zutatensuppe 2021-05-13 16:58:21 +02:00
parent 343263be6c
commit 8e7aa7d453
7 changed files with 156 additions and 43 deletions

18
public/App.vue.js Normal file
View file

@ -0,0 +1,18 @@
export default {
name: 'app',
template: `
<div id="app">
<ul class="nav" v-if="showNav">
<li><router-link class="btn" :to="{name: 'index'}">Index</router-link></li>
<li><router-link class="btn" :to="{name: 'new-game'}">New game</router-link></li>
</ul>
<router-view />
</div>`,
computed: {
showNav () {
// TODO: add info wether to show nav to route props
return !['game', 'replay'].includes(this.$route.name)
},
},
}

View file

@ -2,13 +2,30 @@
<head>
<link rel="stylesheet" href="/style.css" />
<script src="https://unpkg.com/vue@3.0.11"></script>
<script src="https://unpkg.com/vue-router@4.0.8"></script>
<title>🧩 jigsaw.hyottoko.club</title>
</head>
<body>
<div id="app"></div>
<script type="module">
import App from "/App.vue.js"
import Index from "/views/Index.vue.js"
const app = Vue.createApp(Index)
import NewGame from "/views/NewGame.vue.js"
import Game from "/views/Game.vue.js"
import Replay from "/views/Replay.vue.js"
const router = VueRouter.createRouter({
history: VueRouter.createWebHashHistory(),
routes: [
{ name: 'index', path: '/', component: Index },
{ name: 'new-game', path: '/new-game', component: NewGame },
{ name: 'game', path: '/g/:id', component: Game },
{ name: 'replay', path: '/replay/:id', component: Replay },
],
})
const app = Vue.createApp(App)
app.use(router)
app.mount('#app')
</script>
</body>

26
public/views/Game.vue.js Normal file
View file

@ -0,0 +1,26 @@
"use strict"
export default {
name: 'game',
template: `<div>{{gameData}}</div>`,
data() {
return {
gameData: null,
}
},
created() {
this.$watch(
() => this.$route.params,
() => { this.fetchData() },
{ immediate: true }
)
},
methods: {
async fetchData() {
this.gameData = null
const res = await fetch(`/api/game-data/${this.$route.params.id}`)
const json = await res.json()
this.gameData = json
},
},
}

View file

@ -2,45 +2,27 @@
import Time from './../../common/Time.js'
import GameTeaser from './../components/GameTeaser.vue.js'
import NewGameDialog from './../components/NewGameDialog.vue.js'
export default {
components: {
GameTeaser,
NewGameDialog,
},
// TODO: use vue router
template: `
<div id="app">
<ul class="nav">
<li><span class="btn" @click="view = 'index'">Home</span></li>
<li><span class="btn" @click="view = 'new-game'">New game</span></li>
</ul>
<div>
<h1>Running games</h1>
<div class="game-teaser-wrap" v-for="g in gamesRunning">
<game-teaser :game="g" />
</div>
<new-game-dialog v-if="view === 'new-game'"
:images="images"
@newGame="onNewGame"
/>
<div v-if="view === 'index'">
<h1>Running games</h1>
<div class="game-teaser-wrap" v-for="g in gamesRunning">
<game-teaser :game="g" />
</div>
<h1>Finished games</h1>
<div class="game-teaser-wrap" v-for="g in gamesFinished">
<game-teaser :game="g" />
</div>
<h1>Finished games</h1>
<div class="game-teaser-wrap" v-for="g in gamesFinished">
<game-teaser :game="g" />
</div>
</div>`,
data() {
return {
view: 'index',
gamesRunning: [],
gamesFinished: [],
images: [],
}
},
async created() {
@ -48,7 +30,6 @@ export default {
const json = await res.json()
this.gamesRunning = json.gamesRunning
this.gamesFinished = json.gamesFinished
this.images = json.images
},
methods: {
time(start, end) {
@ -58,19 +39,5 @@ export default {
const timeDiffStr = Time.timeDiffStr(from, to)
return `${icon} ${timeDiffStr}`
},
async onNewGame(gameSettings) {
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()
location.assign(game.url)
}
}
}
}

View file

@ -0,0 +1,40 @@
"use strict"
import NewGameDialog from './../components/NewGameDialog.vue.js'
export default {
components: {
NewGameDialog,
},
// TODO: maybe move dialog back, now that this is a view on its own
template: `
<div>
<new-game-dialog :images="images" @newGame="onNewGame" />
</div>`,
data() {
return {
images: [],
}
},
async created() {
const res = await fetch('/api/newgame-data')
const json = await res.json()
this.images = json.images
},
methods: {
async onNewGame(gameSettings) {
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()
location.assign(game.url)
}
}
}
}

View file

@ -0,0 +1,26 @@
"use strict"
export default {
name: 'replay',
template: `<div>{{replayData}}</div>`,
data() {
return {
replayData: null,
}
},
created() {
this.$watch(
() => this.$route.params,
() => { this.fetchData() },
{ immediate: true }
)
},
methods: {
async fetchData() {
this.replayData = null
const res = await fetch(`/api/replay-data/${this.$route.params.id}`)
const json = await res.json()
this.replayData = json
},
},
}