feat: add participant names to group chat
This commit is contained in:
parent
08a15b9c95
commit
cf368b792d
15
caesar.json
15
caesar.json
|
@ -1,4 +1,11 @@
|
||||||
[
|
{
|
||||||
{ "character": 0, "text": "Sire! Forgive my informal message. We must speak."},
|
"characters": [
|
||||||
{ "character": 1, "text": "What is the meaning of this? What is so urgent it cannot wait for our usual meeting? Speak plainly and get to the pooint. I have more important matters to attend to than deciphering vague missives."}
|
"Mark Antony",
|
||||||
]
|
"Julius Caesar"
|
||||||
|
],
|
||||||
|
"messages":
|
||||||
|
[
|
||||||
|
{ "character": 0, "text": "Sire! Forgive my informal message. We must speak."},
|
||||||
|
{ "character": 1, "text": "What is the meaning of this? What is so urgent it cannot wait for our usual meeting? Speak plainly and get to the pooint. I have more important matters to attend to than deciphering vague missives."}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -1,23 +1,34 @@
|
||||||
[
|
{
|
||||||
{ "character": 1, "text": "Alright, it’s time. We need to finalize the plan. Everyone good for tomorrow?" },
|
"characters": [
|
||||||
{ "character": 2, "text": "Yes, it has to be tomorrow. No more delays." },
|
"Mark Antony",
|
||||||
{ "character": 3, "text": "Do we know exactly where he’s going to be?" },
|
"Cassius",
|
||||||
{ "character": 4, "text": "He’s going to the Senate tomorrow for sure. I’ve convinced him to go, even though he’s been acting paranoid lately." },
|
"Brutus",
|
||||||
{ "character": 5, "text": "Good. We need to catch him before he even suspects anything. Are we all clear on the roles?" },
|
"Casca",
|
||||||
{ "character": 1, "text": "I’ll signal when we’re ready. Brutus, you’ll come in last. Your presence will make it look more… noble." },
|
"Decimus",
|
||||||
{ "character": 2, "text": "It’s not about appearances. This is about saving the Republic." },
|
"Trebonius"
|
||||||
{ "character": 3, "text": "Yeah, yeah. But we can’t forget how people will react after this. They need to see it as necessary." },
|
],
|
||||||
{ "character": 1, "text": "Casca, you’ll be the first to strike, as planned. You good with that?" },
|
"messages": [
|
||||||
{ "character": 3, "text": "Yeah, I’ve got this. One stab, clean." },
|
{ "character": 1, "text": "Alright, it’s time. We need to finalize the plan. Everyone good for tomorrow?" },
|
||||||
{ "character": 4, "text": "Remember, we’re all in this together. There’s no turning back now." },
|
{ "character": 2, "text": "Yes, it has to be tomorrow. No more delays." },
|
||||||
{ "character": 5, "text": "What about Mark Antony? He’s always close to Caesar." },
|
{ "character": 3, "text": "Do we know exactly where he’s going to be?" },
|
||||||
{ "character": 1, "text": "Trebonius, you handle him. Keep him distracted outside. Just make sure he doesn’t get involved." },
|
{ "character": 4, "text": "He’s going to the Senate tomorrow for sure. I’ve convinced him to go, even though he’s been acting paranoid lately." },
|
||||||
{ "character": 5, "text": "Consider it done." },
|
{ "character": 5, "text": "Good. We need to catch him before he even suspects anything. Are we all clear on the roles?" },
|
||||||
{ "character": 2, "text": "Remember, this isn’t murder. It’s justice. Rome is greater than one man." },
|
{ "character": 1, "text": "I’ll signal when we’re ready. Brutus, you’ll come in last. Your presence will make it look more… noble." },
|
||||||
{ "character": 3, "text": "Right. But tomorrow… it’s gonna be chaos." },
|
{ "character": 2, "text": "It’s not about appearances. This is about saving the Republic." },
|
||||||
{ "character": 4, "text": "We’ll handle the fallout after. Stick to the plan." },
|
{ "character": 3, "text": "Yeah, yeah. But we can’t forget how people will react after this. They need to see it as necessary." },
|
||||||
{ "character": 1, "text": "Tomorrow, at the Senate. Let’s end this tyranny." },
|
{ "character": 1, "text": "Casca, you’ll be the first to strike, as planned. You good with that?" },
|
||||||
{ "character": 2, "text": "For Rome." },
|
{ "character": 3, "text": "Yeah, I’ve got this. One stab, clean." },
|
||||||
{ "character": 3, "text": "For the Republic." },
|
{ "character": 4, "text": "Remember, we’re all in this together. There’s no turning back now." },
|
||||||
{ "character": 5, "text": "For our future." }
|
{ "character": 5, "text": "What about Mark Antony? He’s always close to Caesar." },
|
||||||
]
|
{ "character": 1, "text": "Trebonius, you handle him. Keep him distracted outside. Just make sure he doesn’t get involved." },
|
||||||
|
{ "character": 5, "text": "Consider it done." },
|
||||||
|
{ "character": 2, "text": "Remember, this isn’t murder. It’s justice. Rome is greater than one man." },
|
||||||
|
{ "character": 3, "text": "Right. But tomorrow… it’s gonna be chaos." },
|
||||||
|
{ "character": 4, "text": "We’ll handle the fallout after. Stick to the plan." },
|
||||||
|
{ "character": 1, "text": "Tomorrow, at the Senate. Let’s end this tyranny." },
|
||||||
|
{ "character": 2, "text": "For Rome." },
|
||||||
|
{ "character": 3, "text": "For the Republic." },
|
||||||
|
{ "character": 5, "text": "For our future." },
|
||||||
|
{ "character": 0, "text": "uh" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"characters": [
|
||||||
|
"Mark Antony",
|
||||||
|
"Lepidus"
|
||||||
|
],
|
||||||
|
"messages": [
|
||||||
|
{ "character": 0, "text": "Lepidus, how’s the Senate holding up without Caesar?" },
|
||||||
|
{ "character": 0, "text": "I’m guessing things are getting messier by the day." },
|
||||||
|
{ "character": 1, "text": "You have no idea." },
|
||||||
|
{ "character": 1, "text": "Yesterday, half of them couldn’t even agree on the order of the agenda." },
|
||||||
|
{ "character": 0, "text": "Sounds like a circus." },
|
||||||
|
{ "character": 0, "text": "Need me to step in and straighten things out?" },
|
||||||
|
{ "character": 1, "text": "Might need more than that. We’re stretched thin on allies." },
|
||||||
|
{ "character": 0, "text": "We’ll make it work. Caesar’s return should stabilize things." },
|
||||||
|
{ "character": 1, "text": "Hopefully. Until then, I’ll try not to let it all fall apart." }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
30
lucius.json
30
lucius.json
|
@ -1,12 +1,18 @@
|
||||||
[
|
{
|
||||||
{ "character": 0, "text": "How’s everything in Rome, Lucius?" },
|
"characters": [
|
||||||
{ "character": 1, "text": "Same old chaos. Senate’s split on everything." },
|
"Mark Antony",
|
||||||
{ "character": 0, "text": "Let them bicker. You’re holding up, right?" },
|
"Lucius Antony"
|
||||||
{ "character": 1, "text": "Barely. Could use more allies here." },
|
],
|
||||||
{ "character": 0, "text": "I’ll see what I can do. Don’t let them push you around." },
|
"messages":
|
||||||
{ "character": 1, "text": "Not worried about that. Just tired of their nonsense." },
|
[
|
||||||
{ "character": 0, "text": "Hang in there. I’ll be back soon." },
|
{ "character": 0, "text": "How’s everything in Rome, Lucius?" },
|
||||||
{ "character": 1, "text": "You better. You owe me a break." },
|
{ "character": 1, "text": "Same old chaos. Senate’s split on everything." },
|
||||||
{ "character": 0, "text": "It’s coming, trust me." }
|
{ "character": 0, "text": "Let them bicker. You’re holding up, right?" },
|
||||||
]
|
{ "character": 1, "text": "Barely. Could use more allies here." },
|
||||||
|
{ "character": 0, "text": "I’ll see what I can do. Don’t let them push you around." },
|
||||||
|
{ "character": 1, "text": "Not worried about that. Just tired of their nonsense." },
|
||||||
|
{ "character": 0, "text": "Hang in there. I’ll be back soon." },
|
||||||
|
{ "character": 1, "text": "You better. You owe me a break." },
|
||||||
|
{ "character": 0, "text": "It’s coming, trust me." }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
88
main.js
88
main.js
|
@ -46,8 +46,9 @@ function getMessageList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
class AgentMessage {
|
class AgentMessage {
|
||||||
constructor(text) {
|
constructor(text, senderName) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
this.senderName = senderName;
|
||||||
}
|
}
|
||||||
|
|
||||||
getIsOurs() {
|
getIsOurs() {
|
||||||
|
@ -61,6 +62,12 @@ class AgentMessage {
|
||||||
contentElem.className = "message-content rounded-rectangle theirs";
|
contentElem.className = "message-content rounded-rectangle theirs";
|
||||||
liElem.appendChild(contentElem);
|
liElem.appendChild(contentElem);
|
||||||
|
|
||||||
|
if (this.senderName) {
|
||||||
|
const nameElem = document.createElement("h3");
|
||||||
|
nameElem.innerHTML = this.senderName;
|
||||||
|
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 = this.text;
|
||||||
|
@ -191,7 +198,7 @@ function setVisibleOnMobile(element, isVisible) {
|
||||||
classes.splice(idx, 1);
|
classes.splice(idx, 1);
|
||||||
}
|
}
|
||||||
classes.push(visibleClass);
|
classes.push(visibleClass);
|
||||||
} else if (!classes.includes(invisibleClass)) {
|
} else if (!isVisible && !classes.includes(invisibleClass)) {
|
||||||
const idx = classes.indexOf(visibleClass);
|
const idx = classes.indexOf(visibleClass);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
classes.splice(idx, 1);
|
classes.splice(idx, 1);
|
||||||
|
@ -213,6 +220,12 @@ function showSidePanel() {
|
||||||
setVisibleOnMobile(conversationListElem, true);
|
setVisibleOnMobile(conversationListElem, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readConversationJson(path, callback) {
|
||||||
|
fetch(path)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(json => callback(json));
|
||||||
|
}
|
||||||
|
|
||||||
function showConversation(path) {
|
function showConversation(path) {
|
||||||
|
|
||||||
const mainPanel = document.getElementById("main-panel");
|
const mainPanel = document.getElementById("main-panel");
|
||||||
|
@ -223,59 +236,62 @@ function showConversation(path) {
|
||||||
|
|
||||||
const title = path.split(".")[0];
|
const title = path.split(".")[0];
|
||||||
|
|
||||||
fetch(path)
|
readConversationJson(path, json => {
|
||||||
.then(response => response.json())
|
conversation = new Conversation(title);
|
||||||
.then(json => {
|
const jsonMessages = json.messages;
|
||||||
conversation = new Conversation(title);
|
const participants = json.characters;
|
||||||
|
|
||||||
let initialMessages = [];
|
let initialMessages = [];
|
||||||
|
|
||||||
for (let i = 0; i < json.length; i++) {
|
for (let i = 0; i < jsonMessages.length; i++) {
|
||||||
const data = json[i];
|
const data = jsonMessages[i];
|
||||||
const text = data.text;
|
const text = data.text;
|
||||||
if (data.character == 0) {
|
if (data.character == 0) {
|
||||||
const message = new UserMessage(text);
|
const message = new UserMessage(text);
|
||||||
message.updateStatus("delivered");
|
message.updateStatus("delivered");
|
||||||
initialMessages.push(message);
|
initialMessages.push(message);
|
||||||
} else {
|
} else {
|
||||||
const message = new AgentMessage(text);
|
const message = participants.length > 2
|
||||||
initialMessages.push(message);
|
? new AgentMessage(text, participants[data.character])
|
||||||
}
|
: new AgentMessage(text);
|
||||||
|
initialMessages.push(message);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
conversation.initialize(initialMessages);
|
conversation.initialize(initialMessages);
|
||||||
conversation.render();
|
conversation.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addConversationPreview(path) {
|
function addConversationPreview(path) {
|
||||||
const title = path.split(".")[0];
|
const title = path.split(".")[0];
|
||||||
const listRoot = document.getElementById("side-panel");
|
const listRoot = document.getElementById("side-panel");
|
||||||
|
|
||||||
fetch(path)
|
readConversationJson(path, json => {
|
||||||
.then(response => response.json())
|
const messages = json.messages;
|
||||||
.then(json => {
|
|
||||||
const elem = document.createElement("div");
|
|
||||||
elem.onclick = () => showConversation(path);
|
|
||||||
elem.className = "conversation";
|
|
||||||
|
|
||||||
const headerElem = document.createElement("h2");
|
const elem = document.createElement("div");
|
||||||
headerElem.innerHTML = title;
|
elem.onclick = () => showConversation(path);
|
||||||
elem.appendChild(headerElem);
|
elem.className = "conversation";
|
||||||
|
|
||||||
const previewElem = document.createElement("span");
|
const headerElem = document.createElement("h2");
|
||||||
previewElem.innerHTML = json[json.length - 1].text;
|
headerElem.innerHTML = title;
|
||||||
elem.appendChild(previewElem);
|
elem.appendChild(headerElem);
|
||||||
|
|
||||||
listRoot.appendChild(elem);
|
const previewElem = document.createElement("span");
|
||||||
});
|
previewElem.innerHTML = messages[messages.length - 1].text;
|
||||||
|
elem.appendChild(previewElem);
|
||||||
|
|
||||||
|
listRoot.appendChild(elem);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateConversationList() {
|
function populateConversationList() {
|
||||||
const conversationFiles = [
|
const conversationFiles = [
|
||||||
"caesar.json",
|
"caesar.json",
|
||||||
"lucius.json",
|
"lucius.json",
|
||||||
"ides-of-march.json"
|
"ides-of-march.json",
|
||||||
|
"lepidus.json"
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i = 0; i < conversationFiles.length; i++) {
|
for (let i = 0; i < conversationFiles.length; i++) {
|
||||||
|
|
16
styles.css
16
styles.css
|
@ -134,7 +134,17 @@ h1 {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-content.theirs h3 {
|
||||||
|
color: color-mix(in hsl, var(--eggshell) 50%, white 50%);
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
font-size: .85em;
|
||||||
|
font-weight: bolder;
|
||||||
|
letter-spacing: .03em;
|
||||||
|
}
|
||||||
|
|
||||||
.theirs .message-text {
|
.theirs .message-text {
|
||||||
|
/*TODO: move this up to .message-content.theirs?*/
|
||||||
color: var(--eggshell);
|
color: var(--eggshell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,12 +181,8 @@ li {
|
||||||
#textbox {
|
#textbox {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
/*position: sticky;*/
|
|
||||||
/*flex-position: end;*/
|
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
||||||
margin-top: 0.5em;
|
|
||||||
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
background-color: var(--dark-purple);
|
background-color: var(--dark-purple);
|
||||||
|
@ -194,7 +200,7 @@ li {
|
||||||
}
|
}
|
||||||
|
|
||||||
#textbox input {
|
#textbox input {
|
||||||
flex-grow: 2;
|
flex-grow: 4;
|
||||||
|
|
||||||
color: var(--dark-purple);
|
color: var(--dark-purple);
|
||||||
background-color: var(--eggshell);
|
background-color: var(--eggshell);
|
||||||
|
|
Loading…
Reference in New Issue