(async () => { // check notification permission // This is useful to alert people that they should do something await Notification.requestPermission() })() const problems_count = JSON.parse(document.getElementById('problems_count').textContent) const tournaments = JSON.parse(document.getElementById('tournaments_list').textContent) let socket = null const messages = document.getElementById('messages') /** * Request to abort the draw of the given tournament. * Only volunteers are allowed to do this. * @param tid The tournament id */ function abortDraw(tid) { socket.send(JSON.stringify({'tid': tid, 'type': 'abort'})) } /** * Request to cancel the last step. * Only volunteers are allowed to do this. * @param tid The tournament id */ function cancelLastStep(tid) { socket.send(JSON.stringify({'tid': tid, 'type': 'cancel'})) } /** * Request to launch a dice between 1 and 100, for the two first steps. * The parameter `trigram` can be specified (by volunteers) to launch a dice for a specific team. * @param tid The tournament id * @param trigram The trigram of the team that a volunteer wants to force the dice launch (default: null) */ function drawDice(tid, trigram = null) { socket.send(JSON.stringify({'tid': tid, 'type': 'dice', 'trigram': trigram})) } /** * Request to draw a new problem. * @param tid The tournament id */ function drawProblem(tid) { socket.send(JSON.stringify({'tid': tid, 'type': 'draw_problem'})) } /** * Accept the current proposed problem. * @param tid The tournament id */ function acceptProblem(tid) { socket.send(JSON.stringify({'tid': tid, 'type': 'accept'})) } /** * Reject the current proposed problem. * @param tid The tournament id */ function rejectProblem(tid) { socket.send(JSON.stringify({'tid': tid, 'type': 'reject'})) } /** * Volunteers can export the draw to make it available for notation. * @param tid The tournament id */ function exportDraw(tid) { socket.send(JSON.stringify({'tid': tid, 'type': 'export'})) } /** * Volunteers can make the draw continue for the second round of the final. * @param tid The tournament id */ function continueFinal(tid) { socket.send(JSON.stringify({'tid': tid, 'type': 'continue_final'})) } /** * Display a new notification with the given title and the given body. * @param title The title of the notification * @param body The body of the notification * @param timeout The time (in milliseconds) after that the notification automatically closes. 0 to make indefinite. Default to 5000 ms. * @return Notification */ function showNotification(title, body, timeout = 5000) { let notif = new Notification(title, {'body': body, 'icon': "/static/tfjm.svg"}) if (timeout) setTimeout(() => notif.close(), timeout) return notif } document.addEventListener('DOMContentLoaded', () => { if (document.location.hash) { // Open the tab of the tournament that is present in the hash document.querySelectorAll('button[data-bs-toggle="tab"]').forEach(elem => { if ('#' + elem.innerText.toLowerCase() === document.location.hash.toLowerCase()) { elem.click() } }) } // When a tab is opened, add the tournament name in the hash document.querySelectorAll('button[data-bs-toggle="tab"]').forEach( elem => elem.addEventListener( 'click', () => document.location.hash = '#' + elem.innerText.toLowerCase())) /** * Add alert message on the top on the interface. * @param message The content of the alert. * @param type The alert type, which is a bootstrap color (success, info, warning, danger,…). * @param timeout The time (in milliseconds) before the alert is auto-closing. 0 to infinitely, default to 5000 ms. */ function addMessage(message, type, timeout = 5000) { const wrapper = document.createElement('div') wrapper.innerHTML = [ `