diff --git a/frontend/static/css/TournamentPage.css b/frontend/static/css/TournamentPage.css new file mode 100644 index 0000000..d9c826b --- /dev/null +++ b/frontend/static/css/TournamentPage.css @@ -0,0 +1,51 @@ +#tournament-tree { + display:flex; + flex-direction:row; +} + +.round { + display:flex; + flex-direction:column; + justify-content:center; + width:200px; + list-style:none; + padding:0; +} + +.round .spacer{ flex-grow:1; } +.round .spacer:first-child, +.round .spacer:last-child{ flex-grow:.5; } + +.round .game-spacer{ + flex-grow:1; +} + +body{ + font-family:sans-serif; + font-size:small; + padding:10px; + line-height:1.4em; +} + +li.game{ +padding-left:20px; +} + +li.game.winner{ + font-weight:bold; +} +li.game span{ + float:right; + margin-right:5px; +} + +li.game-top{ border-bottom:1px solid #aaa; } + +li.game-spacer{ + border-right:1px solid #aaa; + min-height:40px; +} + +li.game-bottom{ + border-top:1px solid #aaa; +} \ No newline at end of file diff --git a/frontend/static/js/api/tournament/Tournament.js b/frontend/static/js/api/tournament/Tournament.js index e5e4682..2d727ce 100644 --- a/frontend/static/js/api/tournament/Tournament.js +++ b/frontend/static/js/api/tournament/Tournament.js @@ -102,7 +102,7 @@ class Tourmanent return; this.connected = false; this._socket.close(); - this.disconnect_func(event); + this.disconnectHandler(event); } toggle_participation() @@ -112,13 +112,40 @@ class Tourmanent this._socket.send(JSON.stringify({participate: ""})); } + async onParticipantsUpdate(data) + { + oldParticipantList = this.par + + await this.participantsUpdateHandler(); + } + + async onError(data) + { + await this.errorHandler(data); + } + + /** + * + * @param {MessageEvent} event + */ + onReceive(event) + { + const data = JSON.parse(event.data); + + if (data?.detail === "error") + this.onError(data); + else if (data?.detail === "participants_update") + this.onParticipantsUpdate(data); + } + /** * Join the tournament Websocket - * @param {CallableFunction} receive_func - * @param {CallableFunction} disconnect_func + * @param {CallableFunction} errorHandler + * @param {CallableFunction} participantsUpdateHandler + * @param {CallableFunction} disconnectHandler * @returns {?} */ - async join(receive_func, disconnect_func) + async join(participantsUpdateHandler, errorHandler, disconnectHandler) { if (!await this.client.isAuthenticated()) return null; @@ -130,13 +157,11 @@ class Tourmanent this.connected = true; this.isParticipating = false; - this.receive_func = receive_func; - this.disconnect_func = disconnect_func; + this.participantsUpdateHandler = participantsUpdateHandler; + this.errorHandler = errorHandler; + this.disconnectHandler = disconnectHandler; - this._socket.onmessage = function (event) { - const data = JSON.parse(event.data); - receive_func(data); - }; + this._socket.onmessage = this.onReceive.bind(this); this._socket.onclose = this.leave.bind(this); } diff --git a/frontend/static/js/views/tournament/TournamentPageView.js b/frontend/static/js/views/tournament/TournamentPageView.js index d36fd3d..20a52a1 100644 --- a/frontend/static/js/views/tournament/TournamentPageView.js +++ b/frontend/static/js/views/tournament/TournamentPageView.js @@ -1,3 +1,5 @@ +import { Profile } from "../../api/Profile.js"; +import { Tourmanent } from "../../api/tournament/Tournament.js"; import {client, navigateTo} from "../../index.js"; import AbstractAuthenticatedView from "../abstracts/AbstractAuthenticatedView.js"; @@ -14,10 +16,61 @@ export default class extends AbstractAuthenticatedView this.tournament.toggle_participation(); } + createGraph() + { + console.log(this.tournament); + let tournament_tree = document.createElement("div"); + + tournament_tree.id = "tournament-tree"; + + document.getElementById("app").appendChild(tournament_tree); + + for (let round_id = 0; round_id < this.tournament.levels.length; round_id++) + { + let current_round = document.createElement("ul"); + + tournament_tree.appendChild(current_round); + + current_round.className = `round round-${round_id}`; + + for (let participant_i = 0; participant_i < this.tournament.levels[round_id].length; participant_i += 2) + { + let spacer = document.createElement("li"); + + spacer.className = "spacer"; + spacer.innerText = " "; + + current_round.appendChild(spacer); + + let game_top = document.createElement("li"); + + game_top.className = "game game-top"; + game_top.innerText = `${this.tournament.levels[round_id][participant_i]}`; + + current_round.appendChild(game_top); + + let game_spacer = document.createElement("li"); + + spacer.className = "game game-spacer"; + spacer.innerText = " "; + + current_round.appendChild(game_spacer); + + let game_bottom = document.createElement("li"); + + game_bottom.className = "game game-bottom"; + game_bottom.innerText = `${this.tournament.levels[round_id][participant_i + 1]}`; + + current_round.appendChild(game_bottom); + } + } + + } + async receive(data) { - if (data.detail === "nb_participants" || data.detail === "update_participants") - document.getElementById("nb_participants").innerText = `${data.nb_participants} / ${this.tournament.nb_players}`; + if (data.detail === "update_participants") + document.getElementById("nb_participants").innerText = `${data.participants} / ${this.tournament.nb_players}`; if (data.detail === "go_to") navigateTo(data.url); if (data.detail === "is_participant") @@ -32,36 +85,56 @@ export default class extends AbstractAuthenticatedView document.getElementById("display").innerText = state ? "You are a particpant" : "You are not a participant"; } - async ondisconnect(event) + /** + * + * @param {[Profile]} oldParticipantsList + * @param {[Profile]} currentParticipantsList + */ + async onParticipantsUpdate(oldParticipantsList, currentParticipantsList) { + + } + + async onDisconnect(event) + { + } + + async onError(data) + { + } async postInit() { + /** + * @type {Tourmanent} + */ this.tournament = await client.tournaments.getTournament(this.id); if (this.tournament === null) return 404; - this.tournament.join(this.receive.bind(this), this.ondisconnect.bind(this)); + this.tournament.join(this.onParticipantsUpdate.bind(this), this.onError.bind(this), this.onDisconnect.bind(this)); let button = document.getElementById("button"); button.onclick = this.pressButton.bind(this); document.getElementById("name").innerText = this.tournament.name; - document.getElementById("nb_players").innerText = this.tournament.nb_players; + document.getElementById("nb_participants").innerText = this.tournament.nb_players; document.getElementById("nb_players_by_game").innerText = this.tournament.nb_players_by_game; document.getElementById("level").innerText = this.tournament.level; document.getElementById("state").innerText = this.tournament.state; if (this.tournament.started === false) button.disabled = false; + this.createGraph(); } async getHtml() { return ` +