This repository has been archived on 2024-04-29. You can view files and clone it, but cannot push or open issues or pull requests.
node-fftcg/frontend/src/components/forms/DeckEditor.vue

198 lines
4.7 KiB
Vue
Raw Normal View History

2019-05-16 15:47:58 +00:00
<template>
2019-05-17 13:24:52 +00:00
<v-container v-if="value">
<v-card flat>
<v-alert :value="count !== 50" type="warning">
{{ count }} cards detected! (Decks should have exactly 50 cards)
</v-alert>
<v-alert :value="maximum > 3" type="warning">
Card with {{ maximum }} copies detected! (Cards should not have more
than 3 copies)
</v-alert>
<v-textarea
ref="textarea"
label="Edit Deck"
:value="list"
rows="35"
hint="Change card counts and/or serial numbers. Names will be updated automatically."
style="font-family: monospace"
>
</v-textarea>
<v-card-actions>
<v-btn color="error" @click.native="$emit('input', false)">
<v-icon>cancel</v-icon>
cancel
</v-btn>
<v-spacer></v-spacer>
<v-btn color="info" @click.native="check">
<v-icon>check</v-icon>
validate
</v-btn>
<v-btn color="success" @click.native="save" :disabled="!checked">
<v-icon>save</v-icon>
save
</v-btn>
</v-card-actions>
</v-card>
</v-container>
2019-05-16 15:47:58 +00:00
</template>
<script>
2019-05-20 15:02:39 +00:00
import * as Cookies from 'js-cookie'
import axios from '@/plugins/axios'
2019-05-16 15:47:58 +00:00
export default {
name: 'DeckEditor',
props: {
2019-05-17 13:24:52 +00:00
id: Number,
list: String,
value: Boolean
2019-05-16 15:47:58 +00:00
},
data: () => ({
2019-05-17 13:24:52 +00:00
count: 50,
maximum: 0,
checked: false
2019-05-16 15:47:58 +00:00
}),
2019-05-20 15:02:39 +00:00
computed: {
session: () => Cookies.get('session')
},
2019-05-16 15:47:58 +00:00
methods: {
parse_deck(deck_string) {
let retval = {
name: '',
note: '',
cards: [],
count: 0
}
// select all lines containing card serial numbers
let cardLinesRE = /^.*\b\d-\d{3}[A-Z]?\b.*$/gm
let cardLines = deck_string.match(cardLinesRE)
2019-05-16 23:16:22 +00:00
let cardCounts = {}
2019-05-16 15:47:58 +00:00
cardLines.forEach(cardLine => {
// extract serial (guaranteed to be in here!)
let serialRE = /\b(\d-\d{3})[A-Z]?\b/i
let serial = serialRE.exec(cardLine)[1]
// strip out serial number
cardLine = cardLine.replace(serialRE, '')
let countREs = [
// prioritize a count with "times" symbol *, x, ×
/\b([0-9]+)(?:[*×]|[x]\b)/,
/(?:[*×]|\b[x])([0-9]+)\b/,
// next priority: count with whitespace
/\s+([0-9]+)\s+/,
/\s+([0-9]+)\b/,
/\b([0-9]+)\s+/,
// least priority: any simple number
/\b([0-9]+)\b/
]
// fallback value
let count = 1
for (let i = 0; i < countREs.length; i++) {
let data = countREs[i].exec(cardLine)
if (data) {
count = Number(data[1])
break
}
}
2019-05-16 23:16:22 +00:00
// count copies
if (!cardCounts[serial]) {
cardCounts[serial] = 0
}
cardCounts[serial] += count
retval.count += count
})
// push card data into deck
Object.keys(cardCounts).forEach(serial => {
2019-05-16 15:47:58 +00:00
retval.cards.push({
serial: serial,
2019-05-16 23:16:22 +00:00
count: cardCounts[serial]
2019-05-16 15:47:58 +00:00
})
})
// strip out lines with serial numbers
deck_string = deck_string.replace(cardLinesRE, '')
// select the line containing 'deck name:'
// and its successor (ffdecks format)
let metaRE = /^Deck Name: (.+)$[\s]*?^(.+)$/m
let metaData = metaRE.exec(deck_string)
// fallback
retval.name = 'Unnamed Deck'
retval.note = ''
if (!metaData) {
// no ffdecks format found: strip out anything after the first empty line
deck_string = deck_string.replace(/^[\s]*$[^]*/m, '')
// use lax format: <anything>:[deck name][newline][note]
metaRE = /[^]*?:(.+)$[\s]*?^([^]*)/m
metaData = metaRE.exec(deck_string)
}
// look again, I am not an else!
if (metaData) {
// extract matches
retval.name = metaData[1].trim()
retval.note = metaData[2].trim()
}
return retval
},
check() {
let new_deck = this.parse_deck(this.$refs.textarea.lazyValue)
2019-05-16 23:16:22 +00:00
// count number of cards
2019-05-17 13:24:52 +00:00
this.count = new_deck.count
2019-05-16 23:16:22 +00:00
// find most frequent card
2019-05-17 13:24:52 +00:00
this.maximum = 0
2019-05-16 23:16:22 +00:00
new_deck.cards.forEach(card => {
2019-05-17 13:24:52 +00:00
if (card.count > this.maximum) this.maximum = card.count
2019-05-16 23:16:22 +00:00
})
2019-05-17 13:24:52 +00:00
// deck has now been checked
this.checked = true
2019-05-20 15:02:39 +00:00
},
save() {
let new_deck = this.parse_deck(this.$refs.textarea.lazyValue)
axios
.post('/decks/modify', {
session: this.session,
deckID: this.id,
deckCards: new_deck
})
.then(response => {
if (response.data.success) {
this.close()
}
})
2019-05-16 15:47:58 +00:00
}
2019-05-17 13:24:52 +00:00
},
activated() {
console.log('Frosch')
2019-05-16 15:47:58 +00:00
}
}
</script>