diff --git a/main.js b/main.js
index 0ac89ae..1d10988 100644
--- a/main.js
+++ b/main.js
@@ -1,39 +1,141 @@
+// how to we communicate...
+// * in flight
+// * arrived! (probably) <- this is the tricky one. we know enough time has passed for the message
+// * received to have been received, but we are only halfway to the earliest possible
+// * read acknowledgement.
+//
+// we know the length of the roundtrip: it is 2x the light lag. progress bars show a passage of time,
+// it could scroll:
+// * along the bottom of the message
+// * across the message
+// * as it is being sent, a transluscent red bar grows from right to left (towards their messages)
+// * while we are waiting for acknowledgement, a similar blue bar brows from left to right
+// * next to the message
+
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: ":)"}
+ { c: 1, text: "hows space"},
+ { c: 0, text: "trying to work out if the coffees shit but"},
+ { c: 0, text: "taste not happenin"},
+ { c: 1, text: "maybe youre being spared"},
+ { c: 0, text: "youre right"},
+ { c: 0, text: "ship swill is a delicacy to no one"},
+ { c: 0, text: "at least the caffeines doing its job"},
+ { c: 1, text: "good to hear!"},
+ { c: 1, text: "induction today wish me luckk"},
+ { c: 0, text: "break a leg!"},
+ { c: 1, text: ":)"}
];
let messageIdx = 1;
let title = "hester";
let pings = 0;
+function getMessageList() {
+ return document.getElementById("messages");
+}
+
+function getMessageElement(messageIdx) {
+ let list = getMessageList();
+ let messageElements = list.getElementsByTagName("li");
+ return messageElements[messageIdx];
+}
+
+class SentMessage {
+ constructor(oneWayLag, idx) {
+ this.oneWayLag = oneWayLag;
+ this.idx = idx;
+ //this.content = conversation[idx].text;
+ this.createdTime = Date.now();
+
+ this.updateBarIntervalId = setInterval(() => {
+ let elapsed = Math.abs(Date.now() - this.createdTime) / 1000;
+ let progress = elapsed / this.oneWayLag;
+
+ // divide in half so we measure the round trip
+ progress /= 2;
+
+ this.setProgress(progress);
+ }, 10);
+ }
+
+ setProgress(amount) {
+ let thisMessage = getMessageElement(this.idx);
+ let progressBar = thisMessage.getElementsByClassName("progress")[0];
+
+ if (amount < 0.5) {
+ this.updateStatus("in flight");
+ progressBar.style.backgroundColor = "red";
+ amount *= 2;
+ }
+ else if (amount < 1) {
+ this.updateStatus("completing round trip");
+ progressBar.style.backgroundColor = "blue";
+ amount -= 0.5;
+ amount *= 2;
+ }
+ else {
+ this.updateStatus("delivered");
+ clearInterval(this.updateBarIntervalId);
+ amount = 0;
+ }
+ amount = Math.min(amount, 1);
+ let percentage = `${amount * 100}%`;
+ progressBar.style.width = percentage;
+
+ }
+
+ updateStatus(newStatus) {
+ let thisMessage = getMessageElement(this.idx);
+ let statusElement = thisMessage.getElementsByClassName("message-status")[0];
+ statusElement.innerHTML = newStatus;
+ }
+}
+
function updateTextBox(message) {
- document.getElementById("textbox").value = message;
+ document.getElementById("textbox-input").value = message;
}
// show messages up to index
function showMessages(idx) {
- let messageList = document.getElementById("messages");
+ let messageList = getMessageList();
+
+ // TODO: rebuilding the DOM here clears this status of sent messages. instead of
+ // rebuilding it completely, append a new message onto the end of the inner html.
+ // TODO: is this also the juncture to clear the status of previous messages?
// clear current messages
messageList.innerHTML = "";
// inject messages into ul
for (let i = 0; i < idx; i++) {
- messageList.innerHTML += `
${conversation[i].message}
`;
+ let message = conversation[i];
+ messageList.innerHTML += getMessageHtml(message.text, isMessageOurs(message));
}
}
+function getMessageHtml(text, isOurs) {
+ let owner = isOurs ? "ours" : "theirs";
+
+ // we don't want loading bars on their messages, since we have no idea if one has been sent
+ // until it arrives
+ let progressBar = isOurs
+ ? `
`
+ : "";
+
+ let statusText = isOurs
+ ? `
status
`
+ : "";
+
+ let message = `
+
+ ${progressBar}
+ ${text}
+
${statusText}
`;
+
+ return message;
+}
+
function isMessageOurs(message) {
if (!message)
return false;
@@ -53,7 +155,7 @@ function getOurNextMessage(idx) {
function getLightLag() {
lag = 3.0 + Math.sin(Date.now() / 10000);
- return Math.round(lag * 100) / 100;
+ return Math.round(lag * 10000) / 10000;
}
function updatePings() {
@@ -104,6 +206,7 @@ function waitForIncomingMessages() {
messageIdx++;
pings++;
+ // update the chat with their message
updateChat(messageIdx);
}, delaySeconds * 1000);
}
@@ -113,46 +216,66 @@ function updatePreviewText(messageIdx) {
// display our next message or an empty box
let nextMessage = conversation[messageIdx];
let previewText = isMessageOurs(nextMessage)
- ? conversation[messageIdx].message
+ ? conversation[messageIdx].text
: "";
updateTextBox(previewText);
}
-function send() {
- // we have interacted with the page so remove all pings
- clearPings();
+function sendOurMessage() {
+ // the message we are sending is the one currently in the text box, so we should construct it
+ // before advancing the conversation
+ let oneWayLag = getLightLag();
+ let currentMessage = conversation[messageIdx];
+ let sentMessage = new SentMessage(oneWayLag, messageIdx);
+ console.log(sentMessage);
- // we are still waiting to receive messages so pressing the button oughtn't do anything
- if (!isMessageOurs(conversation[messageIdx]))
- return;
+ // message.send()
+ // when we send the message, we want to start an interval that updates the progress animation
+ // message.setProgress() should be a private method that updates the appropriate element
- // advance conversation state
+ // advance conversation with our next message
messageIdx++;
-
+ nextMessage = conversation[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])) {
+ if (!isMessageOurs(nextMessage)) {
waitForIncomingMessages();
}
updateChat(messageIdx);
}
-function updateLightLag(lag) {
- document.getElementById("delay").innerHTML = lag.toFixed(2) + " seconds";
+function pressSendButton() {
+ // we have interacted with the page so remove all pings
+ clearPings();
+
+ // peek conversation state
+ let nextMessage = conversation[messageIdx];
+
+ // we are still waiting to receive messages so pressing the button oughtn't do anything
+ if (!isMessageOurs(nextMessage))
+ return;
+
+ sendOurMessage();
+}
+
+function updateLightLag() {
+ let text = getLightLag().toFixed(5) + " seconds";
+ document.getElementById("delay-text").innerHTML = text;
}
function startLightLagUpdateLoop() {
setInterval(() => {
- updateLightLag(getLightLag());
+ updateLightLag();
}, 1000);
}
function init() {
showMessages(messageIdx);
// load the first message into the text box
- updateTextBox(conversation[messageIdx].message);
+ updateTextBox(conversation[messageIdx].text);
pings = 1;
document.title = title;
diff --git a/styles.css b/styles.css
new file mode 100644
index 0000000..e491f89
--- /dev/null
+++ b/styles.css
@@ -0,0 +1,126 @@
+html {
+ font-family: sans-serif;
+}
+
+h1 {
+ display: inline;
+}
+
+.delay {
+ display: inline;
+}
+
+.rounded-rectangle {
+ border-width: 2px;
+ border: black;
+ border-style: solid;
+ border-radius: 1em;
+
+ padding: 7px;
+}
+
+.message-content {
+ z-index: 1;
+ position: absolute;
+}
+
+.message-content.theirs {
+ background-color: yellow;
+ left: 0;
+}
+
+.message-content.ours {
+ background-color: pink;
+ right: 0;
+ margin-bottom: 0.5em;
+}
+
+ul {
+ margin-bottom: 1.5em;
+ padding: 0;
+ list-style: none;
+}
+
+li {
+ height: 2.5em;
+ width: 100%;
+
+ margin-top: 1.5em;
+ position: relative;
+}
+
+#textbox {
+ margin-top: 2em;
+ padding: 0;
+}
+
+#textbox input {
+ margin: 0.5em;
+ margin-left: 0;
+
+ width: 85%;
+ font-size: 1em;
+}
+
+button {
+ margin: 0.5em;
+ padding: 0;
+ width: 10%;
+ position: absolute;
+ right: 0;
+ font-size: 1em;
+}
+
+/*
+.loader-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+}
+*/
+
+
+.progress-bar {
+ width: 100%;
+ height: 100%;
+ opacity: 80%;
+ max-width: 400px;
+ background-color: #e0e0e0;
+ border-radius: 10px;
+ overflow: hidden;
+ position: absolute;
+
+ z-index: -1;
+ top: 0;
+ left: 0;
+}
+
+.progress {
+ opacity: 80%;
+ width: 0;
+ height: 100%;
+ background-color: #ff5c35;
+ /*
+ animation: fill 4s infinite;
+ */
+}
+
+.message-status {
+ margin-top: 1em;
+ position: absolute;
+ top: 2.3em;
+ right: 1em;
+ font-size: .8em;
+}
+
+/*
+@keyframes fill {
+ 0% {
+ width: 0;
+ }
+ 100% {
+ width: 100%;
+ }
+}
+*/