diff --git a/main.js b/main.js
index 1d10988..a6fbab2 100644
--- a/main.js
+++ b/main.js
@@ -26,8 +26,9 @@ conversation = [
{ c: 1, text: ":)"}
];
+sentMessages = []
let messageIdx = 1;
-let title = "hester";
+let title = "Hester Gomez";
let pings = 0;
function getMessageList() {
@@ -41,17 +42,17 @@ function getMessageElement(messageIdx) {
}
class SentMessage {
- constructor(oneWayLag, idx) {
+ constructor(oneWayLag, idx, onDelivered) {
this.oneWayLag = oneWayLag;
this.idx = idx;
- //this.content = conversation[idx].text;
this.createdTime = Date.now();
+ this.onDelivered = onDelivered;
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
+ // divide in half to measure the round trip
progress /= 2;
this.setProgress(progress);
@@ -77,11 +78,11 @@ class SentMessage {
this.updateStatus("delivered");
clearInterval(this.updateBarIntervalId);
amount = 0;
+ this.onDelivered();
}
amount = Math.min(amount, 1);
let percentage = `${amount * 100}%`;
progressBar.style.width = percentage;
-
}
updateStatus(newStatus) {
@@ -95,23 +96,17 @@ function updateTextBox(message) {
document.getElementById("textbox-input").value = message;
}
-// show messages up to index
-function showMessages(idx) {
+function setTypingIndicator(isTyping) {
+ document.getElementById("typing-indicator").innerHTML = isTyping
+ ? "Hester is typing..."
+ : "";
+}
- 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++) {
- let message = conversation[i];
- messageList.innerHTML += getMessageHtml(message.text, isMessageOurs(message));
- }
+// add the message at the index to the displayed messages
+function addMessage(idx) {
+ let message = conversation[idx];
+ let messageHtml = getMessageHtml(message.text, isMessageOurs(message));
+ getMessageList().innerHTML += messageHtml;
}
function getMessageHtml(text, isOurs) {
@@ -187,29 +182,45 @@ function getResponses(idx) {
}
function updateChat(messageIdx) {
- showMessages(messageIdx);
+ addMessage(messageIdx-1);
updatePreviewText(messageIdx);
updatePings();
}
+function getRandomDelay(min, max) {
+ const range = max - min;
+ return min + Math.random() * range;
+}
+
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 smallDelay = getRandomDelay(2, 10);
let responses = getResponses(messageIdx);
let lightLag = getLightLag();
- for (let i = 0; i < responses.length; i++) {
- let delaySeconds = lightLag + smallDelay * i;
+ setTimeout(() => {
+ setTypingIndicator(true);
- setTimeout(() => {
- messageIdx++;
- pings++;
+ for (let i = 0; i < responses.length; i++) {
+ let delaySeconds = lightLag + smallDelay * i;
- // update the chat with their message
- updateChat(messageIdx);
- }, delaySeconds * 1000);
- }
+ const stopTyping = i == responses.length - 1;
+
+ setTimeout(() => {
+ messageIdx++;
+ pings++;
+
+ // update the chat with their message
+ updateChat(messageIdx);
+
+ if (stopTyping) {
+ setTypingIndicator(false);
+ }
+
+ }, delaySeconds * 1000);
+ }
+ },getRandomDelay(1, 3));
}
function updatePreviewText(messageIdx) {
@@ -226,24 +237,37 @@ function sendOurMessage() {
// before advancing the conversation
let oneWayLag = getLightLag();
let currentMessage = conversation[messageIdx];
- let sentMessage = new SentMessage(oneWayLag, messageIdx);
- console.log(sentMessage);
+ let nextMessage = conversation[messageIdx + 1];
- // 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
+ let sentMessage = new SentMessage(oneWayLag, messageIdx, () => {
+
+ // if the next message is ours we don't need to wait for anything
+ if (isMessageOurs(nextMessage))
+ return;
+
+ // wait for them to read the message
+ setTimeout(() => {
+ // set the message status to read
+ sentMessage.updateStatus("read");
+
+ // hide the status of previous messages we first need to have references to all of them
+ // when creating messages we need to add these too an array
+ for (let i = 0; i < sentMessages.length; i++) {
+ let message = sentMessages[i];
+ if (message != sentMessage) {
+ message.updateStatus("");
+ }
+ }
+
+ waitForIncomingMessages();
+ }, getRandomDelay(5, 30) * 1000);
+ });
+ sentMessages.push(sentMessage);
// 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(nextMessage)) {
- waitForIncomingMessages();
- }
+ // update displayed messages
updateChat(messageIdx);
}
@@ -273,7 +297,12 @@ function startLightLagUpdateLoop() {
}
function init() {
- showMessages(messageIdx);
+ setTimeout(() => {
+ addMessage(0);
+ updatePings();
+ setTypingIndicator(false);
+ }, 400);
+
// load the first message into the text box
updateTextBox(conversation[messageIdx].text);
pings = 1;
diff --git a/styles.css b/styles.css
index e491f89..09f076f 100644
--- a/styles.css
+++ b/styles.css
@@ -2,7 +2,17 @@ html {
font-family: sans-serif;
}
+body {
+ margin-left: 0;
+ margin-right: 0;
+}
+
+#page {
+ max-width: 600px;
+}
+
h1 {
+ margin-left: 0.5em;
display: inline;
}
@@ -36,7 +46,7 @@ h1 {
}
ul {
- margin-bottom: 1.5em;
+ margin: 1em;
padding: 0;
list-style: none;
}
@@ -45,18 +55,31 @@ li {
height: 2.5em;
width: 100%;
- margin-top: 1.5em;
+ margin-bottom: 1.5em;
position: relative;
}
+
#textbox {
- margin-top: 2em;
- padding: 0;
+ width: 100%;
+ position: absolute;
+ bottom: 0;
+
+ margin-top: 0.5em;
+}
+
+#typing-indicator {
+ margin: 0;
+ margin-left: 1em;
+ margin-bottom: 0.5em;
+
+ position: absolute;
+ bottom: 3em;
}
#textbox input {
margin: 0.5em;
- margin-left: 0;
+ left: 1em;
width: 85%;
font-size: 1em;
@@ -71,16 +94,6 @@ button {
font-size: 1em;
}
-/*
-.loader-container {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100vh;
-}
-*/
-
-
.progress-bar {
width: 100%;
height: 100%;
@@ -101,9 +114,6 @@ button {
width: 0;
height: 100%;
background-color: #ff5c35;
- /*
- animation: fill 4s infinite;
- */
}
.message-status {
@@ -113,14 +123,3 @@ button {
right: 1em;
font-size: .8em;
}
-
-/*
-@keyframes fill {
- 0% {
- width: 0;
- }
- 100% {
- width: 100%;
- }
-}
-*/