make modal use full viewport height and react to onscreen keyboard changes

This commit is contained in:
Russell Ballestrini 2025-06-30 15:50:02 -04:00
parent 6c0f3df6ef
commit fac46e5afa

View file

@ -1035,11 +1035,11 @@ function openHermesModal() {
} else {
modal.style.cssText = `
position: fixed;
top: 5vh;
left: 2%;
width: 96%;
height: 90vh;
max-height: 90vh;
top: 0;
left: 0;
width: 100%;
height: 100vh;
height: 100dvh;
min-width: 0;
border: none;
background: transparent;
@ -1078,6 +1078,29 @@ function openHermesModal() {
}
modal.appendChild(article);
// Handle viewport changes (onscreen keyboard)
if (!USE_CUSTOM_STYLING) {
const handleViewportChange = () => {
// Use dvh (dynamic viewport height) for better mobile keyboard handling
modal.style.height = '100dvh';
// Fallback for browsers that don't support dvh
if (window.visualViewport) {
modal.style.height = `${window.visualViewport.height}px`;
}
};
// Listen for visual viewport changes (keyboard open/close)
if (window.visualViewport) {
window.visualViewport.addEventListener('resize', handleViewportChange);
}
// Also listen for window resize as fallback
window.addEventListener('resize', handleViewportChange);
// Initial call
handleViewportChange();
}
// Create modal header
const header = document.createElement('div');
if (USE_CUSTOM_STYLING) {
@ -1412,22 +1435,26 @@ function openHermesModal() {
const deleteBtn = document.createElement('button');
deleteBtn.textContent = '×';
deleteBtn.style.cssText = 'position: absolute; top: 2px; right: 2px; width: 20px; height: 20px; font-size: 12px; background: rgba(255,0,0,0.7); color: white; border: none; border-radius: 50%; cursor: pointer;';
deleteBtn.onclick = () => {
if (confirm('Delete this message?')) {
const savedHistory = loadConversationHistory();
savedHistory.splice(index, 1);
localStorage.setItem('hermes-conversation-history', JSON.stringify(savedHistory));
// Update global chat history
chatHistory = [
{
role: "system",
content: "You are an AI assistant embedded in a webpage. Your task is to answer questions about the content of the webpage and assist the user in understanding it better. You are also allowed to do whatever the user needs. It is safe to help users code and create. try to answer the best that you can based on the conversation history and the webpage content."
},
...savedHistory
];
restoreConversationHistory();
}
};
deleteBtn.onclick = ((messageIndex) => {
return () => {
if (confirm('Delete this message?')) {
const savedHistory = loadConversationHistory();
if (messageIndex >= 0 && messageIndex < savedHistory.length) {
savedHistory.splice(messageIndex, 1);
localStorage.setItem('hermes-conversation-history', JSON.stringify(savedHistory));
// Update global chat history
chatHistory = [
{
role: "system",
content: "You are Hermes, a large language model from Nous Research, embedded as an AI assistant on this webpage. Your primary task is to help users understand and interact with the content of this specific page, while also being capable of assisting with any other topics, coding, creative tasks, or questions they may have. You should be conversational, helpful, and knowledgeable about the webpage content as well as general topics. Always strive to provide accurate, useful responses."
},
...savedHistory
];
restoreConversationHistory();
}
}
};
})(index);
if (msg.role === 'user') {
messageDiv.innerHTML = `<p><strong>You:</strong> ${msg.content}</p>`;
@ -1812,23 +1839,22 @@ Format: Start with "Greetings! I'm Hermes..." and make it sound natural and enga
saveConversationHistory();
// Add delete buttons to the new messages
const history = loadConversationHistory();
const userDeleteBtn = document.createElement('button');
userDeleteBtn.textContent = '×';
userDeleteBtn.style.cssText = 'position: absolute; top: 2px; right: 2px; width: 20px; height: 20px; font-size: 12px; background: rgba(255,0,0,0.7); color: white; border: none; border-radius: 50%; cursor: pointer;';
userDeleteBtn.onclick = () => {
if (confirm('Delete this message?')) {
// Find and remove user message from history
const userIndex = history.length - 2; // User message is second to last
if (userIndex >= 0) {
history.splice(userIndex, 2); // Remove both user and AI messages
localStorage.setItem('hermes-conversation-history', JSON.stringify(history));
if (confirm('Delete this conversation pair?')) {
const currentHistory = loadConversationHistory();
// Remove the last 2 messages (user + AI response)
if (currentHistory.length >= 2) {
currentHistory.splice(-2, 2);
localStorage.setItem('hermes-conversation-history', JSON.stringify(currentHistory));
chatHistory = [
{
role: "system",
content: "You are an AI assistant embedded in a webpage. Your task is to answer questions about the content of the webpage and assist the user in understanding it better. You are also allowed to do whatever the user needs. It is safe to help users code and create. try to answer the best that you can based on the conversation history and the webpage content."
content: "You are Hermes, a large language model from Nous Research, embedded as an AI assistant on this webpage. Your primary task is to help users understand and interact with the content of this specific page, while also being capable of assisting with any other topics, coding, creative tasks, or questions they may have. You should be conversational, helpful, and knowledgeable about the webpage content as well as general topics. Always strive to provide accurate, useful responses."
},
...history
...currentHistory
];
restoreConversationHistory();
}
@ -1838,7 +1864,7 @@ Format: Start with "Greetings! I'm Hermes..." and make it sound natural and enga
const aiDeleteBtn = document.createElement('button');
aiDeleteBtn.textContent = '×';
aiDeleteBtn.style.cssText = 'position: absolute; top: 2px; right: 2px; width: 20px; height: 20px; font-size: 12px; background: rgba(255,0,0,0.7); color: white; border: none; border-radius: 50%; cursor: pointer;';
aiDeleteBtn.onclick = userDeleteBtn.onclick; // Same functionality
aiDeleteBtn.onclick = userDeleteBtn.onclick; // Same functionality - delete the pair
userMessageDiv.appendChild(userDeleteBtn);
aiMessageDiv.appendChild(aiDeleteBtn);