puzzle/src/frontend/views/NewGame.vue

133 lines
4 KiB
Vue
Raw Normal View History

2021-05-21 00:43:02 +02:00
"New Game" page: Upload button big, centered, at the top of the page, as
visible as possible. Upload button has a warning that the image will
be added to public gallery, just so noone uploads anything naughty on
accident. The page can show all the images by default, or one of the categories
of images. Instead of categories, you can make the system tag-based, like
in jigsawpuzzles.io
2021-05-17 00:27:47 +02:00
<template>
<div>
2021-05-21 00:43:02 +02:00
<div class="upload-image-teaser">
<div class="btn btn-big" @click="dialog='new-image'">Upload your image</div>
<div class="hint">(The image you upload will be added to the public gallery.)</div>
</div>
<div>
<label v-if="categories.length > 0">
Category:
<select v-model="filters.category" @change="filtersChanged">
<option value="">All</option>
2021-05-22 01:51:44 +02:00
<option v-for="(c, idx) in categories" :key="idx" :value="c.slug">{{c.title}}</option>
2021-05-21 00:43:02 +02:00
</select>
</label>
<label>
Sort by:
<select v-model="filters.sort" @change="filtersChanged">
<option value="date_desc">Newest first</option>
<option value="date_asc">Oldest first</option>
<option value="alpha_asc">A-Z</option>
<option value="alpha_desc">Z-A</option>
</select>
</label>
</div>
2021-05-22 01:51:44 +02:00
<image-library :images="images" @imageClicked="imageClicked" />
<new-image-dialog v-if="dialog==='new-image'" @bgclick="dialog=''" @postToGalleryClick="postToGalleryClick" @setupGameClick="setupGameClick" />
2021-05-21 00:43:02 +02:00
<new-game-dialog v-if="image && dialog==='new-game'" @bgclick="dialog=''" @newGame="onNewGame" :image="image" />
2021-05-17 00:27:47 +02:00
</div>
</template>
2021-05-13 16:58:21 +02:00
2021-05-17 00:27:47 +02:00
<script lang="ts">
import { defineComponent } from 'vue'
2021-05-13 16:58:21 +02:00
2021-05-21 00:43:02 +02:00
import ImageLibrary from './../components/ImageLibrary.vue'
import NewImageDialog from './../components/NewImageDialog.vue'
2021-05-17 00:27:47 +02:00
import NewGameDialog from './../components/NewGameDialog.vue'
2021-05-21 00:43:02 +02:00
import { GameSettings, Image } from '../../common/GameCommon'
import Util from '../../common/Util'
2021-05-17 00:27:47 +02:00
export default defineComponent({
2021-05-13 16:58:21 +02:00
components: {
2021-05-21 00:43:02 +02:00
ImageLibrary,
NewImageDialog,
2021-05-13 16:58:21 +02:00
NewGameDialog,
},
data() {
return {
2021-05-21 00:43:02 +02:00
filters: {
sort: 'date_desc',
category: '',
},
2021-05-13 16:58:21 +02:00
images: [],
2021-05-21 00:43:02 +02:00
categories: [],
image: {
2021-05-22 01:51:44 +02:00
id: 0,
filename: '',
2021-05-21 00:43:02 +02:00
file: '',
2021-05-22 01:51:44 +02:00
url: '',
2021-05-21 00:43:02 +02:00
title: '',
2021-05-22 01:51:44 +02:00
categories: [],
created: 0,
2021-05-21 00:43:02 +02:00
} as Image,
dialog: '',
2021-05-13 16:58:21 +02:00
}
},
async created() {
2021-05-21 00:43:02 +02:00
await this.loadImages()
2021-05-13 16:58:21 +02:00
},
methods: {
2021-05-21 00:43:02 +02:00
async loadImages () {
const res = await fetch(`/api/newgame-data${Util.asQueryArgs(this.filters)}`)
const json = await res.json()
this.images = json.images
this.categories = json.categories
},
async filtersChanged () {
await this.loadImages()
},
imageClicked (image: Image) {
this.image = image
this.dialog = 'new-game'
},
2021-05-22 01:51:44 +02:00
async uploadImage (data: any) {
const formData = new FormData();
formData.append('file', data.file, data.file.name);
formData.append('title', data.title)
formData.append('category', data.category)
const res = await fetch('/upload', {
method: 'post',
body: formData,
})
return await res.json()
},
async postToGalleryClick(data: any) {
await this.uploadImage(data)
this.dialog = ''
await this.loadImages()
},
async setupGameClick (data: any) {
const image = await this.uploadImage(data)
this.loadImages() // load images in background
2021-05-21 00:43:02 +02:00
this.image = image
this.dialog = 'new-game'
},
async onNewGame(gameSettings: GameSettings) {
2021-05-13 16:58:21 +02:00
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()
2021-05-15 11:06:37 +02:00
this.$router.push({ name: 'game', params: { id: game.id } })
2021-05-13 16:58:21 +02:00
}
2021-05-21 00:43:02 +02:00
},
},
2021-05-17 00:27:47 +02:00
})
</script>