feat: conversation switcher
This commit is contained in:
parent
023b8fe55f
commit
08a15b9c95
19
index.html
19
index.html
|
@ -6,26 +6,12 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="side-panel">
|
<div id="side-panel"></div>
|
||||||
|
|
||||||
<div class="conversation">
|
|
||||||
<h2>Lorem</h2>
|
|
||||||
<span>Lorem ipsum blah-de-fuck</span>
|
|
||||||
</div>
|
|
||||||
<div class="conversation">
|
|
||||||
<h2>Caesar</h2>
|
|
||||||
<span>Heyy Markus-chan uwu xoxo. i heard u was in town maybe stop by</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
TODO: other conversations to fill out the panel! filler stuff!
|
|
||||||
-->
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div id="main-panel">
|
<div id="main-panel">
|
||||||
|
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<button class="rounded-rectangle" onclick="console.log('back')"><- back</button>
|
<button id="conversation-list-button" class="rounded-rectangle" onclick="showSidePanel()"><- back</button>
|
||||||
<h1 id="header-title">NAME</h1>
|
<h1 id="header-title">NAME</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -37,6 +23,7 @@ TODO: other conversations to fill out the panel! filler stuff!
|
||||||
<input id="textbox-input" class="rounded-rectangle" type="text" onkeydown="pressSendButton()"></input>
|
<input id="textbox-input" class="rounded-rectangle" type="text" onkeydown="pressSendButton()"></input>
|
||||||
<button class="rounded-rectangle" onclick="pressSendButton()">send</button>
|
<button class="rounded-rectangle" onclick="pressSendButton()">send</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="main.js"></script>
|
<script src="main.js"></script>
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
[
|
||||||
|
{ "character": 0, "text": "How’s everything in Rome, Lucius?" },
|
||||||
|
{ "character": 1, "text": "Same old chaos. Senate’s split on everything." },
|
||||||
|
{ "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." }
|
||||||
|
]
|
||||||
|
|
126
main.js
126
main.js
|
@ -177,31 +177,115 @@ function onMessageSent(message) {
|
||||||
updateChat(message);
|
updateChat(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
function init(messagesData) {
|
// probably a bit hacky! but this saves having to do like, state or something in CSS?
|
||||||
conversation = new Conversation("Caesar");
|
// which probably is possible and probably would be the better way to do it, but that
|
||||||
|
// sounds like a bunch of learning i'm not SUPER in the mood for
|
||||||
|
function setVisibleOnMobile(element, isVisible) {
|
||||||
|
let classes = element.className.split().filter(c => c != "");
|
||||||
|
const invisibleClass = "invisible-on-mobile";
|
||||||
|
const visibleClass = "visible";
|
||||||
|
|
||||||
let initialMessages = [];
|
if (isVisible && !classes.includes(visibleClass)) {
|
||||||
|
const idx = classes.indexOf(invisibleClass);
|
||||||
for (let i = 0; i < messagesData.length; i++) {
|
if (idx != -1) {
|
||||||
const data = messagesData[i];
|
classes.splice(idx, 1);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
classes.push(visibleClass);
|
||||||
|
} else if (!classes.includes(invisibleClass)) {
|
||||||
|
const idx = classes.indexOf(visibleClass);
|
||||||
|
if (idx != -1) {
|
||||||
|
classes.splice(idx, 1);
|
||||||
|
}
|
||||||
|
classes.push(invisibleClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
conversation.initialize(initialMessages);
|
element.className = classes.join(" ");
|
||||||
conversation.render();
|
|
||||||
|
|
||||||
setTypingIndicator(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch("lorem.json")
|
function showSidePanel() {
|
||||||
.then(response => response.json())
|
// this function can only be called on mobile. the main conversation should be
|
||||||
.then(json => init(json));
|
// hidden and the side conversations panel should take up the whole screen.
|
||||||
|
|
||||||
|
const mainPanel = document.getElementById("main-panel");
|
||||||
|
const conversationListElem = document.getElementById("side-panel");
|
||||||
|
|
||||||
|
setVisibleOnMobile(mainPanel, false);
|
||||||
|
setVisibleOnMobile(conversationListElem, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showConversation(path) {
|
||||||
|
|
||||||
|
const mainPanel = document.getElementById("main-panel");
|
||||||
|
const conversationListElem = document.getElementById("side-panel");
|
||||||
|
|
||||||
|
setVisibleOnMobile(mainPanel, true);
|
||||||
|
setVisibleOnMobile(conversationListElem, false);
|
||||||
|
|
||||||
|
const title = path.split(".")[0];
|
||||||
|
|
||||||
|
fetch(path)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(json => {
|
||||||
|
conversation = new Conversation(title);
|
||||||
|
|
||||||
|
let initialMessages = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < json.length; i++) {
|
||||||
|
const data = json[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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addConversationPreview(path) {
|
||||||
|
const title = path.split(".")[0];
|
||||||
|
const listRoot = document.getElementById("side-panel");
|
||||||
|
|
||||||
|
fetch(path)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(json => {
|
||||||
|
const elem = document.createElement("div");
|
||||||
|
elem.onclick = () => showConversation(path);
|
||||||
|
elem.className = "conversation";
|
||||||
|
|
||||||
|
const headerElem = document.createElement("h2");
|
||||||
|
headerElem.innerHTML = title;
|
||||||
|
elem.appendChild(headerElem);
|
||||||
|
|
||||||
|
const previewElem = document.createElement("span");
|
||||||
|
previewElem.innerHTML = json[json.length - 1].text;
|
||||||
|
elem.appendChild(previewElem);
|
||||||
|
|
||||||
|
listRoot.appendChild(elem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateConversationList() {
|
||||||
|
const conversationFiles = [
|
||||||
|
"caesar.json",
|
||||||
|
"lucius.json",
|
||||||
|
"ides-of-march.json"
|
||||||
|
];
|
||||||
|
|
||||||
|
for (let i = 0; i < conversationFiles.length; i++) {
|
||||||
|
const path = conversationFiles[i];
|
||||||
|
addConversationPreview(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTypingIndicator(false);
|
||||||
|
populateConversationList();
|
||||||
|
|
||||||
|
showConversation("lucius.json");
|
||||||
|
|
||||||
|
|
72
styles.css
72
styles.css
|
@ -19,16 +19,56 @@ body {
|
||||||
|
|
||||||
#side-panel {
|
#side-panel {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: red;
|
background-color: var(--dark-purple);
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
width: 0;
|
#header button {
|
||||||
visibility: hidden;
|
transform: translateY(-.3em);
|
||||||
|
width: auto;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
#side-panel {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#side-panel.invisible-on-mobile {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* on desktop only */
|
||||||
|
@media only screen and (min-width: 768px) {
|
||||||
|
#side-panel {
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
visibility: visible;
|
||||||
|
border-right: 3px solid var(--eggshell);
|
||||||
|
}
|
||||||
|
|
||||||
|
#side-panel.invisible-on-mobile {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header button {
|
||||||
|
width: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#side-panel .conversation {
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#side-panel .conversation {
|
#side-panel .conversation {
|
||||||
width: 300px;
|
width: 100%;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
border: solid black 3px;
|
border-bottom: solid var(--eggshell) 3px;
|
||||||
|
color: var(--eggshell);
|
||||||
|
padding: .5em;
|
||||||
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -36,7 +76,8 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
#side-panel .conversation:hover {
|
#side-panel .conversation:hover {
|
||||||
background-color: pink;
|
background-color: var(--eggshell);
|
||||||
|
color: var(--dark-purple);
|
||||||
}
|
}
|
||||||
|
|
||||||
#side-panel h2 {
|
#side-panel h2 {
|
||||||
|
@ -46,7 +87,6 @@ body {
|
||||||
#header {
|
#header {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
background-color: red;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#main-panel {
|
#main-panel {
|
||||||
|
@ -63,9 +103,6 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
transform: translateY(.3rem);
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
color: var(--eggshell);
|
color: var(--eggshell);
|
||||||
|
@ -114,6 +151,7 @@ h1 {
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
|
/*height:100%;*/
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
margin: .5em;
|
margin: .5em;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -185,16 +223,6 @@ button:hover {
|
||||||
background-color: var(--eggshell);
|
background-color: var(--eggshell);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: 768px) {
|
|
||||||
button {
|
|
||||||
width: 10%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#textbox input {
|
|
||||||
width: 85%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -222,7 +250,3 @@ button:hover {
|
||||||
right: 1em;
|
right: 1em;
|
||||||
font-size: .8em;
|
font-size: .8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conversations {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue