208 lines
5.1 KiB
JavaScript
208 lines
5.1 KiB
JavaScript
const startTime = Date.now();
|
|
|
|
var conversation = null;
|
|
|
|
class Conversation {
|
|
constructor(name) {
|
|
this.messages = [];
|
|
this.name = name;
|
|
}
|
|
|
|
initialize(initialMessages) {
|
|
document.title = this.name;
|
|
document.getElementById("header-title").innerHTML = this.name;
|
|
|
|
this.messages = initialMessages;
|
|
}
|
|
|
|
// for the user to send their own messages
|
|
sendUserMessage(text) {
|
|
const message = new UserMessage(text);
|
|
message.updateStatus("sent");
|
|
setTimeout(() => {
|
|
message.updateStatus("delivered");
|
|
this.render();
|
|
}, 1000);
|
|
this.messages.push(message);
|
|
}
|
|
|
|
// update the current HTML based on messages
|
|
render() {
|
|
// clear stale HTML
|
|
getMessageList().innerHTML = "";
|
|
|
|
// render message elements
|
|
for (let i = 0; i < this.messages.length; i++)
|
|
{
|
|
const messageRoot = document.getElementById("messages");
|
|
const newMessage = this.messages[i];
|
|
messageRoot.appendChild(newMessage.getElement());
|
|
}
|
|
}
|
|
}
|
|
|
|
function getMessageList() {
|
|
return document.getElementById("messages");
|
|
}
|
|
|
|
class AgentMessage {
|
|
constructor(text) {
|
|
this.text = text;
|
|
}
|
|
|
|
getIsOurs() {
|
|
return false;
|
|
}
|
|
|
|
getElement() {
|
|
const liElem = document.createElement("li");
|
|
|
|
const contentElem = document.createElement("span");
|
|
contentElem.className = "message-content rounded-rectangle theirs";
|
|
liElem.appendChild(contentElem);
|
|
|
|
const textElem = document.createElement("span");
|
|
textElem.className = "message-text";
|
|
textElem.innerHTML = this.text;
|
|
contentElem.appendChild(textElem);
|
|
|
|
return liElem;
|
|
}
|
|
}
|
|
|
|
class UserMessage {
|
|
constructor(text) {
|
|
this.createdTime = Date.now();
|
|
this.text = text;
|
|
this.status = "";
|
|
}
|
|
|
|
getIsOurs() {
|
|
return true;
|
|
}
|
|
|
|
getElement() {
|
|
const liElem = document.createElement("li");
|
|
|
|
const contentElem = document.createElement("span");
|
|
contentElem.className = "message-content rounded-rectangle ours";
|
|
liElem.appendChild(contentElem);
|
|
|
|
const textElem = document.createElement("span");
|
|
textElem.className = "message-text";
|
|
textElem.innerHTML = this.text;
|
|
contentElem.appendChild(textElem);
|
|
|
|
const statusElem = document.createElement("p");
|
|
statusElem.className = "message-status";
|
|
statusElem.innerHTML = this.status;
|
|
liElem.appendChild(statusElem);
|
|
|
|
return liElem;
|
|
}
|
|
|
|
updateStatus(newStatus) {
|
|
this.status = newStatus;
|
|
}
|
|
}
|
|
|
|
function setTypingIndicator(isTyping) {
|
|
document.getElementById("typing-indicator").innerHTML = isTyping
|
|
? `${conversation.contactName} is typing...`
|
|
: "";
|
|
}
|
|
|
|
// add the message at the index to the displayed messages
|
|
function addMessage(message) {
|
|
getMessageList().innerHTML += message.getHtml();
|
|
|
|
// scroll as far as we can so that messages aren't hidden
|
|
window.scrollTo(0, document.body.scrollHeight);
|
|
}
|
|
|
|
function updatePings() {
|
|
const title = conversation.name;
|
|
let newTitle = conversation.pings > 0
|
|
? `(${conversation.pings}) ${title}`
|
|
: title;
|
|
|
|
document.title = newTitle;
|
|
}
|
|
|
|
function clearPings() {
|
|
conversation.pings = 0;
|
|
updatePings();
|
|
}
|
|
|
|
// returns a decimal value between min and max
|
|
function getRandomInRange(min, max) {
|
|
const range = max - min;
|
|
return min + Math.random() * range;
|
|
}
|
|
|
|
function updateChat(message) {
|
|
addMessage(message);
|
|
const previewText = conversation.getTypedMessageText();
|
|
document.getElementById("textbox-input").value = previewText;
|
|
updatePings();
|
|
}
|
|
|
|
function pressSendButton() {
|
|
if (event.type == "keydown" && event.key != "Enter")
|
|
return;
|
|
|
|
// we have interacted with the page so remove all pings
|
|
clearPings();
|
|
|
|
// get the content of the text box
|
|
const textBox = document.getElementById("textbox-input");
|
|
const text = textBox.value;
|
|
if (!text)
|
|
return;
|
|
|
|
textBox.value = "";
|
|
|
|
conversation.sendUserMessage(text);
|
|
conversation.render();
|
|
|
|
// TODO: start process of receiving next message from server (or fake it for now)
|
|
}
|
|
|
|
function onMessageReceived(message) {
|
|
updateChat(message);
|
|
setTypingIndicator(false);
|
|
}
|
|
|
|
function onMessageSent(message) {
|
|
updateChat(message);
|
|
}
|
|
|
|
function init(messagesData) {
|
|
conversation = new Conversation("Caesar");
|
|
|
|
let initialMessages = [];
|
|
|
|
for (let i = 0; i < messagesData.length; i++) {
|
|
const data = messagesData[i];
|
|
const text = data.text;
|
|
if (data.character == 0) {
|
|
const message = new UserMessage(text);
|
|
message.updateStatus("delivered");
|
|
initialMessages.push(message);
|
|
} else {
|
|
const message = new AgentMessage(text);
|
|
initialMessages.push(message);
|
|
}
|
|
}
|
|
|
|
conversation.initialize(initialMessages);
|
|
conversation.render();
|
|
|
|
setTypingIndicator(false);
|
|
}
|
|
|
|
fetch("caesar.json")
|
|
.then(response => response.json())
|
|
.then(json => init(json));
|
|
|