move new game setup to new component

This commit is contained in:
Zutatensuppe 2021-05-13 14:01:10 +02:00
parent 734b7eacc8
commit 722be39ad9
2 changed files with 106 additions and 71 deletions

View file

@ -0,0 +1,94 @@
"use strict"
import GameCommon from './../../common/GameCommon.js'
import Upload from './../components/Upload.vue.js'
import ImageTeaser from './../components/ImageTeaser.vue.js'
export default {
name: 'NewGameDialog',
components: {
Upload,
ImageTeaser,
},
template: `
<div>
<h1>New game</h1>
<table>
<tr>
<td><label>Pieces: </label></td>
<td><input type="text" v-model="tiles" /></td>
</tr>
<tr>
<td><label>Scoring: </label></td>
<td>
<label><input type="radio" v-model="scoreMode" value="1" /> Any (Score when pieces are connected to each other or on final location)</label>
<br />
<label><input type="radio" v-model="scoreMode" value="0" /> Final (Score when pieces are put to their final location)</label>
</td>
</tr>
<tr>
<td><label>Image: </label></td>
<td>
<span v-if="image">
<img :src="image.url" style="width: 150px;" />
or
<upload @uploaded="mediaImgUploaded($event)" accept="image/*" label="Upload an image" />
</span>
<span v-else>
<upload @uploaded="mediaImgUploaded($event)" accept="image/*" label="Upload an image" />
(or select from below)
</span>
</td>
</tr>
<tr>
<td colspan="2">
<button class="btn" :disabled="!canStartNewGame" :class="" @click="onNewGameClick">Start new game</button>
</td>
</tr>
</table>
<h1>Image lib</h1>
<div>
<image-teaser v-for="i in images" :image="i" @click="image = i" />
</div>
</div>`,
props: {
images: Array,
},
emits: {
newGame: null,
},
data() {
return {
tiles: 1000,
image: '',
scoreMode: GameCommon.SCORE_MODE_ANY,
}
},
methods: {
mediaImgUploaded(j) {
this.image = j.image
},
canStartNewGame () {
if (!this.tilesInt || !this.image || ![0, 1].includes(this.scoreModeInt)) {
return false
}
return true
},
onNewGameClick() {
this.$emit('newGame', {
tiles: this.tilesInt,
image: this.image,
scoreMode: this.scoreModeInt,
})
},
},
computed: {
scoreModeInt () {
return parseInt(this.scoreMode, 10)
},
tilesInt () {
return parseInt(this.tiles, 10)
},
},
}

View file

@ -1,64 +1,28 @@
"use strict" "use strict"
import GameCommon from './../../common/GameCommon.js'
import Time from './../../common/Time.js' import Time from './../../common/Time.js'
import Upload from './../components/Upload.vue.js'
import GameTeaser from './../components/GameTeaser.vue.js' import GameTeaser from './../components/GameTeaser.vue.js'
import ImageTeaser from './../components/ImageTeaser.vue.js' import NewGameDialog from './../components/NewGameDialog.vue.js'
export default { export default {
components: { components: {
Upload,
GameTeaser, GameTeaser,
ImageTeaser, NewGameDialog,
}, },
template: ` template: `
<div id="app"> <div id="app">
<span class="btn" @click="showNewGameDialog = !showNewGameDialog">New game</span>
<new-game-dialog
v-if="showNewGameDialog"
:images="images"
@newGame="onNewGame"
/>
<h1>Running games</h1> <h1>Running games</h1>
<div class="game-teaser-wrap" v-for="g in gamesRunning"> <div class="game-teaser-wrap" v-for="g in gamesRunning">
<game-teaser :game="g" /> <game-teaser :game="g" />
</div> </div>
<h1>New game</h1>
<table>
<tr>
<td><label>Pieces: </label></td>
<td><input type="text" v-model="tiles" /></td>
</tr>
<tr>
<td><label>Scoring: </label></td>
<td>
<label><input type="radio" v-model="scoreMode" value="1" /> Any (Score when pieces are connected to each other or on final location)</label>
<br />
<label><input type="radio" v-model="scoreMode" value="0" /> Final (Score when pieces are put to their final location)</label>
</td>
</tr>
<tr>
<td><label>Image: </label></td>
<td>
<span v-if="image">
<img :src="image.url" style="width: 150px;" />
or
<upload @uploaded="mediaImgUploaded($event)" accept="image/*" label="Upload an image" />
</span>
<span v-else>
<upload @uploaded="mediaImgUploaded($event)" accept="image/*" label="Upload an image" />
(or select from below)
</span>
</td>
</tr>
<tr>
<td colspan="2">
<button class="btn" :disabled="!canStartNewGame" :class="" @click="onNewGameClick">Start new game</button>
</td>
</tr>
</table>
<h1>Image lib</h1>
<div>
<image-teaser v-for="i in images" :image="i" @click="image = i" />
</div>
<h1>Finished games</h1> <h1>Finished games</h1>
<div class="game-teaser-wrap" v-for="g in gamesFinished"> <div class="game-teaser-wrap" v-for="g in gamesFinished">
<game-teaser :game="g" /> <game-teaser :game="g" />
@ -66,9 +30,7 @@ export default {
</div>`, </div>`,
data() { data() {
return { return {
tiles: 1000, showNewGameDialog: false,
image: '',
scoreMode: GameCommon.SCORE_MODE_ANY,
gamesRunning: [], gamesRunning: [],
gamesFinished: [], gamesFinished: [],
@ -82,20 +44,6 @@ export default {
this.gamesFinished = json.gamesFinished this.gamesFinished = json.gamesFinished
this.images = json.images this.images = json.images
}, },
computed: {
scoreModeInt () {
return parseInt(this.scoreMode, 10)
},
tilesInt () {
return parseInt(this.tiles, 10)
},
canStartNewGame () {
if (!this.tilesInt || !this.image || ![0, 1].includes(this.scoreModeInt)) {
return false
}
return true
},
},
methods: { methods: {
time(start, end) { time(start, end) {
const icon = end ? '🏁' : '⏳' const icon = end ? '🏁' : '⏳'
@ -104,21 +52,14 @@ export default {
const timeDiffStr = Time.timeDiffStr(from, to) const timeDiffStr = Time.timeDiffStr(from, to)
return `${icon} ${timeDiffStr}` return `${icon} ${timeDiffStr}`
}, },
mediaImgUploaded(j) { async onNewGame(gameSettings) {
this.image = j.image
},
async onNewGameClick() {
const res = await fetch('/newgame', { const res = await fetch('/newgame', {
method: 'post', method: 'post',
headers: { headers: {
'Accept': 'application/json', 'Accept': 'application/json',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify({ body: JSON.stringify(gameSettings),
tiles: this.tilesInt,
image: this.image,
scoreMode: this.scoreModeInt,
}),
}) })
if (res.status === 200) { if (res.status === 200) {
const game = await res.json() const game = await res.json()