feat: romanize text
This commit is contained in:
parent
f4b6960047
commit
5405fc730e
61
main.js
61
main.js
|
@ -5,7 +5,7 @@ var conversation = null;
|
||||||
class Conversation {
|
class Conversation {
|
||||||
constructor(name) {
|
constructor(name) {
|
||||||
this.messages = [];
|
this.messages = [];
|
||||||
this.name = name;
|
this.name = romanize(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
setInteractive(isInteractive) {
|
setInteractive(isInteractive) {
|
||||||
|
@ -29,6 +29,10 @@ class Conversation {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
message.updateStatus("delivered");
|
message.updateStatus("delivered");
|
||||||
this.render();
|
this.render();
|
||||||
|
setTimeout(() => {
|
||||||
|
message.updateStatus("read");
|
||||||
|
this.render();
|
||||||
|
}, 5000);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
this.messages.push(message);
|
this.messages.push(message);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +42,27 @@ class Conversation {
|
||||||
// clear stale HTML
|
// clear stale HTML
|
||||||
getMessageList().innerHTML = "";
|
getMessageList().innerHTML = "";
|
||||||
|
|
||||||
|
// if there are multiple 'read' messages, we only want the last one to display
|
||||||
|
// the status. the other ones must have been read, so clear their statuses.
|
||||||
|
let foundReadMessage = false;
|
||||||
|
for (let i = this.messages.length - 1; i >= 0; i--) {
|
||||||
|
const message = this.messages[i];
|
||||||
|
if (!message.getIsOurs())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if we haven't found a read message yet, let's check to see if we have now
|
||||||
|
if (!foundReadMessage) {
|
||||||
|
if (message.status == "read") {
|
||||||
|
foundReadMessage = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we have found a read message, which means all messages above it should
|
||||||
|
// have empty status
|
||||||
|
message.updateStatus("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// render message elements
|
// render message elements
|
||||||
for (let i = 0; i < this.messages.length; i++)
|
for (let i = 0; i < this.messages.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +77,12 @@ function getMessageList() {
|
||||||
return document.getElementById("messages");
|
return document.getElementById("messages");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function romanize(text) {
|
||||||
|
text = text.replaceAll('u', 'v');
|
||||||
|
text = text.replaceAll('U', 'V');
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
class AgentMessage {
|
class AgentMessage {
|
||||||
constructor(text, senderName) {
|
constructor(text, senderName) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
@ -72,13 +103,13 @@ class AgentMessage {
|
||||||
|
|
||||||
if (this.senderName) {
|
if (this.senderName) {
|
||||||
const nameElem = document.createElement("h3");
|
const nameElem = document.createElement("h3");
|
||||||
nameElem.innerHTML = this.senderName;
|
nameElem.innerHTML = romanize(this.senderName);
|
||||||
contentElem.appendChild(nameElem);
|
contentElem.appendChild(nameElem);
|
||||||
}
|
}
|
||||||
|
|
||||||
const textElem = document.createElement("span");
|
const textElem = document.createElement("span");
|
||||||
textElem.className = "message-text";
|
textElem.className = "message-text";
|
||||||
textElem.innerHTML = this.text;
|
textElem.innerHTML = romanize(this.text);
|
||||||
contentElem.appendChild(textElem);
|
contentElem.appendChild(textElem);
|
||||||
|
|
||||||
return liElem;
|
return liElem;
|
||||||
|
@ -88,7 +119,7 @@ class AgentMessage {
|
||||||
class UserMessage {
|
class UserMessage {
|
||||||
constructor(text) {
|
constructor(text) {
|
||||||
this.createdTime = Date.now();
|
this.createdTime = Date.now();
|
||||||
this.text = text;
|
this.text = romanize(text);
|
||||||
this.status = "";
|
this.status = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +155,11 @@ class UserMessage {
|
||||||
|
|
||||||
class SystemMessage {
|
class SystemMessage {
|
||||||
constructor(text) {
|
constructor(text) {
|
||||||
this.text = text;
|
this.text = romanize(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
getIsOurs() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getElement() {
|
getElement() {
|
||||||
|
@ -178,14 +213,18 @@ function updateChat(message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function pressSendButton() {
|
function pressSendButton() {
|
||||||
|
const textBox = document.getElementById("textbox-input");
|
||||||
|
|
||||||
if (event.type == "keydown" && event.key != "Enter")
|
if (event.type == "keydown" && event.key != "Enter")
|
||||||
|
{
|
||||||
|
textBox.value = romanize(textBox.value);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// we have interacted with the page so remove all pings
|
// we have interacted with the page so remove all pings
|
||||||
clearPings();
|
clearPings();
|
||||||
|
|
||||||
// get the content of the text box
|
// get the content of the text box
|
||||||
const textBox = document.getElementById("textbox-input");
|
|
||||||
const text = textBox.value;
|
const text = textBox.value;
|
||||||
if (!text)
|
if (!text)
|
||||||
return;
|
return;
|
||||||
|
@ -273,7 +312,7 @@ function showConversation(path) {
|
||||||
initialMessages.push(message);
|
initialMessages.push(message);
|
||||||
} else if (data.character == 0) {
|
} else if (data.character == 0) {
|
||||||
const message = new UserMessage(text);
|
const message = new UserMessage(text);
|
||||||
message.updateStatus("delivered");
|
message.updateStatus("read");
|
||||||
initialMessages.push(message);
|
initialMessages.push(message);
|
||||||
} else {
|
} else {
|
||||||
const message = participants.length > 2
|
const message = participants.length > 2
|
||||||
|
@ -300,11 +339,11 @@ function addConversationPreview(path) {
|
||||||
elem.className = "conversation";
|
elem.className = "conversation";
|
||||||
|
|
||||||
const headerElem = document.createElement("h2");
|
const headerElem = document.createElement("h2");
|
||||||
headerElem.innerHTML = json.title;
|
headerElem.innerHTML = romanize(json.title);
|
||||||
elem.appendChild(headerElem);
|
elem.appendChild(headerElem);
|
||||||
|
|
||||||
const previewElem = document.createElement("span");
|
const previewElem = document.createElement("span");
|
||||||
previewElem.innerHTML = messages[messages.length - 1].text;
|
previewElem.innerHTML = romanize(messages[messages.length - 1].text);
|
||||||
elem.appendChild(previewElem);
|
elem.appendChild(previewElem);
|
||||||
|
|
||||||
listRoot.appendChild(elem);
|
listRoot.appendChild(elem);
|
||||||
|
@ -316,7 +355,9 @@ function populateConversationList() {
|
||||||
"caesar.json",
|
"caesar.json",
|
||||||
"lucius.json",
|
"lucius.json",
|
||||||
"ides-of-march.json",
|
"ides-of-march.json",
|
||||||
"lepidus.json"
|
"lepidus.json",
|
||||||
|
"publius.json",
|
||||||
|
"sextus.json"
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i = 0; i < conversationFiles.length; i++) {
|
for (let i = 0; i < conversationFiles.length; i++) {
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"title": "Publius Ventidius",
|
||||||
|
"interactive": true,
|
||||||
|
"characters": [
|
||||||
|
"Mark Antony",
|
||||||
|
"Publius Ventidius"
|
||||||
|
],
|
||||||
|
"messages":
|
||||||
|
[
|
||||||
|
{ "character": 0, "text": "Publius! I’ve just received word about your latest victory. Remarkable work!" },
|
||||||
|
{ "character": 1, "text": "Thank you, Antony. We struck swiftly, caught them off guard. Just doing my part." },
|
||||||
|
{ "character": 0, "text": "Humble as always. But this win, it puts us in a strong position for the next phase." },
|
||||||
|
{ "character": 0, "text": "Tell me, what do you need? More men? Supplies?" },
|
||||||
|
{ "character": 1, "text": "I could use more cavalry, if anything. Our infantry held, but the Parthians are relentless on horseback." },
|
||||||
|
{ "character": 0, "text": "Consider it done. I’ll make sure you have reinforcements by the end of the week." },
|
||||||
|
{ "character": 1, "text": "Much appreciated. We’re close, Antony. A few more pushes and we’ll have them routed." },
|
||||||
|
{ "character": 0, "text": "Good. Keep the pressure on. I’ll handle things on my end. Victory is within reach." }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"title": "Sextus Pompey",
|
||||||
|
"interactive": true,
|
||||||
|
"characters": [
|
||||||
|
"Mark Antony",
|
||||||
|
"Sextus Pompey"
|
||||||
|
],
|
||||||
|
"messages":
|
||||||
|
[
|
||||||
|
{ "character": 0, "text": "Sextus, we need to talk. I’m hearing whispers about your fleet near Sicily." },
|
||||||
|
{ "character": 1, "text": "Whispers? I prefer to call it preparation. A man like me can't afford to sit idly by, Antony." },
|
||||||
|
{ "character": 0, "text": "Preparation for what, exactly? We’ve got enough chaos in Rome without another power struggle." },
|
||||||
|
{ "character": 1, "text": "Oh, don’t worry. My interests are my own, but I’m no threat to you… for now." },
|
||||||
|
{ "character": 0, "text": "For now? That's reassuring. Look, we don’t need more enemies right now, Sextus. We can work together." },
|
||||||
|
{ "character": 1, "text": "You talk of unity, but you’re quick to defend Caesar's agenda. I haven't forgotten how my father was treated." },
|
||||||
|
{ "character": 0, "text": "I’m not my father’s shadow, nor Caesar’s. Just think about it. We’re stronger together than apart." },
|
||||||
|
{ "character": 1, "text": "I’ll think about it. But remember, Antony, my loyalty isn’t given easily." }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
88
styles.css
88
styles.css
|
@ -4,6 +4,13 @@
|
||||||
--eggshell: #dfe2cf;
|
--eggshell: #dfe2cf;
|
||||||
--ucla-blue: #4d7298;
|
--ucla-blue: #4d7298;
|
||||||
--robin-egg-blue: #66ced6;
|
--robin-egg-blue: #66ced6;
|
||||||
|
|
||||||
|
--vermilion: #ef3e36;
|
||||||
|
--lapis-lazuli: #235789;
|
||||||
|
--onyx: #383d3b;
|
||||||
|
--light-cyan: #e0fbfc;
|
||||||
|
--buff: #edb88b;
|
||||||
|
--eeriee-black: #1d201f;
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
|
@ -15,12 +22,13 @@ body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
background-color: var(--buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
#side-panel {
|
#side-panel {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: var(--dark-purple);
|
|
||||||
display: none;
|
display: none;
|
||||||
|
color: var(--onyx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#header button {
|
#header button {
|
||||||
|
@ -44,7 +52,7 @@ body {
|
||||||
display: block;
|
display: block;
|
||||||
width: auto;
|
width: auto;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
border-right: 3px solid var(--eggshell);
|
border-right: 3px solid var(--onyx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#side-panel.invisible-on-mobile {
|
#side-panel.invisible-on-mobile {
|
||||||
|
@ -66,8 +74,8 @@ body {
|
||||||
#side-panel .conversation {
|
#side-panel .conversation {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
border-bottom: solid var(--eggshell) 3px;
|
border-bottom: solid var(--onyx) 3px;
|
||||||
color: var(--eggshell);
|
color: var(--onyx);
|
||||||
padding: .5em;
|
padding: .5em;
|
||||||
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -76,8 +84,8 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
#side-panel .conversation:hover {
|
#side-panel .conversation:hover {
|
||||||
background-color: var(--eggshell);
|
background-color: var(--vermilion);
|
||||||
color: var(--dark-purple);
|
color: var(--light-cyan);
|
||||||
}
|
}
|
||||||
|
|
||||||
#side-panel h2 {
|
#side-panel h2 {
|
||||||
|
@ -87,10 +95,10 @@ body {
|
||||||
#header {
|
#header {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
border-bottom: solid var(--onyx) 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#main-panel {
|
#main-panel {
|
||||||
background-color: var(--dark-purple);
|
|
||||||
float: right;
|
float: right;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -104,14 +112,8 @@ body {
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
color: var(--onyx);
|
||||||
color: var(--eggshell);
|
margin-left: 1em;
|
||||||
}
|
|
||||||
|
|
||||||
.delay {
|
|
||||||
display: inline;
|
|
||||||
|
|
||||||
color: var(--robin-egg-blue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.rounded-rectangle {
|
.rounded-rectangle {
|
||||||
|
@ -129,13 +131,14 @@ h1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-content.theirs {
|
.message-content.theirs {
|
||||||
background-color: var(--ucla-blue);
|
background-color: var(--onyx);
|
||||||
|
color: var(--light-cyan);
|
||||||
|
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-content.theirs h3 {
|
.message-content.theirs h3 {
|
||||||
color: color-mix(in hsl, var(--eggshell) 50%, white 50%);
|
color: var(--buff);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
font-size: .85em;
|
font-size: .85em;
|
||||||
|
@ -144,23 +147,21 @@ h1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.theirs .message-text {
|
.theirs .message-text {
|
||||||
/*TODO: move this up to .message-content.theirs?*/
|
|
||||||
color: var(--eggshell);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-content.ours {
|
.message-content.ours {
|
||||||
background-color: var(--eggshell);
|
background-color: var(--vermilion);
|
||||||
|
|
||||||
right: 0;
|
right: 0;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ours .message-text {
|
.ours .message-text {
|
||||||
color: var(--dark-purple);
|
color: var(--light-cyan);
|
||||||
}
|
}
|
||||||
|
|
||||||
.system-message {
|
.system-message {
|
||||||
color: color-mix(in hsl, var(--eggshell) 80%, var(--dark-purple) 100%);
|
color: var(--onyx);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
@ -169,8 +170,8 @@ ul {
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
/*height:100%;*/
|
/*height:100%;*/
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
margin: .5em;
|
margin: 0 .5em;
|
||||||
padding: 0;
|
padding: .5em 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +185,7 @@ li.message {
|
||||||
height: 2.5em;
|
height: 2.5em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
margin-bottom: 1.5em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#textbox {
|
#textbox {
|
||||||
|
@ -194,7 +195,7 @@ li.message {
|
||||||
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
background-color: var(--dark-purple);
|
/*background-color: var(--light-cyan);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#typing-indicator {
|
#typing-indicator {
|
||||||
|
@ -211,8 +212,8 @@ li.message {
|
||||||
#textbox input {
|
#textbox input {
|
||||||
flex-grow: 4;
|
flex-grow: 4;
|
||||||
|
|
||||||
color: var(--dark-purple);
|
color: var(--onyx);
|
||||||
background-color: var(--eggshell);
|
background-color: var(--light-cyan);
|
||||||
|
|
||||||
margin: 0.5em;
|
margin: 0.5em;
|
||||||
left: 1em;
|
left: 1em;
|
||||||
|
@ -223,8 +224,8 @@ li.message {
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
background-color: var(--dark-purple);
|
background-color: var(--vermilion);
|
||||||
color: var(--eggshell);
|
color: var(--light-cyan);
|
||||||
|
|
||||||
margin: 0.5em;
|
margin: 0.5em;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -234,34 +235,15 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
button:hover {
|
||||||
color: var(--dark-purple);
|
color: var(--light-cyan);
|
||||||
background-color: var(--eggshell);
|
background-color: var(--onyx);
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
max-width: 400px;
|
|
||||||
border-radius: 1em;
|
|
||||||
overflow: hidden;
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
z-index: -1;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress {
|
|
||||||
opacity: 50%;
|
|
||||||
width: 0;
|
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-status {
|
.message-status {
|
||||||
color: var(--eggshell);
|
color: var(--onyx);
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 2.3em;
|
bottom: -1.75em;
|
||||||
right: 1em;
|
right: 1em;
|
||||||
font-size: .8em;
|
font-size: .8em;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue