import InputSuggestions from "./input-suggestions"; import * as MatchmakingStatus from "./tribe-mm-status"; import TribeDefaultConfigs from "./tribe-default-configs"; import * as Misc from "./misc"; import * as UI from "./ui"; import Config, * as UpdateConfig from "./config"; import * as CustomText from "./custom-text"; import * as Notifications from "./notifications"; import * as Funbox from "./funbox"; import * as ThemeColors from "./theme-colors"; import Chart from "chart.js"; import * as TestLogic from "./test-logic"; import * as TestUI from "./test-ui"; import * as Commandline from "./commandline"; import * as CommandlineLists from "./commandline-lists"; import seedrandom from "seedrandom"; export let state = -1; export let socket = io( window.location.hostname === "localhost" ? "http://localhost:3000" : "https://tribe.monkeytype.com", { // socket: io("http://localhost:3000", { autoConnect: false, secure: true, reconnectionAttempts: 1, } ); export let reconnectionAttempts = 0; export let maxReconnectionAttempts = 1; export let activePage = "preloader"; export let pageTransition = false; export let expectedVersion = "0.9.21"; export let room = undefined; let name = undefined; let autoJoin = undefined; let lastQueue = undefined; export function setAutoJoin(code) { autoJoin = code; } let shouldScrollChat = true; let lobbySuggestions; let resultSuggestions; Misc.getEmojiList().then((list) => { lobbySuggestions = new InputSuggestions( $(".pageTribe .lobby .chat .input .emojiSuggestion"), list, ["test", "miodec", "vastus"] ); resultSuggestions = new InputSuggestions( $(".pageTest #result .tribeResultChat .chat .input .emojiSuggestion"), list, [] ); }); let tribeSounds = { join: new Audio("../sound/tribe_ui/join.wav"), leave: new Audio("../sound/tribe_ui/leave.wav"), start: new Audio("../sound/tribe_ui/start.wav"), chat1: new Audio("../sound/tribe_ui/chat1.wav"), chat2: new Audio("../sound/tribe_ui/chat2.wav"), chat_mention: new Audio("../sound/tribe_ui/chat_mention.wav"), finish: new Audio("../sound/tribe_ui/finish.wav"), finish_win: new Audio("../sound/tribe_ui/finish_win.wav"), glow: new Audio("../sound/tribe_ui/glow.wav"), cd: new Audio("../sound/tribe_ui/cd2.wav"), cd_go: new Audio("../sound/tribe_ui/cd_go2.wav"), }; //-1 - disconnected //1 - connected //6 - looking for a public game //7 - in a public lobby waiting to fill //8 - one second before public start //10 - lobby //20 - test about to start //21 - test active //28 - leader finished //29 - everybody finished export function init() { $(".pageTribe .preloader .icon").html( `` ); $(".pageTribe .preloader .text").text("Connecting to Tribe"); socket.connect(); } function changeActiveSubpage(newPage) { if (pageTransition) return; if (newPage === activePage) return; pageTransition = true; UI.swapElements( $(`.pageTribe .${activePage}`), $(`.pageTribe .${newPage}`), 250, () => { if (newPage === "prelobby") { socket.emit("mp_get_online_stats"); } if (newPage === "lobby") { $(".pageTribe .lobby .chat .input input").focus(); } pageTransition = false; activePage = newPage; } ); } function refreshUserList() { $(".pageTribe .lobby .userlist .list").empty(); $(".pageTest #result .tribeResultChat .userlist .list").empty(); let usersArray = []; let names = []; Object.keys(room.users).forEach((sid) => { let u = room.users[sid]; u.sid = sid; if (sid !== socket.id) { names.push(u.name); } usersArray.push(u); }); lobbySuggestions.setNameList(names); resultSuggestions.setNameList(names); let sortedUsers = usersArray.sort((a, b) => b.points - a.points); sortedUsers.forEach((user) => { let icons = ""; if (user.isLeader) { if (user.sid === socket.id) { room.isLeader = true; } icons += `
`; } else { icons += `
`; } icons += `
`; let pointsString; if (user.points == undefined) { pointsString = ""; } else { pointsString = user.points + (user.points == 1 ? "pt" : "pts"); } $(".pageTribe .lobby .userlist .list").append(`
${icons}
${user.name}
${ room.isLeader && user.sid !== socket.id ? `
` : `` }
${pointsString}
`); $(".pageTest #result .tribeResultChat .userlist .list").append(`
${icons}
${user.name}
${ room.isLeader && user.sid !== socket.id ? `
` : `` }
${pointsString}
`); }); } function playSound(sound) { tribeSounds[sound].currentTime = 0; tribeSounds[sound].play(); } function resetLobby() { $(".pageTribe .lobby .userlist .list").empty(); $(".pageTest #result .tribeResultChat .chat .messages").empty(); $(".pageTest #result .tribeResultChat .userlist .list").empty(); $(".pageTribe .lobby .chat .messages").empty(); $(".pageTribe .lobby .inviteLink .code .text").text(""); $(".pageTribe .lobby .inviteLink .link").text(""); $(".pageTest .tribeResultChat .inviteLink .code .text").text(""); $(".pageTest .tribeResultChat .inviteLink .link").text(""); $("#tribeCountdownWrapper .faint").addClass("hidden"); $("#tribeCountdownWrapper .withbg").addClass("hidden"); } export function resetRace() { $(".pageTest .tribePlayers").empty().addClass("hidden"); $(".pageTribe .lobby .tribePlayers").empty().addClass("hidden"); hideCountdown(); hideResultCountdown(); // $(".pageTest #result .tribeResult").addClass("hidden"); // $(".pageTest #result .tribeResultChat").addClass("hidden"); } function applyRoomConfig(cfg) { UpdateConfig.setMode(cfg.mode, true, true); if (cfg.mode === "time") { UpdateConfig.setTimeConfig(cfg.mode2, true, true); } else if (cfg.mode === "words") { UpdateConfig.setWordCount(cfg.mode2, true, true); } else if (cfg.mode === "quote") { UpdateConfig.setQuoteLength(cfg.mode2, true, true, true); } UpdateConfig.setDifficulty(cfg.difficulty, true, true); UpdateConfig.setBlindMode(cfg.blindMode, true, true); UpdateConfig.setLanguage(cfg.language, true, true); Funbox.activate(cfg.funbox, null, true); UpdateConfig.setStopOnError(cfg.stopOnError, true, true); UpdateConfig.setConfidenceMode(cfg.confidenceMode, true, true); UpdateConfig.setPunctuation(cfg.punctuation, true, true); UpdateConfig.setNumbers(cfg.numbers, true, true); if (cfg.minAcc != null) { UpdateConfig.setMinAccCustom(cfg.minAcc, true, true); UpdateConfig.setMinAcc("custom", true, true); } else { UpdateConfig.setMinAcc("off", true, true); } if (cfg.minWpm != null) { UpdateConfig.setMinWpmCustomSpeed(cfg.minAcc, true, true); UpdateConfig.setMinWpm("custom", true, true); } else { UpdateConfig.setMinWpm("off", true, true); } if (cfg.customText !== null) { CustomText.setText(cfg.customText.text); CustomText.setIsWordRandom(cfg.customText.isWordRandom); CustomText.setIsTimeRandom(cfg.customText.isTimeRandom); CustomText.setTime(cfg.customText.time); CustomText.setWord(cfg.customText.word); } } export function checkIfCanChangeConfig(mp) { if (state >= 6) { if (state >= 20 && state < 29) { Notifications.add("You can't change settings during the test", 0, 1); return false; } else if (room !== undefined && room.isLeader) { return true; } else { if (mp) return true; if (room.private) { Notifications.add("Only the leader can change this setting", 0, 1); return false; } else { Notifications.add("You can't change settings when matchmaking", 0, 1); return false; } } } else { return true; } } let syncConfigTimeout = null; export function syncConfig() { setSettingsLoadingIndicator(true); if (syncConfigTimeout === null) { syncConfigTimeout = setTimeout(() => { setSettingsLoadingIndicator(false); let mode2; if (Config.mode === "time") { mode2 = Config.time; } else if (Config.mode === "words") { mode2 = Config.words; } else if (Config.mode === "quote") { mode2 = Config.quoteLength === undefined ? "-1" : Config.quoteLength; } socket.emit("mp_room_config_update", { config: { mode: Config.mode, mode2: mode2, difficulty: Config.difficulty, blindMode: Config.blindMode, language: Config.language, funbox: Funbox.active, stopOnError: Config.stopOnError, confidenceMode: Config.confidenceMode, customText: { text: CustomText.text, isWordRandom: CustomText.isWordRandom, isTimeRandom: CustomText.isTimeRandom, word: CustomText.word, time: CustomText.time, }, punctuation: Config.punctuation, numbers: Config.numbers, minWpm: Config.minWpm === "custom" ? Config.minWpmCustomSpeed : null, minAcc: Config.minAcc === "custom" ? Config.minAccCustom : null, }, }); clearTimeout(syncConfigTimeout); syncConfigTimeout = null; }, 500); } } export function joinRoomByCode(code) { code = "room_" + code; socket.emit("mp_room_join", { roomId: code }); $(".pageTribe .prelobby #joinByCode input").val(""); $(".pageTribe .prelobby #joinByCode .customInput").html(` -- / -- / -- `); } export function startTest() { if (syncConfigTimeout !== null) return; if (room.newTestCooldown) return; room.isReady = true; socket.emit("mp_room_test_start"); } export function sendTestProgress(wpm, raw, acc, progress) { if (state >= 21 && state <= 28 && TestLogic.active) { socket.emit("mp_room_test_progress_update", { sid: socket.id, roomId: room.id, stats: { wpm: wpm, raw: raw, acc: acc, progress: progress, }, }); } } function refreshTestUserList() { $(".tribePlayers").empty(); Object.keys(room.users).forEach((sid) => { if ( (room.private && (room.users[sid].isTyping || room.users[sid].isReady || room.users[sid].isLeader)) || !room.private ) { let user = room.users[sid]; let me = ""; if (sid === socket.id) { me = " me"; } $(".tribePlayers").append(` ${user.name}
-
-
`); } }); $(".tribePlayers").removeClass("hidden"); $(".tribeResult table tbody").empty(); Object.keys(room.users).forEach((sid) => { if ( (room.private && (room.users[sid].isTyping || room.users[sid].isReady || room.users[sid].isLeader)) || !room.private ) { let user = room.users[sid]; let me = ""; if (sid === socket.id) { me = " me"; } $(".tribeResult table tbody").append(` ${user.name} -
-
-
-
-
-
-
`); } }); $(".tribeResult").removeClass("hidden"); } function refreshConfig() { if (room == undefined) return; $(".pageTribe .lobby .currentSettings .groups").empty(); $(".pageTribe .lobby .currentSettings .groups").append(`
${room.config.mode}
`); if (room.config.mode === "time") { $(".pageTribe .lobby .currentSettings .groups").append(`
${room.config.mode2}
`); } else if (room.config.mode === "words") { $(".pageTribe .lobby .currentSettings .groups").append(`
${room.config.mode2}
`); } else if (room.config.mode === "quote") { let qstring = "all"; let num = room.config.mode2; if (num == 0) { qstring = "short"; } else if (num == 1) { qstring = "medium"; } else if (num == 2) { qstring = "long"; } else if (num == 3) { qstring = "thicc"; } $(".pageTribe .lobby .currentSettings .groups").append(`
${qstring}
`); } else if (room.config.mode === "custom") { let t = "Custom settings:"; t += `\ntext length: ${CustomText.text.length}`; if (CustomText.isTimeRandom || CustomText.isWordRandom) { let r = ""; let n = ""; if (CustomText.isTimeRandom) { r = "time"; n = CustomText.time; } else if (CustomText.isWordRandom) { r = "words"; n = CustomText.word; } t += `\nrandom: ${r} ${n}`; } $(".pageTribe .lobby .currentSettings .groups").append(`
custom
`); } $(".pageTribe .lobby .currentSettings .groups").append(`
!?${ room.config.punctuation ? "on" : "off" }
`); $(".pageTribe .lobby .currentSettings .groups").append(`
15${room.config.numbers ? "on" : "off"}
`); $(".pageTribe .lobby .currentSettings .groups").append(`
${room.config.language}
`); if (room.config.difficulty === "normal") { $(".pageTribe .lobby .currentSettings .groups").append(`
normal
`); } else if (room.config.difficulty === "expert") { $(".pageTribe .lobby .currentSettings .groups").append(`
expert
`); } else if (room.config.difficulty === "master") { $(".pageTribe .lobby .currentSettings .groups").append(`
master
`); } if (room.config.blindMode) { $(".pageTribe .lobby .currentSettings .groups").append(`
blind
`); } else { $(".pageTribe .lobby .currentSettings .groups").append(`
off
`); } $(".pageTribe .lobby .currentSettings .groups").append(`
${room.config.funbox}
`); if (room.config.confidenceMode === "off") { $(".pageTribe .lobby .currentSettings .groups").append(`
off
`); } else if (room.config.confidenceMode === "on") { $(".pageTribe .lobby .currentSettings .groups").append(`
confidence
`); } else if (room.config.confidenceMode === "max") { $(".pageTribe .lobby .currentSettings .groups").append(`
max
`); } if (room.config.stopOnError === "off") { $(".pageTribe .lobby .currentSettings .groups").append(`
off
`); } else { $(".pageTribe .lobby .currentSettings .groups").append(`
stop on ${room.config.stopOnError}
`); } $(".pageTribe .lobby .currentSettings .groups").append(`
${ room.config.minWpm == null ? "off" : room.config.minWpm + "wpm" }
`); $(".pageTribe .lobby .currentSettings .groups").append(`
${ room.config.minAcc == null ? "off" : room.config.minAcc + "%" }
`); } export function testFinished(result) { if (state >= 21) { socket.emit("mp_room_test_finished", { result: result }); } } function showCountdown(faint = false) { if (faint) { $("#tribeCountdownWrapper .faint").removeClass("hidden"); } else { $("#tribeCountdownWrapper .withbg").removeClass("hidden"); } } function hideCountdown() { $("#tribeCountdownWrapper .faint").addClass("hidden"); $("#tribeCountdownWrapper .withbg").addClass("hidden"); } function updateCountdown(text) { $("#tribeCountdownWrapper .number").text(text); } function fadeoutCountdown() { $("#tribeCountdownWrapper .faint").animate( { opacity: 0, }, 125, () => { $("#tribeCountdownWrapper .faint") .addClass("hidden") .css("opacity", 0.075); } ); $("#tribeCountdownWrapper .withbg").animate( { opacity: 0, }, 125, () => { $("#tribeCountdownWrapper .withbg").addClass("hidden").css("opacity", 1); } ); } function showResultCountdown() { $("#result .tribeResult .timer").animate({ opacity: 1 }, 125); } function hideResultCountdown() { $("#result .tribeResult .timer").animate({ opacity: 0 }, 125); } function updateResultCountdown(text) { $("#result .tribeResult .timer").text(text); } export function scrollChat() { let chatEl = $(".pageTribe .lobby .chat .messages")[0]; let chatEl2 = $(".pageTest #result .tribeResultChat .chat .messages")[0]; if (shouldScrollChat) { chatEl.scrollTop = chatEl.scrollHeight; chatEl2.scrollTop = chatEl2.scrollHeight; shouldScrollChat = true; } } // function updateAllGraphs(graphs, max) { // try { // graphs.forEach((graph) => { // if (graph.options.scales.yAxes[0].ticks.max < Math.round(max)) { // graph.options.scales.yAxes[0].ticks.max = Math.round(max); // graph.options.scales.yAxes[1].ticks.max = Math.round(max); // } // }); // } catch (e) { // console.error("Something went wrong while updating max graph values " + e); // } // } function fillGraphDataAndUpdate(graph, result, sid) { let labels = []; for (let i = 1; i <= result.chartData.wpm.length; i++) { labels.push(i); } let graphmaxval = Math.max( Math.max(...result.chartData.wpm), Math.max(...result.chartData.raw) ); graph.data.labels = labels; graph.data.datasets[0].data = result.chartData.wpm; graph.data.datasets[1].data = result.chartData.raw; graph.data.datasets[2].data = result.chartData.err; graph.options.scales.yAxes[0].ticks.max = Math.round(graphmaxval); graph.options.scales.yAxes[1].ticks.max = Math.round(graphmaxval); if (sid == socket.id) { graph.data.datasets[0].borderColor = ThemeColors.main; graph.data.datasets[0].pointBackgroundColor = ThemeColors.main; } else { graph.data.datasets[0].borderColor = ThemeColors.text; graph.data.datasets[0].pointBackgroundColor = ThemeColors.text; } graph.data.datasets[1].borderColor = ThemeColors.sub; graph.data.datasets[1].pointBackgroundColor = ThemeColors.sub; graph.update({ duration: 0 }); } function drawMinigraph(sid, result) { try { let graphelem = $(`.tribeResult .player[sid='${sid}'] .graph canvas`)[0]; let graph = new Chart(graphelem, miniChartSettings); fillGraphDataAndUpdate(graph, result, sid); return graph; } catch (e) { Notifications.add("Error drawing mini graph: " + e.message, -1); } } function destroyAllGraphs() { Object.keys(room.userGraphs).forEach((sid) => { let userGraph = room.userGraphs[sid]; userGraph.graph.clear(); userGraph.graph.destroy(); delete room.userGraphs[sid]; }); } function setSettingsLoadingIndicator(truefalse) { if (truefalse) { $(".pageTribe .lobby .currentSettings .loadingIndicator").removeClass( "hidden" ); } else { $(".pageTribe .lobby .currentSettings .loadingIndicator").addClass( "hidden" ); } } function userReady() { $(".pageTribe .lobby .lobbyButtons .userReadyButton").addClass("disabled"); $(".pageTest #result .resultMpButtons .userReadyButton").addClass("disabled"); $(".pageTest #result #readyButton").addClass("disabled"); socket.emit("mp_user_ready"); } function resetReadyButtons() { if (room.isLeader === false && room.isReady === false) { $(".pageTribe .lobby .lobbyButtons .userReadyButton").removeClass( "disabled" ); $(".pageTest #result .resultMpButtons .userReadyButton").removeClass( "disabled" ); $(".pageTest #result #readyButton").removeClass("disabled"); $(".pageTribe .lobby .lobbyButtons .userReadyButton").removeClass("hidden"); $(".pageTest #result .resultMpButtons .userReadyButton").removeClass( "hidden" ); $(".pageTest #result #readyButton").removeClass("hidden"); } else { let cls = "disabled"; if (room.isLeader) { cls = "hidden"; } $(".pageTribe .lobby .lobbyButtons .userReadyButton").addClass(cls); $(".pageTest #result .resultMpButtons .userReadyButton").addClass(cls); $(".pageTest #result #readyButton").addClass(cls); } } function resetLeaderButtons() { if (room.isLeader) { $(".pageTribe .lobby .lobbyButtons .startTestButton").removeClass("hidden"); $(".pageTest #result #backToLobbyButton").removeClass("hidden"); } else { $(".pageTribe .lobby .lobbyButtons .startTestButton").addClass("hidden"); $(".pageTest #result #backToLobbyButton").addClass("hidden"); } } function showTribeUserSettingsPopup() { if ($("#tribeUserSettingsPopupWrapper").hasClass("hidden")) { $("#tribeUserSettingsPopupWrapper") .stop(true, true) .css("opacity", 0) .removeClass("hidden") .animate({ opacity: 1 }, 100); } } function hideTribeUserSettingsPopup() { if (!$("#tribeUserSettingsPopupWrapper").hasClass("hidden")) { $("#tribeUserSettingsPopupWrapper") .stop(true, true) .css("opacity", 1) .animate( { opacity: 0, }, 100, (e) => { $("#tribeUserSettingsPopup").attr("sid", ""); $("#tribeUserSettingsPopupWrapper").addClass("hidden"); } ); } } function updateTribeUserSettingsPopup(sid) { $("#tribeUserSettingsPopup").attr("sid", sid); $("#tribeUserSettingsPopup .title").text( "User settings: " + room.users[sid].name ); } export function setName(newname) { name = newname; socket.emit("mp_system_name_set", { name: newname }); } export function sendIsTypingUpdate(truefalse) { socket.emit("mp_room_user_istypingupdate", { sid: socket.id, typing: truefalse, name: name, }); } function updateWhoIsTyping() { let string = ""; let names = []; Object.keys(room.whoIsTyping).forEach((sid) => { if (room.whoIsTyping[sid].truefalse && sid !== socket.id) { names.push(room.whoIsTyping[sid].name); } }); if (names.length > 0) { for (let i = 0; i < names.length; i++) { if (i === 0) { string += `${names[i]}`; } else if (i === names.length - 1) { string += ` and ${names[i]}`; } else { string += `, ${names[i]}`; } } if (names.length == 1) { string += " is typing..."; } else { string += " are typing..."; } } else { string = " "; } $(".pageTribe .lobby .chat .whoIsTyping").html(string); $(".pageTest #result .tribeResultChat .chat .whoIsTyping").html(string); } export function updateTribeDiff(currentSpeed) { if (state >= 21 && state <= 28 && TestLogic.active) { let elem = $("#tribeDiff"); elem.removeClass("ahead"); elem.removeClass("behind"); let maxwpm = 0; Object.keys(room.userSpeeds).forEach((sid) => { if (room.userSpeeds[sid] > maxwpm) maxwpm = room.userSpeeds[sid]; }); let diff = Math.round(maxwpm - currentSpeed); if (diff == 0) { elem.text("--"); } else if (diff > 0) { elem.text("-" + diff); elem.addClass("behind"); } else { elem.addClass("ahead"); elem.text("+" + Math.abs(diff)); } } } export function showHideTribeDiff(showhide) { if (showhide) { $("#tribeDiff").removeClass("hidden"); } else { $("#tribeDiff").addClass("hidden"); } } function resetTribeDiff() { let elem = $("#tribeDiff"); elem.removeClass("ahead"); elem.removeClass("behind"); elem.text("--"); } async function insertImageEmoji(text) { text = text.trim().split(" "); let big = ""; if (text.length === 1) big = " big"; for (let i = 0; i < text.length; i++) { if (/:.+:/g.test(text[i])) { let emoji = await Misc.getEmojiList(); let result = emoji.filter((e) => e.from == text[i].replace(/:/g, "")); if (result[0] !== undefined) { text[ i ] = `
`; } } } return text.join(" "); } socket.on("connect", (f) => { UpdateConfig.setTimerStyle("mini", true); state = 1; reconnectionAttempts = 0; Notifications.add("Connected to Tribe", 1); let name = "Guest"; if (firebase.auth().currentUser !== null) { name = firebase.auth().currentUser.displayName; } setName(name); changeActiveSubpage("prelobby"); showHideTribeDiff(true); setTimeout(() => { if (autoJoin) { socket.emit("mp_room_join", { roomId: autoJoin }); autoJoin = undefined; // swapElements($(".pageTribe .preloader"), $(".pageTribe .lobby"), 250); } else { // swapElements($(".pageTribe .preloader"), $(".pageTribe .prelobby"), 250); } }, 500); }); socket.on("mp_room_name_update", (data) => { room.users[data.sid].name = data.name; refreshUserList(); }); socket.on("mp_update_online_stats", (data) => { $(".pageTribe .prelobby .welcome .stats").empty(); $(".pageTribe .prelobby .welcome .stats").append( `
Online ${data.online}
` ); $(".pageTribe .prelobby .welcome .stats").append( `
Active Races ${data.rooms}
` ); $(".pageTribe .prelobby .welcome .stats").append( `
Version ${data.version}
` ); if (data.version !== expectedVersion) { Notifications.add( `Tribe version mismatch. Try refreshing or clearing cache. Client version: ${expectedVersion}, server version: ${data.version}`, -1 ); socket.disconnect(); } }); socket.on("mp_update_name", (data) => { name = data.newName; }); socket.on("disconnect", (f) => { state = -1; room = undefined; Notifications.add("Disconnected from Tribe", 0); resetLobby(); resetRace(); changeActiveSubpage("preloader"); showHideTribeDiff(false); MatchmakingStatus.reset(); // $(".pageTribe .preloader div").removeClass("hidden"); // $(".pageTribe .preloader").removeClass("hidden").css("opacity", 1); // $(".pageTribe .preloader .icon").html(``); // $(".pageTribe .preloader .text").text(`Disconnected from Tribe`); }); socket.on("connect_failed", (f) => { state = -1; changeActiveSubpage("preloader"); // $(".pageTribe .preloader div").removeClass("hidden"); // $(".pageTribe .preloader").removeClass("hidden").css("opacity", 1); reconnectionAttempts++; if (reconnectionAttempts >= maxReconnectionAttempts) { $(".pageTribe .preloader .icon").html(``); $(".pageTribe .preloader .text").text( `Could not connect to Tribe server: ${f.message}` ); } else { $(".pageTribe .preloader .text").text("Connection failed. Retrying"); Notifications.add("Tribe connection error: " + f.message, -1); } }); socket.on("connect_error", (f) => { state = -1; reconnectionAttempts++; console.error(f); changeActiveSubpage("preloader"); // $(".pageTribe .preloader div").removeClass("hidden"); // $(".pageTribe .preloader").removeClass("hidden").css("opacity", 1); if (reconnectionAttempts >= maxReconnectionAttempts) { $(".pageTribe .preloader .icon").html(``); $(".pageTribe .preloader .text").text( `Could not connect to Tribe server: ${f.message}` ); } else { $(".pageTribe .preloader .text").text("Connection error. Retrying"); Notifications.add("Tribe connection error: " + f.message, -1); } }); socket.on("mp_room_joined", (data) => { if (room === undefined) { room = data.room; } else { room.users[data.sid] = { sid: data.sid, name: data.name }; } if (data.room.private) { playSound("join"); if (data.sid === socket.id) { let user = room.users[socket.id]; if (user.isLeader) { room.isLeader = true; } else { room.isLeader = false; } room.isReady = false; room.isTyping = false; } resetReadyButtons(); refreshUserList(); if (state === 10) { //user is already in the room and somebody joined } else if (state === 1) { //user is in prelobby and joined a room applyRoomConfig(room.config); refreshConfig(); let link = location.origin + "/tribe" + room.id.substring(4); $(".pageTribe .lobby .inviteLink .code .text").text(room.id.substring(5)); $(".pageTribe .lobby .inviteLink .link").text(link); $(".pageTest .tribeResultChat .inviteLink .code .text").text( room.id.substring(5) ); $(".pageTest .tribeResultChat .inviteLink .link").text(link); changeActiveSubpage("lobby"); state = data.room.state; if (state >= 20 && state < 29) { refreshTestUserList(); } // swapElements($(".pageTribe .prelobby"), $(".pageTribe .lobby"), 250, () => { // state = 10; // // $(".pageTribe .prelobby").addClass('hidden'); // }); resetReadyButtons(); resetLeaderButtons(); } } else { state = 7; MatchmakingStatus.setText( `Waiting for more players to join (${ Object.keys(room.users).length }/5)...` ); } }); socket.on("mp_room_leave", () => { let privateRoom = room.private; state = 1; room = undefined; name.replace(/\(\d\)$/g, ""); resetLobby(); changeActiveSubpage("prelobby"); resetLobby(); resetRace(); $(".pageTribe .prelobby .matchmaking .leaveMatchmakingButton").addClass( "hidden" ); $(".pageTribe .prelobby .matchmaking .buttons .button").removeClass( "disabled" ); MatchmakingStatus.hide(); // swapElements($(".pageTribe .lobby"), $(".pageTribe .prelobby"), 250); }); socket.on("mp_room_user_left", (data) => { if (room.private) { playSound("leave"); if (room.whoIsTyping === undefined) { room.whoIsTyping = {}; } room.whoIsTyping[data.sid] = { name: data.name, truefalse: false }; updateWhoIsTyping(); delete room.users[data.sid]; if (data.newLeader !== "" && data.newLeader === socket.id) { room.isLeader = true; room.users[socket.id].isLeader = true; } refreshUserList(); resetLeaderButtons(); resetReadyButtons(); } else { delete room.users[data.sid]; if (state <= 8) { MatchmakingStatus.setText( `Waiting for more players to join (${ Object.keys(room.users).length }/5)...` ); } else if (state >= 20) { $(`.tribePlayers .player[sid=${data.sid}]`).addClass("failed"); $(`.tribeResult .player[sid=${data.sid}]`).addClass("failed"); } } }); socket.on("mp_room_new_leader", (data) => { room.isLeader = false; Object.keys(room.users).forEach((u) => { room.users[u].isLeader = false; }); room.users[data.newLeader].isLeader = true; if (data.newLeader !== "" && data.newLeader === socket.id) { room.isLeader = true; room.users[socket.id].isLeader = true; } refreshUserList(); resetLeaderButtons(); resetReadyButtons(); }); socket.on("mp_room_config_update", (data) => { room.config = data.newConfig; refreshConfig(); if (!room.isLeader) { Notifications.add("Config changed", 0, 2); applyRoomConfig(room.config); } Object.keys(room.users).forEach((sid) => { room.users[sid].isReady = false; }); room.isReady = false; resetReadyButtons(); refreshUserList(); }); socket.on("mp_chat_message", async (data) => { data.message = data.message.trim(); let nameregex; if (data.isLeader) { nameregex = new RegExp( ` @${name.replace(/[.()]/g, "\\$&")} |^@${name.replace( /[.()]/g, "\\$&" )}$|ready|@everyone`, "i" ); } else { nameregex = new RegExp( ` @${name.replace(/[.()]/g, "\\$&")} |^@${name.replace( /[.()]/g, "\\$&" )}$`, "i" ); } if (!data.isSystem && data.from.name != name) { if (nameregex.test(data.message)) { playSound("chat_mention"); data.message = data.message.replace( nameregex, "$&" ); } else { playSound("chat2"); } } let cls = "message"; let author = ""; if (data.isSystem) { cls = "systemMessage"; } else { let me = ""; if (data.from.name == name) me = " me"; author = `
${data.from.name}:
`; } data.message = await insertImageEmoji(data.message); $(".pageTribe .lobby .chat .messages").append(`
${author}
${data.message}
`); $(".pageTest #result .tribeResultChat .chat .messages").append(`
${author}
${data.message}
`); scrollChat(); }); socket.on("mp_update_mm_status", (data) => { if (data.visible) { MatchmakingStatus.show(); } else { MatchmakingStatus.hide(); } if (data.text !== undefined) MatchmakingStatus.setText(data.text); if (data.raceStarting === true) { playSound("join"); } }); socket.on("mp_room_user_istypingupdate", (data) => { if (room.whoIsTyping === undefined) { room.whoIsTyping = {}; } room.whoIsTyping[data.sid] = { name: data.name, truefalse: data.typing }; updateWhoIsTyping(); }); $(".pageTest #result .tribeResultChat .chat .input input").keypress(() => { setTimeout(() => { $(".pageTribe .lobby .chat .input input").val( $(".pageTest #result .tribeResultChat .chat .input input").val() ); }, 1); }); $(".pageTribe .lobby .chat .input input").keypress((e) => { setTimeout(() => { $(".pageTest #result .tribeResultChat .chat .input input").val( $(".pageTribe .lobby .chat .input input").val() ); }, 1); }); $(".pageTribe .lobby .chat .input input").keydown((e) => { if (e.key == "ArrowUp" || e.key == "ArrowDown" || e.key == "Tab") { e.preventDefault(); } }); $(".pageTribe .lobby .chat .input input").keyup((e) => { if (e.key == "ArrowUp" || e.key == "ArrowDown" || e.key == "Tab") { e.preventDefault(); } if (e.key == "ArrowUp") { lobbySuggestions.moveActiveSuggestion(false); } else if (e.key == "ArrowDown") { lobbySuggestions.moveActiveSuggestion(true); } else if (e.key == "Tab") { let active = lobbySuggestions.getActive(); if (active) { let split = $(".pageTribe .lobby .chat .input input").val().split(" "); if (active.type === "image") { split[split.length - 1] = `:${active.from}:`; } else if (active.type === "emoji") { split[split.length - 1] = `${active.to}`; } else { //its a name split[split.length - 1] = `@${active}`; } $(".pageTribe .lobby .chat .input input").val(split.join(" ") + " "); lobbySuggestions.hide(); } } else { let split = $(".pageTribe .lobby .chat .input input").val().split(" "); split = split[split.length - 1]; if (split.slice(0, 1) === ":") { split = split.replace(/:/g, ""); if (split.length >= 2) { lobbySuggestions.updateSuggestions("emoji", split); lobbySuggestions.show(); } else { lobbySuggestions.hide(); } } else if (split.slice(0, 1) === "@") { split = split.replace(/@/g, ""); if (split.length >= 0) { lobbySuggestions.updateSuggestions("name", split); lobbySuggestions.show(); } else { lobbySuggestions.hide(); } } else { lobbySuggestions.hide(); } } }); $(".pageTest #result .tribeResultChat .chat .input input").keydown((e) => { if (e.key == "ArrowUp" || e.key == "ArrowDown" || e.key == "Tab") { e.preventDefault(); } }); $(".pageTest #result .tribeResultChat .chat .input input").keyup((e) => { if (e.key == "ArrowUp" || e.key == "ArrowDown" || e.key == "Tab") { e.preventDefault(); } if (e.key == "ArrowUp") { resultSuggestions.moveActiveSuggestion(false); } else if (e.key == "ArrowDown") { resultSuggestions.moveActiveSuggestion(true); } else if (e.key == "Tab") { let emoji = resultSuggestions.getActive(); if (emoji) { let split = $(".pageTest #result .tribeResultChat .chat .input input") .val() .split(" "); if (emoji.type === "image") { split[split.length - 1] = `:${emoji.from}:`; } else if (emoji.type === "emoji") { split[split.length - 1] = `${emoji.to}`; } $(".pageTest #result .tribeResultChat .chat .input input").val( split.join(" ") + " " ); resultSuggestions.hide(); } } else { let split = $(".pageTest #result .tribeResultChat .chat .input input") .val() .split(" "); split = split[split.length - 1]; if (split.slice(0, 1) === ":") { split = split.replace(/:/g, ""); if (split.length >= 2) { resultSuggestions.updateSuggestions(split); resultSuggestions.show(); } else { resultSuggestions.hide(); } } else { resultSuggestions.hide(); } } }); socket.on("mp_system_message", (data) => { Notifications.add(`${data.message}`, data.level, undefined, "Tribe"); }); socket.on("mp_room_test_start", (data) => { if (room.private && !room.isTyping) return; // UI.changePage(''); // mp_testCountdown(); // startTest(); setTimeout(() => { if (!TestLogic.active) { TestLogic.startTest(); } }, 500); // Notifications.add("test starting",0); updateCountdown(""); fadeoutCountdown(); playSound("cd_go"); }); socket.on("mp_room_test_countdown", (data) => { if (room.private && !room.isTyping) return; TestUI.focusWords(); updateCountdown(data.val); if (data.val <= 3) playSound("cd"); // if (data.val == 1) fadeoutCountdown() // Notifications.add(`countdown ${data.val}`,0); }); socket.on("mp_room_finishTimer_countdown", (data) => { showResultCountdown(); updateResultCountdown(`Time left for everyone to finish: ${data.val}s`); showCountdown(true); updateCountdown(data.val); if (data.val <= 3) playSound("cd"); }); socket.on("mp_room_finishTimer_over", (data) => { hideResultCountdown(); if (TestLogic.active) TestLogic.finish(undefined, true); }); socket.on("mp_room_readyResultTimer_countdown", (data) => { showResultCountdown(); updateResultCountdown(`Waiting for everyone to get ready: ${data.val}s`); }); socket.on("mp_room_readyResultTimer_over", (data) => { hideResultCountdown(); if (room.isLeader) { $(".pageTest #nextTestButton").removeClass("hidden"); $(".pageTest #backToLobbyButton").removeClass("hidden"); } }); socket.on("mp_room_test_init", (data) => { if (room.private && room.isReady !== true && room.isLeader !== true) { UI.changePage("tribe"); changeActiveSubpage("lobby"); Notifications.add( `Not joining race. isReady: ${room.isReady}, isLeader: ${room.isLeader}`, 0, 0, "DEBUG" ); return; } let delay = 0; if ($(".page.pageTest").hasClass("active")) { //test already visible, delay some stuff delay = 125; } playSound("start"); room.userSpeeds = {}; resetTribeDiff(); room.userGraphs = {}; room.userFinished = false; destroyAllGraphs(); seedrandom(data.seed, { global: true }); console.log(`seed: ${data.seed}`); console.log(`random: ${Math.random()}`); UI.changePage("", true); $(".pageTribe .lobby .chat .input input").val(""); $(".pageTest #result .tribeResultChat .chat .input input").val(""); lobbySuggestions.hide(); resultSuggestions.hide(); MatchmakingStatus.reset(); sendIsTypingUpdate(false); hideResultCountdown(); $(".pageTest #restartTestButton").addClass("hidden"); setTimeout(() => { refreshTestUserList(); showCountdown(); }, delay); }); socket.on("mp_room_state_update", (data) => { state = data.newState; Notifications.add(`state changed to ${data.newState}`, 0); if (data.newState === 8) { $(".pageTribe .prelobby .matchmaking .leaveMatchmakingButton").addClass( "hidden" ); } }); socket.on("mp_room_user_test_progress_update", (data) => { if (room.isTyping) { if (data.sid !== socket.id) room.userSpeeds[data.sid] = data.stats.wpm; } $(`.tribePlayers .player[sid=${data.sid}] .wpm`).text(data.stats.wpm); $(`.tribePlayers .player[sid=${data.sid}] .acc`).text( Math.floor(data.stats.acc) + "%" ); $(`.tribeResult table .player[sid=${data.sid}] .wpm .text`).text( data.stats.wpm ); $(`.tribeResult table .player[sid=${data.sid}] .acc .text`).text( Math.floor(data.stats.acc) + "%" ); $(`.tribePlayers .player[sid=${data.sid}] .bar`) .stop(true, false) .animate( { width: Config.mode === "time" ? data.stats.wpmProgress + "%" : data.stats.progress + "%", }, 1000, "linear" ); $(`.tribeResult table .player[sid=${data.sid}] .bar`) .stop(true, false) .animate( { width: Config.mode === "time" ? data.stats.wpmProgress + "%" : data.stats.progress + "%", }, 1000, "linear" ); }); let graphs = []; socket.on("mp_room_user_finished", (data) => { room.users[data.sid].isFinished = true; $(`.tribeResult`).removeClass("hidden"); $(`.tribeResult table .player[sid=${data.sid}] .wpm .text`).text( data.result.wpm ); $(`.tribeResult table .player[sid=${data.sid}] .acc .text`).text( data.result.acc + "%" ); // $(`.tribeResult table .player[sid=${data.sid}] .progress`).remove(); // $(`.tribeResult table .player[sid=${data.sid}] .raw`).remove(); // $(`.tribeResult table .player[sid=${data.sid}] .con`).remove(); // $(`.tribeResult table .player[sid=${data.sid}] .char`).remove(); // $(`.tribeResult table .player[sid=${data.sid}] .acc`).after(` // // // // `); $(`.tribeResult table .player[sid=${data.sid}] .raw .text`).text( data.result.raw ); let val = "-"; if (data.result.afk) { val = "afk"; } else if (data.result.invalid) { val = "invalid"; } else if (data.result.failed) { val = "failed"; } else if (data.result.outOfTime) { val = "out of time"; } $(`.tribeResult table .player[sid=${data.sid}] .other`).text(val); $(`.tribeResult table .player[sid=${data.sid}] .char`).text(data.result.char); $(`.tribeResult table .player[sid=${data.sid}] .con .text`).text( data.result.con + "%" ); if (data.result.failed || data.result.invalid || data.result.afk) { $(`.tribePlayers .player[sid=${data.sid}]`).addClass("failed"); $(`.tribeResult .player[sid=${data.sid}]`).addClass("failed"); } if (room.userGraphs === undefined) room.userGraphs = {}; room.userGraphs[data.sid] = { data: data.result, }; UI.swapElements( $(`.tribeResult table .player[sid=${data.sid}] .progress`), $(`.tribeResult table .player[sid=${data.sid}] .graph`), 125 ); setTimeout(() => { if (data.sid === socket.id) { room.userFinished = true; Object.keys(room.userGraphs).forEachWithCallback((sid, i, next) => { setTimeout(() => { let userGraph = room.userGraphs[sid]; userGraph.graph = drawMinigraph(sid, userGraph.data); next(); }, 100); }); } else if (room.userFinished) { room.userGraphs[data.sid].graph = drawMinigraph(data.sid, data.result); } }, 250); // $(`.tribeResult table .player[sid=${data.sid}] .progress`), // swapElements( // $(`.tribeResult table .player[sid=${data.sid}] .progress`), // $(`.tribeResult table .player[sid=${data.sid}] .graph`), // 125, // () => { // drawMinigraph(data.sid, data.result); // // $(`.tribeResult table .player[sid=${data.sid}] .graph`).css('opacity',0).animate({opacity:1},125); // } // ); if (Config.mode !== "time" && !data.result.failed && !data.result.afk) { $(`.tribePlayers .player[sid=${data.sid}] .bar`).stop(true, false).animate( { width: "100%", }, 1000, "linear" ); $(`.tribeResult table .player[sid=${data.sid}] .bar`) .stop(true, false) .animate( { width: "100%", }, 1000, "linear" ); } }); socket.on("mp_room_winner", (data) => { let pos = 1; if (data.official) { hideResultCountdown(); // updateAllGraphs(graphs, data.maxRaw); // room.newTestCooldown = true; // $("#result #nextTestButton").html( // `` // ); // $("#result #nextTestButton").attr( // "aria-label", // "Please wait for all players to view their result" // ); // setTimeout(() => { // room.newTestCooldown = false; // $("#result #nextTestButton").html( // `` // ); // $("#result #nextTestButton").attr("aria-label", "Next test"); // }, 5000); } let userwon = false; data.sorted.forEach((sid) => { $(`.tribeResult table [sid=${sid.sid}] .pos .num`).text( `${pos}${Misc.getNumberSuffix(pos)}` ); if (data.official && pos == 1) { if (sid.sid === socket.id) { userwon = true; } $(`.tribeResult table [sid=${sid.sid}] .crown .fa-crown`).animate( { opacity: 1 }, 125 ); } else { $(`.tribeResult table [sid=${sid.sid}] .crown .fa-crown`).css( "opacity", 0 ); } pos++; }); if (userwon && data.official) { playSound("finish_win"); } else if (!userwon && data.official) { playSound("finish"); } }); socket.on("mp_room_miniCrowns", (data) => { let count = {}; Object.keys(data.crowns).forEach((c) => { let crown = data.crowns[c]; crown.sidList.forEach((sid) => { if (count[sid] === undefined) { count[sid] = 1; } else { count[sid]++; } $(`.tribeResult table [sid=${sid}] .${c} .miniCrown`).animate( { opacity: 0.5 }, 125 ); }); }); Object.keys(count).forEach((sid) => { if (count[sid] === 4) { $(`.tribeResult table [sid=${sid}] .crown`).append( `
` ); $(`.tribeResult table [sid=${sid}] .crown`).attr( "aria-label", "Dominated" ); $(`.tribeResult table [sid=${sid}] .crown`).attr( "data-balloon-pos", "up" ); if (sid === socket.id) { playSound("glow"); } } }); }); socket.on("mp_room_points", (data) => { data.users.forEach((user) => { $(`.tribeResult table [sid=${user.sid}] .pos .points`).text( `+${user.newPoints}${user.newPoints == 1 ? "pt" : "pts"}` ); room.users[user.sid].points = user.totalPoints; }); refreshUserList(); }); socket.on("mp_room_back_to_lobby", (data) => { Object.keys(room.users).forEach((sid) => { room.users[sid].isTyping = false; }); $(".tribePlayers").addClass("hidden"); UI.changePage("tribe"); refreshUserList(); }); socket.on("mp_room_user_info_update", (data) => { let checkReady = false; Object.keys(data.values).forEach((bool) => { room.users[data.sid][bool] = data.values[bool]; if (bool === "isReady" && data.values[bool]) checkReady = true; if (data.sid === socket.id) { room[bool] = data.values[bool]; if (bool === "isReady" && !data.values[bool] && !room.isLeader) { resetReadyButtons(); } } }); if (room.isLeader && checkReady) { let everyoneReady = true; Object.keys(room.users).forEach((sid) => { if ( !room.users[sid].isReady && !room.users[sid].isLeader && (!room.users[sid].isTyping || room.users[sid].isFinished) ) everyoneReady = false; }); if (everyoneReady) { playSound("chat_mention"); Notifications.add("Everyone is ready", 1, 3, "Tribe"); } } refreshUserList(); }); $(".pageTribe #createPrivateRoom").click((f) => { // activateFunbox("none"); // setLanguage("english"); // setMode("quote"); let mode2; if (Config.mode === "time") { mode2 = Config.time; } else if (Config.mode === "words") { mode2 = Config.words; } else if (Config.mode === "quote") { mode2 = Config.quoteLength === undefined ? "-1" : Config.quoteLength; } socket.emit("mp_room_create", { config: { mode: Config.mode, mode2: mode2, difficulty: Config.difficulty, blindMode: Config.blindMode, language: Config.language, funbox: Funbox.active, stopOnError: Config.stopOnError, confidenceMode: Config.confidenceMode, customText: { text: CustomText.text, isWordRandom: CustomText.isWordRandom, isTimeRandom: CustomText.isTimeRandom, word: CustomText.word, time: CustomText.time, }, punctuation: Config.punctuation, numbers: Config.numbers, minWpm: Config.minWpm === "custom" ? Config.minWpmCustomSpeed : null, minAcc: Config.minAcc === "custom" ? Config.minAccCustom : null, }, }); }); $(".pageTest #result .tribeResultChat .chat .input input").keyup((e) => { if (e.keyCode === 13) { let msg = $(".pageTest #result .tribeResultChat .chat .input input").val(); msg = Misc.encodeHTML(msg); if (msg === "") return; if (msg.length > 512) { Notifications.add("Message cannot be longer than 512 characters.", 0); return; } sendIsTypingUpdate(false); socket.emit("mp_chat_message", { isSystem: false, isLeader: room.isLeader, message: msg, from: { id: socket.id, name: name, }, }); resultSuggestions.hide(); $(".pageTest #result .tribeResultChat .chat .input input").val(""); $(".pageTribe .lobby .chat .input input").val(""); } }); $(".pageTribe .lobby .chat .input input").keyup((e) => { if (e.keyCode === 13) { let msg = $(".pageTribe .lobby .chat .input input").val(); msg = Misc.encodeHTML(msg); if (msg === "") return; if (msg.length > 512) { Notifications.add("Message cannot be longer than 512 characters.", 0); return; } sendIsTypingUpdate(false); socket.emit("mp_chat_message", { isSystem: false, isLeader: room.isLeader, message: msg, from: { id: socket.id, name: name, }, }); lobbySuggestions.hide(); $(".pageTribe .lobby .chat .input input").val(""); $(".pageTest #result .tribeResultChat .chat .input input").val(""); } }); $( ".pageTribe .lobby .chat .input input, .pageTest #result .tribeResultChat .chat .input input" ).on("input", (e) => { // e.currentTarget.value = emoji.emojify(e.currentTarget.value); if (e.currentTarget.value.length === 1) { //typing update sendIsTypingUpdate(true); } else if (e.currentTarget.value == "") { //not typing update sendIsTypingUpdate(false); } }); $(".pageTest #result .tribeResultChat .chat .messages").on("scroll", (e) => { let chatEl = $(".pageTest #result .tribeResultChat .chat .messages")[0]; shouldScrollChat = chatEl.scrollHeight - chatEl.scrollTop <= chatEl.clientHeight + 10; }); $(".pageTribe .lobby .chat .messages").on("scroll", (e) => { let chatEl = $(".pageTribe .lobby .chat .messages")[0]; shouldScrollChat = chatEl.scrollHeight - chatEl.scrollTop <= chatEl.clientHeight + 10; }); $( ".pageTribe .lobby .inviteLink .text, .pageTest .tribeResultChat .inviteLink .code .text" ).click(async (e) => { try { await navigator.clipboard.writeText( $(".pageTribe .lobby .inviteLink .text").text() ); Notifications.add("Code copied", 1); } catch (e) { Notifications.add("Could not copy to clipboard: " + e, -1); } }); $(".pageTribe .lobby .inviteLink .text").hover(async (e) => { $(".pageTribe .lobby .inviteLink .text").css( "color", "#" + $(".pageTribe .lobby .inviteLink .text").text() ); }); $(".pageTest .tribeResultChat .inviteLink .code .text").hover(async (e) => { $(".pageTest .tribeResultChat .inviteLink .code .text").css( "color", "#" + $(".pageTest .tribeResultChat .inviteLink .code .text").text() ); }); $(".pageTest .tribeResultChat .inviteLink .code .text").hover( function () { $(this).css("color", "#" + $(".pageTribe .lobby .inviteLink .text").text()); }, function () { $(this).css("color", ""); } ); $(".pageTribe .lobby .inviteLink .text").hover( function () { $(this).css("color", "#" + $(".pageTribe .lobby .inviteLink .text").text()); }, function () { $(this).css("color", ""); } ); $( ".pageTribe .lobby .inviteLink .link, .pageTest .tribeResultChat .inviteLink .link" ).click(async (e) => { try { await navigator.clipboard.writeText( $(".pageTribe .lobby .inviteLink .link").text() ); Notifications.add("Link copied", 1); } catch (e) { Notifications.add("Could not copy to clipboard: " + e, -1); } }); $(".pageTribe .prelobby #joinByCode .customInput").click((e) => { $(".pageTribe .prelobby #joinByCode input").focus(); }); $(".pageTribe .prelobby #joinByCode input").focus((e) => { $(".pageTribe .prelobby #joinByCode .customInput .byte").addClass("focused"); }); $(".pageTribe .prelobby #joinByCode input").focusout((e) => { $(".pageTribe .prelobby #joinByCode .customInput .byte").removeClass( "focused" ); }); $(".pageTribe .prelobby .matchmaking .button").click((e) => { if (state >= 6 && state <= 8) return; let queue = $(e.currentTarget).attr("queue"); MatchmakingStatus.setText("Searching for a room..."); MatchmakingStatus.show(); state = 6; lastQueue = queue; applyRoomConfig(TribeDefaultConfigs[queue]); $(".pageTribe .prelobby .matchmaking .buttons .button").addClass("disabled"); setTimeout(() => { $(".pageTribe .prelobby .matchmaking .leaveMatchmakingButton").removeClass( "hidden" ); socket.emit("mp_room_join", { queue: queue }); }, 1000); }); $(".pageTest #result #queueAgainButton").click((e) => { if (state >= 6 && state <= 8) return; MatchmakingStatus.setText("Searching for a room..."); MatchmakingStatus.show(); state = 6; applyRoomConfig(TribeDefaultConfigs[lastQueue]); TestLogic.restart(); $(".pageTribe .prelobby .matchmaking .buttons .button").addClass("disabled"); setTimeout(() => { socket.emit("mp_room_join", { queue: lastQueue }); $(".pageTribe .prelobby .matchmaking .leaveMatchmakingButton").removeClass( "hidden" ); }, 1000); }); $(".pageTribe .prelobby .matchmaking .leaveMatchmakingButton").click((e) => { if (state === 7) { socket.emit("mp_room_leave"); } }); $(".pageTribe .prelobby #joinByCode .button").click((e) => { let code = $(".pageTribe .prelobby #joinByCode input").val().toLowerCase(); if (code.length !== 6) { Notifications.add("Code required", 0); } else { joinRoomByCode(code); } }); $(".pageTribe .prelobby #joinByCode input").keyup((e) => { if (e.key === "Enter") { let code = $(".pageTribe .prelobby #joinByCode input").val().toLowerCase(); if (code.length !== 6) { Notifications.add("Code required", 0); } else { joinRoomByCode(code); } } else { setTimeout((t) => { // let t1 = "xx"; // let t2 = "xx"; // let t2 = "xx"; let v = $(".pageTribe .prelobby #joinByCode input").val(); // let text = `${v[0] == undefined ? 'x' : v[0]}`; // let iv = 0; // for (let i = 0; i < 8; i++){ // text[i] = v[iv] == undefined ? 'x' : v[iv]; // if(![2,5].includes(i)) iv++; // } let code = []; for (let i = 0; i < 6; i++) { let char = v[i] == undefined ? "-" : v[i]; code.push(char); } let text = code.join(""); $($(".pageTribe .prelobby #joinByCode .customInput .byte")[0]).text( text.substring(0, 2) ); $($(".pageTribe .prelobby #joinByCode .customInput .byte")[1]).text( text.substring(2, 4) ); $($(".pageTribe .prelobby #joinByCode .customInput .byte")[2]).text( text.substring(4, 6) ); }, 0); } }); $( ".pageTribe .lobby .lobbyButtons .leaveRoomButton, .pageTest #result .resultMpButtons .leaveRoomButton" ).click((e) => { socket.emit("mp_room_leave"); }); $(".pageTribe .lobby .lobbyButtons .startTestButton").click((e) => { startTest(); }); $( `.pageTribe .lobby .lobbyButtons .userReadyButton, .pageTest #result #readyButton, .pageTest #result .resultMpButtons .userReadyButton` ).click((e) => { userReady(); }); $( `.pageTribe .lobby .lobbyButtons .userReadyButton, .pageTest #result #readyButton, .pageTest #result .resultMpButtons .userReadyButton` ).on("keypress", (event) => { if (event.keyCode == 13) { userReady(); } }); $(document).on("keypress", (e) => { if ((state === 10 || state === 29) && e.key === "Enter" && e.shiftKey) { if (room.isLeader) { startTest(); } else { userReady(); } } }); $(".pageTest #result #backToLobbyButton").click((e) => { socket.emit("mp_room_back_to_lobby"); }); $(document).on( "click", ".pageTribe .lobby .currentSettings .groups .group", (e) => { if (room.isLeader) { // let commands = eval($(e.currentTarget).attr("commands")); let commands = CommandlineLists.getList( $(e.currentTarget).attr("commands") ); let func = $(e.currentTarget).attr("function"); if (commands != undefined) { if ($(e.currentTarget).attr("commands") === "commandsTags") { CommandlineLists.updateTagCommands(); } CommandlineLists.pushCurrent(commands); Commandline.show(); } else if (func != undefined) { eval(func); } } } ); $("#tribeUserSettingsPopupWrapper").click((e) => { if ($(e.target).attr("id") === "tribeUserSettingsPopupWrapper") { hideTribeUserSettingsPopup(); } }); $(document).on( "click", ".pageTribe .lobby .userlist .user .userSettings", (e) => { updateTribeUserSettingsPopup($(e.currentTarget).attr("sid")); showTribeUserSettingsPopup(); } ); $(document).on("click", "#tribeUserSettingsPopup .buttons .leader", (e) => { let sid = $("#tribeUserSettingsPopup").attr("sid"); socket.emit("mp_room_new_leader", { sid: sid }); hideTribeUserSettingsPopup(); }); $(document).on("click", "#tribeUserSettingsPopup .buttons .ban", (e) => { let sid = $("#tribeUserSettingsPopup").attr("sid"); socket.emit("mp_room_ban_user", { sid: sid }); hideTribeUserSettingsPopup(); }); $(document).on("keypress", (e) => { if ( state === 10 && !$(".pageTribe .lobby .chat .input input").is(":focus") && e.key === "/" ) { $(".pageTribe .lobby .chat .input input").focus(); e.preventDefault(); } if ( state >= 28 && !$(".pageTest #result .tribeResultChat .chat .input input").is(":focus") && e.key === "/" ) { $(".pageTest #result .tribeResultChat .chat .input input").focus(); e.preventDefault(); } }); let miniChartSettings = { type: "line", data: { labels: [1, 2, 3], datasets: [ { label: "wpm", data: [100, 100, 100], borderColor: "rgba(125, 125, 125, 1)", borderWidth: 1, yAxisID: "wpm", order: 2, radius: 1, }, { label: "raw", data: [110, 110, 110], borderColor: "rgba(125, 125, 125, 1)", borderWidth: 1, yAxisID: "raw", order: 3, radius: 1, }, { label: "errors", data: [1, 0, 1], borderColor: "rgba(255, 125, 125, 1)", pointBackgroundColor: "rgba(255, 125, 125, 1)", borderWidth: 1, order: 1, yAxisID: "error", maxBarThickness: 10, type: "scatter", pointStyle: "crossRot", radius: function (context) { var index = context.dataIndex; var value = context.dataset.data[index]; return value <= 0 ? 0 : 2; }, pointHoverRadius: function (context) { var index = context.dataIndex; var value = context.dataset.data[index]; return value <= 0 ? 0 : 3; }, }, ], }, options: { layout: { padding: { left: 5, right: 5, top: 5, bottom: 5, }, }, tooltips: { titleFontFamily: "Roboto Mono", bodyFontFamily: "Roboto Mono", mode: "index", intersect: false, callbacks: { afterLabel: function (ti, data) { try { //TODO bring back // $(".wordInputAfter").remove(); // let wordsToHighlight = // keypressPerSecond[parseInt(ti.xLabel) - 1].words; // let unique = [...new Set(wordsToHighlight)]; // unique.forEach((wordIndex) => { // let wordEl = $($("#resultWordsHistory .words .word")[wordIndex]); // let input = wordEl.attr("input"); // if (input != undefined) // wordEl.append(`
${input}
`); // }); } catch (e) {} }, }, }, legend: { display: false, labels: { defaultFontFamily: "Roboto Mono", }, }, responsive: true, maintainAspectRatio: false, scales: { xAxes: [ { ticks: { fontFamily: "Roboto Mono", autoSkip: true, autoSkipPadding: 40, }, display: false, scaleLabel: { display: false, labelString: "Seconds", fontFamily: "Roboto Mono", }, }, ], yAxes: [ { id: "wpm", display: false, scaleLabel: { display: true, labelString: "Words per Minute", fontFamily: "Roboto Mono", }, ticks: { fontFamily: "Roboto Mono", beginAtZero: true, min: 0, autoSkip: true, autoSkipPadding: 40, }, gridLines: { display: true, }, }, { id: "raw", display: false, scaleLabel: { display: true, labelString: "Raw Words per Minute", fontFamily: "Roboto Mono", }, ticks: { fontFamily: "Roboto Mono", beginAtZero: true, min: 0, autoSkip: true, autoSkipPadding: 40, }, gridLines: { display: false, }, }, { id: "error", display: false, position: "right", scaleLabel: { display: true, labelString: "Errors", fontFamily: "Roboto Mono", }, ticks: { precision: 0, fontFamily: "Roboto Mono", beginAtZero: true, autoSkip: true, autoSkipPadding: 40, }, gridLines: { display: false, }, }, ], }, annotation: { annotations: [], }, }, };