Compare commits

...

8 Commits

Author SHA1 Message Date
Ugo Finnendahl 0dc5eb5226 add watchmode 2 months ago
Ugo Finnendahl b3fa938897 add rest input via / 2 months ago
Ugo Finnendahl 453bcb0d6f add default game to tnm 2 months ago
Ugo Finnendahl 9efe183658 add breaks to end dialog 2 months ago
Ugo Finnendahl ba04659d6f cleanup 2 months ago
Ugo Finnendahl c98daf4b76 remove api from cache 2 months ago
Ugo Finnendahl a1a37631b3 bug fixes for double in 2 months ago
Ugo Finnendahl 6f06cfc428 herbst tnm 2 months ago
  1. 1
      assets/js/components/dialog.js
  2. 19
      assets/js/views/xoi/logic.js
  3. 66
      assets/js/views/xoi/main.js
  4. 29
      content/1_members/24_230/member.txt
  5. 52
      content/2_seasons/1_2024/4_liga/4jujnos9/xoi.txt
  6. 41
      content/2_seasons/1_2024/4_liga/_drafts/template/xoi.txt
  7. 52
      content/2_seasons/1_2024/4_liga/as5ijioi/xoi.txt
  8. 52
      content/2_seasons/1_2024/4_liga/bx8cct6r/xoi.txt
  9. 52
      content/2_seasons/1_2024/4_liga/cien2e5y/xoi.txt
  10. 52
      content/2_seasons/1_2024/4_liga/exgzkzyy/xoi.txt
  11. 52
      content/2_seasons/1_2024/4_liga/gcysu6ge/xoi.txt
  12. 52
      content/2_seasons/1_2024/4_liga/rxwuanez/xoi.txt
  13. 52
      content/2_seasons/1_2024/4_liga/tk69oajx/xoi.txt
  14. 5
      content/2_seasons/1_2024/4_liga/tournament.txt
  15. 52
      content/2_seasons/1_2024/4_liga/u3wssk4j/xoi.txt
  16. 52
      content/2_seasons/1_2024/4_liga/wovzm0jh/xoi.txt
  17. 52
      content/2_seasons/1_2024/4_liga/xdadumtb/xoi.txt
  18. 52
      content/2_seasons/1_2024/4_liga/yw8a9zsz/xoi.txt
  19. 41
      content/2_seasons/1_2024/5_autumn-grand-prix/_drafts/256lip8t/xoi.txt
  20. 41
      content/2_seasons/1_2024/5_autumn-grand-prix/_drafts/cvmylohu/xoi.txt
  21. 41
      content/2_seasons/1_2024/5_autumn-grand-prix/_drafts/hkz96vt7/xoi.txt
  22. 41
      content/2_seasons/1_2024/5_autumn-grand-prix/_drafts/ihap3lgd/xoi.txt
  23. 52
      content/2_seasons/1_2024/5_autumn-grand-prix/bux8rpm6/xoi.txt
  24. 52
      content/2_seasons/1_2024/5_autumn-grand-prix/ce4fqjwm/xoi.txt
  25. 52
      content/2_seasons/1_2024/5_autumn-grand-prix/guuanotg/xoi.txt
  26. 52
      content/2_seasons/1_2024/5_autumn-grand-prix/ivwhmdoe/xoi.txt
  27. 52
      content/2_seasons/1_2024/5_autumn-grand-prix/jfyjddui/xoi.txt
  28. 52
      content/2_seasons/1_2024/5_autumn-grand-prix/jzc8jx4x/xoi.txt
  29. 41
      content/2_seasons/1_2024/5_autumn-grand-prix/miuxwlp4/xoi.txt
  30. 52
      content/2_seasons/1_2024/5_autumn-grand-prix/ngdfd5sd/xoi.txt
  31. 52
      content/2_seasons/1_2024/5_autumn-grand-prix/pnyxwihz/xoi.txt
  32. 52
      content/2_seasons/1_2024/5_autumn-grand-prix/q42hp0bn/xoi.txt
  33. 12
      content/2_seasons/1_2024/5_autumn-grand-prix/tournament.txt
  34. 52
      content/2_seasons/1_2024/5_autumn-grand-prix/wokuqp02/xoi.txt
  35. 52
      content/2_seasons/1_2024/5_autumn-grand-prix/yrb4yey6/xoi.txt
  36. 5
      content/3_boards/boards.txt
  37. 41
      content/3_templates/_drafts/dido301/xoi.txt
  38. 41
      content/3_templates/_drafts/dodo501bof6/xoi.txt
  39. 41
      content/3_templates/_drafts/dodo501bof7/xoi.txt
  40. 5
      content/3_templates/templates.txt
  41. 4
      site/blueprints/pages/member.yml
  42. 10
      site/blueprints/pages/templates.yml
  43. 16
      site/blueprints/pages/tournament.yml
  44. 2
      site/blueprints/pages/xoi.yml
  45. 14
      site/controllers/home.php
  46. 22
      site/models/xoi.php
  47. 6
      sw.js

@ -10,7 +10,6 @@ export default {
const handlers = [ArrowHorizontalKeyHandler];
if (props.withshortkey) {
handlers.push(NumberKeyHandler);
console.log(handlers);
}
handleActive(props, handlers);
const elements = computed(() => props.buttons.map((i) => { i.onClick = () => emit('resolve', i.result ); return i; }) );

@ -113,6 +113,25 @@ export function getGameProps(page, current_set, current_leg) {
});
ret.current_player = current_player;
const breaks = computed(() => {
let b = [0,0];
for (const j in page.game.sets) {
const set = page.game.sets[j];
for (const i in set.legs) {
const l = set.legs[i];
if (l.visits[l.visits.length-1].toGo === undefined) {
return b;
}
if (l.visits[l.visits.length-1].toGo[0] == 0 && i%2 == 1)
b[0] += 1;
else if (l.visits[l.visits.length-1].toGo[1] == 0 && i%2 == 0)
b[1] += 1;
}
}
return b;
});
ret.breaks = breaks;
const getVal = (tr) => {
const val = tr.trim();
if (val == "") {

@ -54,7 +54,7 @@ const pregame = {
<div><span class="label">Player 1:</span><d-playerElem v-index="active" @click="selectPlayer(0)" :player="page.players[0]"></d-playerElem></div>
<div><span class="label">Player 2:</span><d-playerElem v-index="active" @click="selectPlayer(1)" :player="page.players[1]"></d-playerElem></div>
<div><span class="label">X01:</span><d-plainElem v-index="active" @click="selectX01()" :text="page.modus"></d-plainElem></div>
<div><span class="label">Out:</span><d-plainElem v-index="active" @click="selectIn()" :text="page.in"></d-plainElem></div>
<div><span class="label">In:</span><d-plainElem v-index="active" @click="selectIn()" :text="page.in"></d-plainElem></div>
<!-- <div><span class="label">Best of Sets:</span><d-inputElem v-index="active" v-model="page.sets"></d-inputElem></div> -->
<div><span class="label">Best of Legs (per Set):</span><d-inputElem v-index="active" v-model="page.legs"></d-inputElem></div>
<div><d-plainElem text="Start" v-index="active" @click="$emit('resolve', page)"></d-plainElem></div>
@ -127,8 +127,7 @@ const player = {
props: ['page', 'id', 'current_stat'],
setup(props) {
const addStats = (stat1, stat2) => {
console.log(stat1);
return {
let res = {
average: [stat1.average[0]+stat2.average[0], stat1.average[1]+stat2.average[1]],
first9: [stat1.first9[0]+stat2.first9[0], stat1.first9[1]+stat2.first9[1]],
"60+": stat1["60+"]+stat2["60+"],
@ -138,6 +137,12 @@ const player = {
"checkouts": [stat1.checkouts[0]+stat2.checkouts[0], stat1.checkouts[1]+stat2.checkouts[1]],
"checkoutPoints": [...stat1.checkoutPoints, ...stat2.checkoutPoints]
}
if ("checkins" in stat1 && "checkins" in stat2){
res["checkins"] = [stat1.checkins[0]+stat2.checkins[0], stat1.checkins[1]+stat2.checkins[1]];
res["checkinPoints"] = [...stat1.checkinPoints, ...stat2.checkinPoints];
}
return res;
}
const inspect = !!props.page.enddate;
const tourStats = computed(() => {
@ -306,6 +311,9 @@ const gameinput = {
} else if (e.key == "F4" || e.keyCode == 115) {
e.preventDefault();
context.emit('resolve', "26");
} else if (e.key == "/" || e.keyCode == 111 || e.key == "r") {
e.preventDefault();
context.emit('resolve', -1*parseFloat(e.target.value));
}
}
@ -318,7 +326,7 @@ const gameinput = {
const xoi = {
props: ['page', 'active', 'stack', 'inspect'],
props: ['page', 'active', 'stack', 'inspect', 'watch'],
components: {
"d-player": player,
"d-score": score,
@ -336,13 +344,20 @@ const xoi = {
current_leg = computed(() => current_set.value.legs[leg_id.value]);
current_stat = computed( () => props.page.stats?.sets[set_id.value].legs[leg_id.value]);
}
if (props.watch) {
setInterval(async () => {
let gs = await refreshGame(props.page.id);
props.page.game = gs.game;
props.page.stats = gs.stats;
}, 2000);
}
const computedProps = getGameProps(props.page, current_set, current_leg);
if (!props.inspect) {
current_stat = computed( () => props.page.stats?.sets[props.page.stats.sets.length-1].legs[computedProps.current_set.value.legs.length-1]);
}
const mounted = onMounted(async () => {
if (props.inspect) {
if (props.inspect || props.watch) {
} else {
const winner = await gameHandler(gamestack, props.stack, props.page, computedProps)
context.emit('resolve', winner);
@ -449,11 +464,11 @@ const impossibleDialog = (sum) => {
}]}
}
const gameOverDialog = (winner, points) => {
const gameOverDialog = (winner, points, breaks) => {
return {
"withshortkey": true,
"title": `Game Over`,
"text": `${winner != "DRAW" ? "The winner is": ""} ${winner} with ${points[0]}-${points[1]}`,
"text": `${winner != "DRAW" ? "The winner is": ""} ${winner} with ${points[0]}-${points[1]} (Breaks: ${breaks[0]}-${breaks[1]})`,
"buttons": [
{
"component": "d-plainElem",
@ -475,6 +490,15 @@ const gameOverDialog = (winner, points) => {
// API
////////////////////////////////////////////////////////////////////////////////
function refreshGame(id){
return getQuery(`site.find('${id}')`, {
select: {
game: "page.rounds.parseJSON",
stats: "page.stats.parseJSON"
}
})
}
function getGame(id){
return getQuery(`site.find('${id}')`, {
select: {
@ -589,7 +613,11 @@ const gameStateMachine = (gamestack, stack, page, computedProps) => {
1: async (input, reGet) => {
// Normal Game Loop
// Get Game Input
const [visit, error] = await overlayAndPop("d-gameinput", { input: input }, gamestack);
let [visit, error] = await overlayAndPop("d-gameinput", { input: input }, gamestack);
if (parseFloat(visit) < 0 ){
visit = ""+(computedProps.current_toGo.value[computedProps.current_player.value * 1] - parseFloat(visit)*-1);
}
// back/delete last throw
if (error != undefined) {
const val = removeLastVisit(page);
@ -645,7 +673,7 @@ const gameStateMachine = (gamestack, stack, page, computedProps) => {
if (winner != -2){
name = page.players[winner].forename;
}
const [answer, error] = await overlayAndPop("d-dialog", gameOverDialog(name, points[1]), stack);
const [answer, error] = await overlayAndPop("d-dialog", gameOverDialog(name, points[1], computedProps.breaks.value), stack);
if (answer == "end") {
saveGame(page);
return [undefined, page.stats.winner];
@ -667,12 +695,19 @@ export const gameHandler = async (gamestack, stack, page, computedProps) => {
return powerStateMachine(sm, gamestack);
}
function getUrlParam(name) {
var url_string = window.location;
let url = new URL(url_string);
let params = new URLSearchParams(url.search);
return params.get(name);
}
// General State Machine
const stateMachine = (stack, page) => {
return {
0: async (input, reGet) => {
// Dispatcher
// Check if in watchmode
// Check Game State:
if (page.players.length != 2 || page.startdate === undefined || page.startdate === ""){
// Pre Game
@ -683,6 +718,10 @@ const stateMachine = (stack, page) => {
return [2, page];
} else {
// In Game
if (getUrlParam("w") != null){
// Watch Game
return [5, undefined];
}
return [3, page];
}
} else {
@ -738,6 +777,15 @@ const stateMachine = (stack, page) => {
return false;
},1);
return [4, res];
},
5: async (_, reGet) => {
const [res, e] = await overlayAndPop("d-xoi", { page: page, watch: true }, stack);
var re = /^https?:\/\/[^/]+/i;
window.setTimeout(() => {
window.location.href = re.exec(window.location.href)[0];
return false;
},1);
return [5, res];
}
};
}

@ -0,0 +1,29 @@
Title: 10
----
Forename: Junes
----
Surname: Ouakili-Bilan
----
Nickname:
----
Number: 10
----
Pic:
----
Files:
----
Uuid: GZaBDcKmbMICoNZ8

File diff suppressed because one or more lines are too long

@ -0,0 +1,41 @@
Title: Template
----
Max: 501
----
Sets: 1
----
Legs: 6
----
In: Straight
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: qXIhukwbcsAF6tuD

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -27,6 +27,7 @@ Participants:
- page://5bw1wQY8DAfxUVAw
- page://8TlbKlF7fVBwS24c
- page://5qeooGppOFqpprW5
- page://GZaBDcKmbMICoNZ8
----
@ -34,6 +35,10 @@ Date: 2024-12-31
----
Default: - page://nagfzxiV2WxdRc7A
----
Uuid: aCHTbw5ZqTTnO3IY
----

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,41 @@
Title: DIDO301
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: aH5scdKjvS0IS3Jo

@ -0,0 +1,41 @@
Title: Template
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: yPPt29M3WHOZO7u1

@ -0,0 +1,41 @@
Title: DIDO301
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: pKzyBEjOUz9c8ibP

@ -0,0 +1,41 @@
Title: DIDO301
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: z35XfckvPvetLXWA

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,41 @@
Title: DIDO301
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: p3POP6ilQfWDlSUX

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -13,8 +13,8 @@ Participants:
- page://90CUYLfokdOm9Gw0
- page://7GAUHPdaKdD2sHm9
- page://x8tm8FzBBY95HqIi
- page://UkQNJytohCGIXySl
- page://2ymjLWSMV1xXil3P
- page://TbZF36aHK27hZvnK
- page://GZaBDcKmbMICoNZ8
----
@ -22,4 +22,12 @@ Date: 2024-10-19
----
Default: - page://xZwlBgTSJwQtcret
----
Template: - page://xZwlBgTSJwQtcret
----
Uuid: xt5fiX8sJ6Dk3ZPT

@ -1,52 +0,0 @@
Title: wOkUqP02
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
- page://fShTMgFob20fogyr
- page://90CUYLfokdOm9Gw0
----
Startdate: 2024-10-14 22:39:00
----
Enddate:
----
Rounds: {"sets":[{"points":[0,0],"legs":[{"points":[0,0],"visits":[{"player":"page://fShTMgFob20fogyr","throws":[],"visit":1,"checkoutTries":0,"checkinTries":0,"numDarts":0}]}]}]}
----
Stats: {"stats":[{"180":0,"player":"page://fShTMgFob20fogyr","average":[0,0],"first9":[0,0],"checkouts":[0,0],"checkins":[0,0],"checkinPoints":[],"checkoutPoints":[],"60+":0,"100+":0,"140+":0},{"180":0,"player":"page://90CUYLfokdOm9Gw0","average":[0,0],"first9":[0,0],"checkouts":[0,0],"checkins":[0,0],"checkinPoints":[],"checkoutPoints":[],"60+":0,"100+":0,"140+":0}],"sets":[{"stats":[{"180":0,"player":"page://fShTMgFob20fogyr","average":[0,0],"first9":[0,0],"checkouts":[0,0],"checkins":[0,0],"checkinPoints":[],"checkoutPoints":[],"60+":0,"100+":0,"140+":0},{"180":0,"player":"page://90CUYLfokdOm9Gw0","average":[0,0],"first9":[0,0],"checkouts":[0,0],"checkins":[0,0],"checkinPoints":[],"checkoutPoints":[],"60+":0,"100+":0,"140+":0}],"legs":[{"stats":[{"180":0,"player":"page://fShTMgFob20fogyr","average":[0,0],"first9":[0,0],"checkouts":[0,0],"checkins":[0,0],"checkinPoints":[],"checkoutPoints":[],"60+":0,"100+":0,"140+":0},{"180":0,"player":"page://90CUYLfokdOm9Gw0","average":[0,0],"first9":[0,0],"checkouts":[0,0],"checkins":[0,0],"checkinPoints":[],"checkoutPoints":[],"60+":0,"100+":0,"140+":0}]}]}]}
----
Comment:
----
Uuid: 934yZZl3DLYrDfWc

File diff suppressed because one or more lines are too long

@ -1,5 +0,0 @@
Title: Boards
----
Uuid: 38D0Y5SHxMR9Ypkz

@ -0,0 +1,41 @@
Title: DIDO301
----
Max: 301
----
Sets: 1
----
Legs: 7
----
In: Double
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: xZwlBgTSJwQtcret

@ -0,0 +1,41 @@
Title: SIDO501Bof6
----
Max: 501
----
Sets: 1
----
Legs: 6
----
In: Straight
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:
----
Uuid: nagfzxiV2WxdRc7A

@ -0,0 +1,41 @@
Title: SIDO501Bof7
----
Uuid: caLr6s1GrTQpYNvj
----
Max: 501
----
Sets: 1
----
Legs: 7
----
In: Straight
----
Out: Double
----
Players:
----
Startdate:
----
Enddate:
----
Comment:

@ -0,0 +1,5 @@
Title: Templates
----
Uuid: 8NNCfEteOFEqkhoa

@ -17,7 +17,6 @@ create:
sections:
fields:
type: fields
width: 2/3
fields:
forename:
label: First name
@ -41,8 +40,5 @@ sections:
width: 1/6
multiple: false
query: page.images
files:
width: 1/3
sections:
files:
type: files

@ -0,0 +1,10 @@
title: Templates
create:
status: listed
sections:
pages:
type: pages
label: Games
template: xoi

@ -17,6 +17,12 @@ sections:
width: 1/2
label: Date
type: date
default:
width: 1/1
label: Template
type: pages
max: 1
query: site.find("Templates").drafts
# layout:
# type: layout
# layouts:
@ -24,10 +30,18 @@ sections:
# fieldsets:
# - heading
# - simple_game
pages:
type: pages
label: Games
template: xoi
text: "[{{ page.startdate.toDate('d.m.') }}] {{ page.players.toPages.first.forename }} {{ page.players.toPages.first.surname }} vs. {{ page.players.toPages.nth(1).forename }} {{ page.players.toPages.nth(1).surname }}"
sortBy: startdate desc
status: unlisted
# pages2:
# type: pages
# label: Default
# template: xoi
# sortBy: startdate desc
# status: draft
# max: 1
# limit: 1

@ -1,7 +1,7 @@
title: Game
create:
status: listed
status: draft
sections:
fields:

@ -18,12 +18,25 @@ return function ($page, $site, $kirby) {
try {
$kirby->impersonate('kirby');
if ($site->find($tournament)->default()->toPage()){
$json["error"] = $site->find($tournament)->default()->toPage()->out();
$id = $site->find($tournament)->default()->toPage()->copy(
[
'slug' => Str::slug($name),
'parent' => $site->find($tournament),
'children' => false, // copy children
'files' => false, // don't copy files
'isDraft' => false,
]
);
} else {
$id = $site->find($tournament)->createChild([
'content' => $content,
'slug' => Str::slug($name),
'template' => 'xoi',
'isDraft' => false
]);
}
$json["status"] = "ok";
$json["url"] = $id->url();
} catch (\Exception $e) {
@ -38,3 +51,4 @@ return function ($page, $site, $kirby) {
'error' => $error
];
};

@ -16,25 +16,27 @@ class XoiPage extends Page {
$sum["checkouts"][0] += $stat2["checkouts"][0];
$sum["checkoutPoints"] = array_merge($sum["checkoutPoints"], $stat2["checkoutPoints"]);
$sum["checkouts"][1] += $stat2["checkouts"][1];
if (array_key_exists("checkins", $stat1) && array_key_exists("checkins", $stat2)){
$sum["checkins"][0] += $stat2["checkins"][0];
$sum["checkinPoints"] = array_merge($sum["checkinPoints"], $stat2["checkinPoints"]);
$sum["checkins"][1] += $stat2["checkins"][1];
}
$sum["180"] += $stat2["180"];
$sum["140+"] += $stat2["140+"];
$sum["100+"] += $stat2["100+"];
$sum["60+"] += $stat2["60+"];
return $sum;
}
//
// /**
// * @kql-allowed
// */
// public function tournamentStats() {
// if (count($this->playerUUIDs()) == 2){
// return [$this->parent()->getStats($this->playerUUIDs()[0]),$this->parent()->getStats($this->playerUUIDs()[1])];
// }
// return [];
// }
/**
* @kql-allowed
*/
public function tournamentStats() {
if (count($this->playerUUIDs()) == 2){
return [$this->parent()->getStats($this->playerUUIDs()[0]),$this->parent()->getStats($this->playerUUIDs()[1])];
}
return [];
}
//
// public function reorderPlayer($order){
// kirby()->impersonate('kirby');

@ -14,8 +14,8 @@
// Names of the two caches used in this version of the service worker.
// Change to v2, etc. when you update any of the local resources, which will
// in turn trigger the install event again.
const PRECACHE = 'precache-v2';
const RUNTIME = 'runtime-v2';
const PRECACHE = 'precache-v3';
const RUNTIME = 'runtime-v3';
const cacheOn = true;
// A list of local resources we always want to be cached.
@ -51,7 +51,7 @@ self.addEventListener('activate', event => {
// from the network before returning it to the page.
self.addEventListener('fetch', event => {
// Skip cross-origin requests, like those for Google Analytics.
if (event.request.url.startsWith(self.location.origin) && !event.request.url.includes("panel") && event.request.method === "GET" && cacheOn) {
if (event.request.url.startsWith(self.location.origin) && !event.request.url.includes("panel") && !event.request.url.includes("api") && event.request.method === "GET" && cacheOn) {
event.respondWith(
caches.match(event.request).then(cachedResponse => {
if (cachedResponse) {

Loading…
Cancel
Save