conversation = [ { c: 1, message: "hows space"}, { c: 0, message: "trying to work out if the coffees shit but"}, { c: 0, message: "taste not happenin"}, { c: 1, message: "maybe youre being spared"}, { c: 0, message: "youre right"}, { c: 0, message: "ship swill is a delicacy to no one"}, { c: 0, message: "at least the caffeines doing its job"}, { c: 1, message: "good to hear!"}, { c: 1, message: "induction today wish me luckk"}, { c: 0, message: "break a leg!"}, { c: 1, message: ":)"} ]; let messageIdx = 1; let title = "hester"; let pings = 0; function updateTextBox(message) { document.getElementById("textbox").value = message; } // show messages up to index function showMessages(idx) { let messageList = document.getElementById("messages"); // clear current messages messageList.innerHTML = ""; // inject messages into ul for (let i = 0; i < idx; i++) { messageList.innerHTML += `
  • ${conversation[i].message}

  • `; } } function isMessageOurs(message) { if (!message) return false; return message.c == 0; } function getOurNextMessage(idx) { for (let i = idx; i < conversation.length; i++) { message = conversation[i]; if (isMessageOurs(message)) return message; } return null; } function getLightLag() { lag = 3.0 + Math.sin(Date.now() / 10000); return Math.round(lag * 100) / 100; } function updatePings() { let newTitle = pings > 0 ? `(${pings}) ${title}` : title; document.title = newTitle; } function clearPings() { pings = 0; updatePings(); } function getResponses(idx) { // get the messages that aren't ours until we find one that is let responses = []; for (let i = idx; i < conversation.length; i++) { message = conversation[i]; if (isMessageOurs(message)) break; responses.push(message); } return responses; } function updateChat(messageIdx) { showMessages(messageIdx); updatePreviewText(messageIdx); updatePings(); } function waitForIncomingMessages() { // we don't want messages to arrive all at once if there are multiple messages, // so we need to add a small delay to consecutive messages and wait for them one by one let smallDelay = 2; let responses = getResponses(messageIdx); let lightLag = getLightLag(); for (let i = 0; i < responses.length; i++) { let delaySeconds = lightLag + smallDelay * i; setTimeout(() => { messageIdx++; pings++; updateChat(messageIdx); }, delaySeconds * 1000); } } function updatePreviewText(messageIdx) { // display our next message or an empty box let nextMessage = conversation[messageIdx]; let previewText = isMessageOurs(nextMessage) ? conversation[messageIdx].message : ""; updateTextBox(previewText); } function send() { // we have interacted with the page so remove all pings clearPings(); // we are still waiting to receive messages so pressing the button oughtn't do anything if (!isMessageOurs(conversation[messageIdx])) return; // advance conversation state messageIdx++; // if the next message is not ours, we need to wait for it: set off a thread that // will update the message index and the displayed messages in a few seconds // we are still waiting to receive messages so pressing the button oughtn't do anything if (!isMessageOurs(conversation[messageIdx])) { waitForIncomingMessages(); } updateChat(messageIdx); } function updateLightLag(lag) { document.getElementById("delay").innerHTML = lag.toFixed(2) + " seconds"; } function startLightLagUpdateLoop() { setInterval(() => { updateLightLag(getLightLag()); }, 1000); } function init() { showMessages(messageIdx); // load the first message into the text box updateTextBox(conversation[messageIdx].message); pings = 1; document.title = title; updateLightLag(0); startLightLagUpdateLoop(); } init();