`;
document.body.insertAdjacentHTML('beforeend', formHtml);
document.getElementById('saveEditedQuickReply').addEventListener('click', () => {
const label = document.getElementById('editQuickReplyLabel').value.trim();
const message = document.getElementById('editQuickReplyMessage').value.trim();
if (!label) {
alert('Button Label cannot be empty.');
return;
}
config.replies[index].label = label;
config.replies[index].message = message;
renderQuickRepliesList(config);
closeEditQuickReplyForm();
});
const closeForm = () => {
document.getElementById('editQuickReplyForm')?.remove();
};
document.getElementById('cancelEditedQuickReply').addEventListener('click', closeForm);
document.getElementById('closeEditQuickReplyForm').addEventListener('click', closeForm);
}
// --- Quick Reply Button Generation and Injection ---
function addQuickButtons() {
// Check for the presence of a quick reply wrapper, remove if it exists to prevent duplicates
let existingWrapper = document.getElementById('quickReplyWrapper');
if (existingWrapper) {
existingWrapper.remove();
}
const targetContainer = document.querySelector('div.chakra-form-control.css-1kxonj9');
if (!targetContainer) return;
const wrapper = document.createElement('div');
wrapper.id = 'quickReplyWrapper';
wrapper.style.cssText = `
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 14px;
padding-left: 2px;
align-items: left;
max-width: ${MAX_WRAPPER_WIDTH}px;
`;
const config = loadQuickRepliesConfig();
config.replies.forEach((reply) => {
const btn = document.createElement('button');
btn.textContent = reply.label;
btn.style.cssText = `
color: #a855f7;
background: none;
cursor: pointer;
font-size: 0.85em;
padding: 4px 10px;
border: none;
border-radius: 6px;
transition: all 0.2s ease;
white-space: nowrap;
`;
btn.addEventListener('mouseover', () => {
btn.style.textDecoration = 'underline';
});
btn.addEventListener('mouseout', () => {
btn.style.textDecoration = 'none';
});
btn.addEventListener('click', (e) => {
e.stopPropagation();
const textarea = document.querySelector('textarea[aria-label="Send message textarea"]');
if (textarea) { // Only check for the textarea's presence initially
dispatchReactInput(textarea, reply.message); // Write the text into the textarea
// Now, after the text is entered, look for the send button and click it
// We use a small timeout to give the UI a moment to update and show the send button
setTimeout(() => {
const sendButton = document.querySelector('button[aria-label="Send message"]');
if (sendButton) {
sendButton.click();
} else {
console.warn("Kindroid Quick Reply: Send button not found after text input. (This is expected if the button doesn't appear for a short while)");
}
}, 100); // Increased timeout slightly to 100ms for better reliability
} else {
console.warn("Kindroid Quick Reply: Textarea not found.");
}
});
wrapper.appendChild(btn);
});
targetContainer.appendChild(wrapper);
}
// Function to be called after config changes to re-render UI buttons
function updateQuickButtons() {
addQuickButtons(); // This will remove existing and re-add from current config
GM_setValue(QUICK_REPLIES_ADDED_FLAG, 'true'); // Flag that buttons are set up
}
function waitForChatBoxAndInject() {
const interval = setInterval(() => {
const container = document.querySelector('div.chakra-form-control.css-1kxonj9');
// NEW REQUIREMENT: Check for the presence of the voice mode button
const voiceModeButton = document.querySelector('button[aria-label="enter voice mode"]');
if (container && voiceModeButton) { // Modified condition: both container and voice mode button must be present
clearInterval(interval);
updateQuickButtons(); // Use the update function to ensure latest config
}
}, 500);
}
// Handle SPA navigation (pushState, popState)
const originalPushState = history.pushState;
history.pushState = function () {
originalPushState.apply(this, arguments);
setTimeout(waitForChatBoxAndInject, 500);
};
window.addEventListener('popstate', () => {
setTimeout(waitForChatBoxAndInject, 500);
});
// Initial injection
waitForChatBoxAndInject();
// MutationObserver to reinject if buttons disappear (e.g., due to page changes)
const liveObserver = new MutationObserver(() => {
const inputPresent = document.querySelector('div.chakra-form-control.css-1kxonj9');
const wrapperPresent = document.getElementById('quickReplyWrapper');
// Ensure the voice mode button is also present before reinjecting
const voiceModeButtonPresent = document.querySelector('button[aria-label="enter voice mode"]');
if (inputPresent && !wrapperPresent && voiceModeButtonPresent) { // Modified condition for reinjection
updateQuickButtons(); // Use the update function
}
});
liveObserver.observe(document.body, {
childList: true,
subtree: true
});
// Register menu command to open manager
GM_registerMenuCommand('Manage Quick Replies', showQuickReplyManager);
// Listen for storage changes in case another tab/window updates the config
GM_addValueChangeListener(QUICK_REPLIES_CONFIG_KEY, (key, oldValue, newValue) => {
updateQuickButtons(); // Re-render buttons if config changes
});
})();