SotM_Playfield/src/Editor.vue

153 lines
4.3 KiB
Vue
Raw Normal View History

2018-12-28 10:46:01 -05:00
<template>
<div>
2019-01-04 16:11:27 -05:00
<headful :title="'Editor|' + deckInfo.meta.name"> </headful>
2018-12-28 10:46:01 -05:00
<div id="controls">
<div>
<button type="button" @click="upload"> Save Deck </button>
Download:
2018-12-28 10:46:01 -05:00
<button type="button" @click="jsonInputDownload">
Input JSON
2018-12-28 10:46:01 -05:00
</button>
<button type="button"
@click="downloadFile(`/decks/${deckID}.tts.json`, deckInfo.meta.name + '.tts.json')">
Tabletop Output JSON
</button>
<button type="button"
@click="downloadFile(`/decks/${deckID}.png`, deckInfo.meta.name + '.png')">
Deck PNG
2018-12-28 10:46:01 -05:00
</button>
</div>
<div>
<label> Upload JSON: WARNING: WILL CLEAR DECK
<input @change="jsonUpload" type="file">
</label>
</div>
<div>
<label> Deck Name: <input type="text" v-model="deckInfo.meta.name"> </label>
<label> Deck Type:
<select v-model="deckInfo.meta.type">
<option value="hero">hero</option>
<option value="villain">villain</option>
<option value="environment">environment</option>
</select>
</label>
</div>
2018-12-28 10:46:01 -05:00
</div>
<div id="cardEditor" v-if="selected">
<button class="close-editor" @click="selected = null">X</button>
<div v-for="(type, prop) in selected.props">
2018-12-28 10:46:01 -05:00
<label> {{ prop }}
<input v-if="type === 'image'" type="file" accept="image/*"
@change="fileUploaded(prop, $event)" />
<textarea v-else-if="type === 'textarea'" v-model="selected.card[prop]"> </textarea>
<input v-else :type="type" v-model="selected.card[prop]"/>
2018-12-28 10:46:01 -05:00
</label>
</div>
</div>
<Deck ref="deck" :cards="deckInfo.cards" v-model="selected"> </Deck>
2018-12-28 10:46:01 -05:00
</div>
</template>
<script>
import yaml from 'js-yaml';
import Deck from './Deck.vue';
2018-12-28 10:46:01 -05:00
export default {
name: 'Editor',
components: {Deck},
2018-12-28 10:46:01 -05:00
props: ['deckID'],
2018-12-28 10:46:01 -05:00
data() {
return {
selected: null,
deckInfo: {meta: {name: "", type: ""},
cards: {}},
2018-12-28 10:46:01 -05:00
};
},
created() {
if (this.deckID !== 'new') {
fetch('/decks/' + this.deckID + '.json')
.then(r => r.json())
2019-01-06 09:48:51 -05:00
.then(j => this.deckInfo = j.deck)
.catch((err) => console.log('did not get old JSON, starting new deck'));
}
2018-12-28 10:46:01 -05:00
/* window.addEventListener(
* 'beforeunload', e => e.returnValue = "Unsaved changes blah blah"); */
},
methods: {
// deck JSON uploader
jsonUpload(event) {
let files = event.target.files;
let reader = new FileReader();
reader.onload = e => this.deckInfo = yaml.safeLoad(e.target.result);
2018-12-28 10:46:01 -05:00
reader.readAsText(files[0]);
},
// download input JSON
jsonInputDownload() {
console.log(JSON.stringify(this.deckInfo));
this.downloadFile('data:application/json;charset=utf-8,' +
encodeURIComponent(JSON.stringify(this.deckInfo)),
this.deckID + '.input.json')
2018-12-28 10:46:01 -05:00
},
fileUploaded(event, prop) {
let reader = new FileReader();
reader.onload = e => {
this.selected.card[prop] = e.target.result;
};
reader.readAsDataURL(event.target.files[0]);
2018-12-28 10:46:01 -05:00
},
downloadFile(file, name) {
let dl = document.createElement('a');
dl.setAttribute('href', file);
dl.setAttribute('download', name);
document.body.appendChild(dl);
dl.click();
document.body.removeChild(dl);
},
upload() {
// POST the inputed json to the server
fetch('/upload', {
2018-12-28 10:46:01 -05:00
method: 'post',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
deck: this.deckInfo,
_id: this.deckID === 'new' ? undefined : this.deckID,
dom: (new XMLSerializer()).serializeToString(this.$refs.deck.$el),
css: document.styleSheets[0].href,
})})
.then(r => r.json())
.then(j => this.$router.replace('/edit/' + j.id))
.catch(err => console.log('Failed to upload' + err));
2018-12-28 10:46:01 -05:00
},
},
}
</script>
<style>
#cardEditor {
position: fixed;
top: 0;
right: 0;
background-color: gray;
padding: 10px;
border-radius: 3px;
}
.close-editor {
float: right;
}
</style>