Implement Help button and modal
This commit is contained in:
parent
2676f40309
commit
afb151009a
3 changed files with 333 additions and 2 deletions
17
index.html
17
index.html
|
|
@ -21,7 +21,8 @@
|
|||
<div class="sidebar-subtitle">Conversations</div>
|
||||
<div class="conversations-list" id="conversations-list"></div>
|
||||
</div>
|
||||
<div style="color: rgb(255, 255, 255); text-decoration: none; font-weight: 200; position: fixed; bottom: 0; left: 0; height: 50px; width: 250px; background-color: black; z-index: 2000;">
|
||||
<div style="color: rgb(255, 255, 255); text-decoration: none; font-weight: 200; position: fixed; bottom: 0; left: 0; height: 90px; width: 250px; background-color: black; z-index: 2000;">
|
||||
<button id="help-btn" class="help-btn">Help</button>
|
||||
<a href="privacy/" style="color: rgb(255, 255, 255); text-decoration: none; font-weight: 200; position: absolute; bottom: 15px; left: 30px;">View our privacy policy here</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -38,6 +39,20 @@
|
|||
<a style="color: rgb(255, 255, 255); text-decoration: none; font-weight: 200; position: absolute; bottom: 15px; right: 30px;">Log Out</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Help Modal -->
|
||||
<div id="help-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h2>Help</h2>
|
||||
<span class="close-btn">×</span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Make sure you refresh (CTRL + Shift + R) when encountering an error:</p>
|
||||
<p>Contact support: <a href="mailto:USCBaisupport@oliver.agency">USCBaisupport@oliver.agency</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/2.1.0/showdown.min.js"></script>
|
||||
<script src="js/variables.js"></script>
|
||||
|
|
|
|||
222
js/script.js
222
js/script.js
|
|
@ -607,6 +607,201 @@ const selectTOV = (new_tov_key) => {
|
|||
document.getElementById("tov-list").classList.add("tov-list-hidden");
|
||||
};
|
||||
|
||||
const onAuthenticated = () => {
|
||||
goToCreateNewConversationsPage();
|
||||
getConversations();
|
||||
getAssistants();
|
||||
getTOVs();
|
||||
|
||||
// Ensure the send button is enabled by default
|
||||
document.getElementById("message-input").value = "";
|
||||
|
||||
document.getElementById("assistant-name-container").classList.remove("assistant-name-container-active");
|
||||
document.getElementById("assistant-name").classList.remove("assistant-name-placeholder");
|
||||
document.getElementById("assistants-list").classList.add("assistants-list-hidden");
|
||||
|
||||
document.getElementById("tov-name-container").classList.remove("tov-name-container-active");
|
||||
document.getElementById("tov-name").classList.remove("tov-name-placeholder");
|
||||
document.getElementById("tov-list").classList.add("tov-list-hidden");
|
||||
|
||||
Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear"));
|
||||
document.getElementById("chat").innerHTML += chat_message_user_new.replaceAll("{CONTENT}", md_converter?.makeHtml(message));
|
||||
|
||||
// Scroll to Last Message
|
||||
document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight;
|
||||
|
||||
setTimeout(() => {
|
||||
Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear"));
|
||||
|
||||
document.getElementById("chat").innerHTML += chat_message_assistant_loading_dots;
|
||||
|
||||
setTimeout(() => {
|
||||
// Scroll to Last Message
|
||||
document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight;
|
||||
}, 5);
|
||||
}, 2000);
|
||||
|
||||
//console.log("URI encoded message: " + encodeURI(message));
|
||||
|
||||
|
||||
const utf8Bytes = new TextEncoder().encode(message);
|
||||
let binary = '';
|
||||
for (let i = 0; i < utf8Bytes.length; i++) {
|
||||
binary += String.fromCharCode(utf8Bytes[i]);
|
||||
}
|
||||
const encodedMessage = btoa(binary);
|
||||
|
||||
// Function to make the API call (so we can retry it)
|
||||
const makeAPICall = (retryCount = 0) => {
|
||||
return gcp_fetch(
|
||||
make_url +
|
||||
`?ConversationID=${encodeURI(conversation_id)}&AssistantKey=${encodeURI(new_assistant_key)}&TOV_Key=${encodeURI(
|
||||
new_tov_key
|
||||
)}&Message=${encodeURIComponent(encodedMessage)}`
|
||||
)
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
throw new Error(`Server responded with status: ${res.status} ${res.statusText}`);
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.then((res) => {
|
||||
if (sending_message && res?.conversation_id) {
|
||||
conversation_id = res?.conversation_id;
|
||||
|
||||
if (conversations.findIndex((e) => e.id === res?.conversation_id) === -1 && res?.conversation_title) {
|
||||
conversations = [
|
||||
{ id: res?.conversation_id, title: res?.conversation_title, assistant_key: new_assistant_key, tov_key: new_tov_key },
|
||||
].concat(conversations);
|
||||
|
||||
document.getElementById("conversations-list").innerHTML = conversations
|
||||
?.map((conversation) => {
|
||||
if (conversation?.id === res?.conversation_id)
|
||||
return conversations_list_item_active
|
||||
?.replaceAll("{CONVERSATION_ID}", conversation?.id)
|
||||
?.replaceAll("{CONVERSATION_TITLE}", processConversationTitle(conversation?.title));
|
||||
return conversations_list_item
|
||||
?.replaceAll("{CONVERSATION_ID}", conversation?.id)
|
||||
?.replaceAll("{CONVERSATION_TITLE}", processConversationTitle(conversation?.title));
|
||||
})
|
||||
?.join("");
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable the send button
|
||||
document.getElementById("send-button").disabled = false;
|
||||
|
||||
sending_message = false;
|
||||
Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear"));
|
||||
Array.from(document.getElementsByClassName("chat-message-loading-dots"))?.map((el) => el.remove());
|
||||
|
||||
// Check if we have a message, otherwise show error
|
||||
if (res?.message) {
|
||||
document.getElementById("chat").innerHTML += chat_message_assistant_new.replaceAll("{CONTENT}", md_converter?.makeHtml(removeCitations(res.message)));
|
||||
} else {
|
||||
document.getElementById("chat").innerHTML += chat_message_assistant_new.replaceAll("{CONTENT}", "Sorry, there was an issue processing your request. The response was incomplete.");
|
||||
}
|
||||
|
||||
// Scroll to Last Message
|
||||
document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(`Error in API call (attempt ${retryCount + 1}):`, error);
|
||||
|
||||
// If this is the first failure, retry once
|
||||
if (retryCount === 0) {
|
||||
console.log("Retrying request...");
|
||||
|
||||
// Keep loading indicator
|
||||
// Don't remove the loading dots yet
|
||||
|
||||
// Wait a moment before retrying (e.g., 1 second)
|
||||
return new Promise(resolve => setTimeout(resolve, 1000))
|
||||
.then(() => makeAPICall(retryCount + 1));
|
||||
}
|
||||
|
||||
// If we've already retried or max retries reached, show the error
|
||||
// Re-enable the send button
|
||||
document.getElementById("send-button").disabled = false;
|
||||
|
||||
sending_message = false;
|
||||
Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear"));
|
||||
Array.from(document.getElementsByClassName("chat-message-loading-dots"))?.map((el) => el.remove());
|
||||
|
||||
// Show error message in chat
|
||||
document.getElementById("chat").innerHTML += chat_message_assistant_new.replaceAll(
|
||||
"{CONTENT}",
|
||||
`<div class="error-message">Sorry, an error occurred: ${error.message}</div>`
|
||||
);
|
||||
|
||||
// Scroll to Last Message
|
||||
document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight;
|
||||
});
|
||||
};
|
||||
|
||||
// Start the API call with retry functionality
|
||||
makeAPICall();
|
||||
};
|
||||
|
||||
const toggleAssistantsDropdown = () => {
|
||||
if (conversation_id !== false || sending_message) return false;
|
||||
|
||||
if (Array.from(document.getElementById("assistants-list").classList).includes("assistants-list-hidden")) {
|
||||
document.getElementById("assistant-name-container").classList.add("assistant-name-container-active");
|
||||
document.getElementById("assistants-list").classList.remove("assistants-list-hidden");
|
||||
} else {
|
||||
document.getElementById("assistant-name-container").classList.remove("assistant-name-container-active");
|
||||
document.getElementById("assistants-list").classList.add("assistants-list-hidden");
|
||||
}
|
||||
};
|
||||
|
||||
const selectAssistant = (new_assistant_key) => {
|
||||
if (conversation_id !== false || sending_message) return false;
|
||||
|
||||
const assistant = assistants?.find((e) => e.key === new_assistant_key);
|
||||
if (!assistant) return false;
|
||||
|
||||
assistant_key = new_assistant_key;
|
||||
|
||||
document.getElementById("assistant-name").innerHTML = assistants.find((e) => e.key === new_assistant_key)?.name;
|
||||
document.getElementById("assistant-name-container").classList.remove("assistant-name-container-active");
|
||||
document.getElementById("assistant-name").classList.remove("assistant-name-placeholder");
|
||||
document.getElementById("assistants-list").classList.add("assistants-list-hidden");
|
||||
|
||||
document.getElementById("chat").innerHTML = ``;
|
||||
setTimeout(() => {
|
||||
if (JSON.stringify(assistant_key) === JSON.stringify(new_assistant_key)) {
|
||||
document.getElementById("chat").innerHTML = chat_message_assistant_new.replaceAll("{CONTENT}", assistant?.initial_message);
|
||||
}
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const toggleTOVsDropdown = () => {
|
||||
if (conversation_id !== false || sending_message) return false;
|
||||
|
||||
if (Array.from(document.getElementById("tov-list").classList).includes("tov-list-hidden")) {
|
||||
document.getElementById("tov-name-container").classList.add("tov-name-container-active");
|
||||
document.getElementById("tov-list").classList.remove("tov-list-hidden");
|
||||
} else {
|
||||
document.getElementById("tov-name-container").classList.remove("tov-name-container-active");
|
||||
document.getElementById("tov-list").classList.add("tov-list-hidden");
|
||||
}
|
||||
};
|
||||
|
||||
const selectTOV = (new_tov_key) => {
|
||||
if (conversation_id !== false || sending_message) return false;
|
||||
|
||||
const tov = tone_of_voices?.find((e) => e.key === new_tov_key);
|
||||
if (!tov) return false;
|
||||
|
||||
tov_key = new_tov_key;
|
||||
|
||||
document.getElementById("tov-name").innerHTML = tone_of_voices.find((e) => e.key === new_tov_key)?.name;
|
||||
document.getElementById("tov-name-container").classList.remove("tov-name-container-active");
|
||||
document.getElementById("tov-name").classList.remove("tov-name-placeholder");
|
||||
document.getElementById("tov-list").classList.add("tov-list-hidden");
|
||||
};
|
||||
|
||||
const onAuthenticated = () => {
|
||||
goToCreateNewConversationsPage();
|
||||
getConversations();
|
||||
|
|
@ -620,4 +815,29 @@ const onAuthenticated = () => {
|
|||
sendButton.disabled = false;
|
||||
}
|
||||
}, 500); // Small delay to ensure DOM is ready
|
||||
};
|
||||
};
|
||||
|
||||
// Help Modal Functionality
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const modal = document.getElementById("help-modal");
|
||||
const btn = document.getElementById("help-btn");
|
||||
const span = document.getElementsByClassName("close-btn")[0];
|
||||
|
||||
if (btn) {
|
||||
btn.onclick = function() {
|
||||
modal.style.display = "flex";
|
||||
}
|
||||
}
|
||||
|
||||
if (span) {
|
||||
span.onclick = function() {
|
||||
modal.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
window.onclick = function(event) {
|
||||
if (event.target == modal) {
|
||||
modal.style.display = "none";
|
||||
}
|
||||
}
|
||||
});
|
||||
96
style.css
96
style.css
|
|
@ -652,3 +652,99 @@ button:disabled {
|
|||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Help Button */
|
||||
.help-btn {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 30px;
|
||||
background-color: #0079E8;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.help-btn:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
/* Modal Styles */
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 3000;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: #fefefe;
|
||||
margin: auto;
|
||||
padding: 0;
|
||||
border: 1px solid #888;
|
||||
width: 80%;
|
||||
max-width: 600px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
animation-name: animatetop;
|
||||
animation-duration: 0.4s
|
||||
}
|
||||
|
||||
@keyframes animatetop {
|
||||
from {top: -300px; opacity: 0}
|
||||
to {top: 0; opacity: 1}
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
padding: 15px 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal-header h2 {
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
color: #aaa;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.close-btn:hover,
|
||||
.close-btn:focus {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 20px;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.modal-body a {
|
||||
color: #0079E8;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.modal-body a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue