import { nextTick, reactive, ref, computed, onMounted, onUnmounted } from "vue"; import { state } from "../stateMgr.js"; import { getQuery } from "../kirby.js"; import { initSubState, ArrowVerticalKeyHandler, ArrowHorizontalKeyHandler, NumberKeyHandler } from "../handlers.js"; const html = (v) => { return v[0] }; function initView(view){ const back = state.view; state.back.push(() => { state.view = back }); state.backActive.push(state.activeIndex); state.view = view; } const togo = { props: ['togo'], setup(props) { return { } }, template: html`
{{ togo }}
` } const game = { props: ['players', 'currentleg', 'max', 'sendvisit', 'modelValue', 'overlay'], setup(props, context) { const length = computed(() => props.currentleg?.visits.length ); const visits = computed(() => props.currentleg? props.currentleg.visits:undefined ); const loop = computed(() => Math.max(length.value?length.value+(length.value?length.value%2:0):0,18) ); const getPlayerVisits = (uuid) => { const vs = visits.value.filter((v) => v.player == uuid); if (vs.length < 9) { for (var i = vs.length; i < 9; i++) { vs.push({ "sum": "", "toGo":["",""]}) } } else if (vs.length*2 < visits.value.length) { vs.push({ "sum": "", "toGo":["",""]}); } return vs; } const check_remove = (event) => { if (!event.repeat && event.target.value.length < 1) { context.emit('removeLastVisit', event.target); } } const setup = ref(false); const setupEnter = () => { setup.value = true; } const confirmEnter = (evt) => { if (setup.value) { context.emit('sendvisit', evt.target) } setup.value = false; } return { length, visits, loop, getPlayerVisits, check_remove, confirmEnter, setupEnter } }, template: html`
Points
ToGo
Round
Points
ToGo
{{ max }}
0
{{ max }}
` } const overlay = { props: ['data'], setup(props, context) { const keyhandler = (event) => { ArrowHorizontalKeyHandler(event); NumberKeyHandler(event); if (event.key == "Escape") { context.emit("closeOverlay") } } return { keyhandler } }, template: html`

{{ data.title }}

{{ data.text }}

` } const score = { props: ['page', 'justlegs', 'currentset', 'currentleg'], setup(props) { return { } }, template: html`

{{ currentset?.points[idx] }}

Best of {{ page?.sets }}

Sets

{{ currentleg?.points[idx] }}

Best of {{ page?.legs }}

Legs

` } const player = { props: ['player', 'stats', "id"], setup(props) { const current_set = computed( () => props.stats?.sets[props.stats.sets.length-1]); const current_leg = computed( () => current_set.value?.legs[current_set.value.legs.length-1]); const getAverage = (avg) => { return avg && avg[1] != 0 ? ((3*avg[0])/avg[1]).toFixed(1) : "-"; } const getCheckout = (checkout) => { return checkout && checkout[1] != 0 ? Math.round(1000*checkout[0]/checkout[1])/10 : "- " } const getMax = (checkouts) => { if (checkouts && checkouts.length != 0) { return Math.max(...checkouts); } return "-" } return { current_set, current_leg, getAverage, getCheckout, getMax } }, template: html`

{{ player?.forename }} {{ player?.surname }}

{{ player?.nickname }}

Stat
Match
Leg
Average:
{{ getAverage(stats?.stats[id].average) }}
{{ getAverage(current_leg?.stats[id].average) }}
First 9:
{{ getAverage(stats?.stats[id].first9) }}
{{ getAverage(current_leg?.stats[id].first9) }}
60+:
{{ stats?.stats[id]["60+"] }}
{{ current_leg?.stats[id]["60+"] }}
100+:
{{ stats?.stats[id]["100+"] }}
{{ current_leg?.stats[id]["100+"] }}
140+:
{{ stats?.stats[id]["140+"] }}
{{ current_leg?.stats[id]["140+"] }}
180:
{{ stats?.stats[id]["180"] }}
{{ current_leg?.stats[id]["180"] }}
Checkouts:
{{ getCheckout(stats?.stats[id].checkouts) }}%
Best Checkout:
{{ getMax(stats?.stats[id].checkoutPoints) }}
` } export const xoi = { components: { "d-togo": togo, "d-score": score, "d-game": game, "d-player": player, "d-overlay": overlay }, setup(props, context) { let page = ref(); const updateGame = (reset) => { getQuery(`site.find('${state.id}')`, { select: { title: "page.title", id: "page.id", modus: "page.max", game: "page.rounds.parseJSON", stats: "page.stats.parseJSON", sets: "page.sets", legs: "page.legs", players: { query: "page.players.toPages", select:{ forename: "page.forename", surname: "page.surname", nickname: "page.nickname", uuid: "page.uuid", img: "page.pic.toFile?.url" } } } }).then((res) => { page.value = res; if (reset != undefined) { current_input.value = reset; } if (res.stats.winner){ console.log(res.stats); let winner = "Draw"; if (res.players[0].uuid == res.stats.winner){ winner = res.players[0].forename; } else if (res.players[1].uuid == res.stats.winner) { winner = res.players[1].forename; } overlay.value = { "title": "Game Ended", "text": `The winner is ${winner}`, "buttons": [] }; } }); }; updateGame(); let game = computed(() => page.value ? page.value.game: undefined) let current_set = computed(() => { if (game.value != undefined) { return game.value.sets[game.value.sets.length-1] } return undefined; }) let current_leg = computed(() => { if (current_set.value != undefined) { return current_set.value.legs[current_set.value.legs.length-1] } return undefined; }) let current_toGo = computed(() => { if (current_leg.value != undefined) { if (current_leg.value.visits.length < 2) { return [page.value.modus, page.value.modus] } else { return current_leg.value.visits[current_leg.value.visits.length-2].toGo; } } return [0,0]; }) let current_set_points = computed(() => { if (current_set.value != undefined) { return current_set.value.points; } return undefined; }); let current_leg_points = computed(() => { if (current_leg.value != undefined) { return current_leg.value.points; } return undefined; }); let current_player = computed(() => { if (current_leg.value != undefined) { const len = current_leg.value.visits.length; return current_leg.value.visits[len-1].player == page.value.players[1].uuid; } return undefined; }); const current_input = ref(""); const overlay = ref(); return { page, state, game, current_set, current_leg, current_toGo, current_set_points, current_leg_points, current_player, updateGame, current_input, overlay } }, methods: { async removeLastVisit(){ let last = this.current_leg.visits.length-2 >= 0 ? this.current_leg.visits[this.current_leg.visits.length-2].throws : [""]; last = last.join(","); const response = await fetch(`/${state.id}`, { method: "POST", cache: "no-cache", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "action": "deleteLastThrow", "visit": true, }), }); const ret = await response.json(); if (ret.status == "ok"){ this.updateGame(last); } else { console.log(ret); } }, sum(tr){ const val = tr.trim();; if (val == "") { return 0; } if (val == "SB"){ return 25; } if (val == "DB"){ return 50; } if (val[0] == "S" || val[0] == "O" || val[0] == "I"){ return parseFloat(val.substring(1)); } if (val[0] == "D"){ return 2*parseFloat(val.substring(1)); } if (val[0] == "T"){ return 3*parseFloat(val.substring(1)); } if (val[0] == "M"){ return 0; } else { // TODO: Check for Na return parseFloat(val); } }, verify(sum){ if (this.current_toGo[this.current_player*1]-sum == 0){ return 0; } else if (sum > 180 || [179, 178, 176, 175, 173, 172, 169, 166, 163].indexOf(sum) > -1) { return -1 } else if (this.current_toGo[this.current_player*1]-sum <= 50) { return 1 } }, openOverlay(overlay){ this.overlay = overlay; }, closeOverlay(){ this.overlay = undefined; }, checkout_question(throws){ const buttons = []; for (var i = 1; i <= 3; i++) { const x = i; buttons.push({ "type": "input", "props" : { "type": "button", "value": `${x} (${x})` }, "onClick": () => { this.closeOverlay(); this.checkouttries_question(throws, x, false); } }) } this.openOverlay({ "title": "Congratulations!", "text": `How many darts did you need?` , "buttons": buttons }); }, checkouttries_question(throws, numDarts, zero=true){ const buttons = []; for (var i = 1; i <= numDarts; i++) { const x = i; buttons.push({ "type": "input", "props" : { "type": "button", "value": `${x} (${x})` }, "autofocus": (i==1 && !zero), "onClick": () => { this.closeOverlay(); this.send_visit(throws, numDarts, x) } }) } if (zero) { buttons.push({ "type": "input", "props" : { "type": "button", "value": `0 (${numDarts+1})` }, "autofocus": true, "onClick": () => { this.closeOverlay(); this.send_visit(throws, numDarts, 0) } }) } this.openOverlay({ "title": "Checkout Tries", "text": `How many tries on a Checkout?` , "buttons": buttons }); }, async send_visit(throws, numDarts=3, checkoutTries=0){ const response = await fetch(`/${state.id}`, { method: "POST", cache: "no-cache", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "action": "addThrows", "throws": throws.value.split(","), "checkoutTries": checkoutTries, "numDarts": numDarts, "done": true }), }); const ret = await response.json(); if (ret.status == "ok"){ this.updateGame(""); } else { console.log(ret); } }, async preprocess_visit(throws){ const tr = throws.value.split(","); let sum = 0; tr.forEach((t, i) => { sum += this.sum(t); }); const res = this.verify(sum); if (res == 0){ // Ask for num Darts this.checkout_question(throws); return; } else if (res == 1){ // Ask for checkoutTries this.checkouttries_question(throws, 3); return; } else if (res == -1){ this.openOverlay({ "title": "Impossible", "text": `A score of ${sum} is not possible`, "buttons": [{ "type": "input", "props" : { "type": "button", "value": "ok" }, "onClick" : this.closeOverlay }] }); return; } this.send_visit(throws); } }, template: html`
` } export const initXoiView = (app) => { app.component('d-xoi', xoi) }