gbplugin/content.js

239 lines
7.2 KiB
JavaScript

// Global variables
let settings = {
serverUrl: 'https://api.pragmatismo.com.br/general-bots/process',
enableProcessing: true,
hideContacts: false
};
// Original message storage (before processing)
const originalMessages = new Map();
// Initialize the extension
function init() {
console.log('General Bots: Initializing...');
// Load settings
chrome.storage.sync.get({
serverUrl: 'https://api.pragmatismo.com.br/general-bots/process',
enableProcessing: true,
hideContacts: false
}, function(items) {
settings = items;
console.log('General Bots: Settings loaded', settings);
// Apply hide contacts if enabled
applyContactVisibility();
// Start monitoring the input field
setupInputListener();
});
}
// Apply contact list visibility based on settings
function applyContactVisibility() {
const contactList = document.querySelector('#pane-side');
if (contactList) {
if (settings.hideContacts) {
contactList.parentElement.classList.add('gb-hide-contacts');
} else {
contactList.parentElement.classList.remove('gb-hide-contacts');
}
}
}
// Setup input field listener
function setupInputListener() {
// The main input field where users type messages
const inputSelector = 'div[contenteditable="true"][data-tab="10"]';
// Use MutationObserver to detect when the input field appears
const observer = new MutationObserver(mutations => {
const inputField = document.querySelector(inputSelector);
if (inputField && !inputField.getAttribute('gb-monitored')) {
setupFieldMonitoring(inputField);
inputField.setAttribute('gb-monitored', 'true');
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// Also check immediately in case the field is already present
const inputField = document.querySelector(inputSelector);
if (inputField && !inputField.getAttribute('gb-monitored')) {
setupFieldMonitoring(inputField);
inputField.setAttribute('gb-monitored', 'true');
}
}
// Setup monitoring for a specific input field
function setupFieldMonitoring(inputField) {
console.log('General Bots: Setting up input field monitoring');
// Listen for keydown events (Enter key)
inputField.addEventListener('keydown', async (event) => {
if (event.key === 'Enter' && !event.shiftKey && settings.enableProcessing) {
const originalText = inputField.textContent;
// Only process if there's actual text
if (originalText.trim().length > 0) {
// Prevent default Enter behavior temporarily
event.preventDefault();
try {
// Process message with server
const processedText = await processMessage(originalText);
// Replace text in the input field
inputField.textContent = processedText;
// Store original message for reference
const timestamp = Date.now();
originalMessages.set(timestamp, {
original: originalText,
processed: processedText
});
// Simulate Enter press to send the message
simulateEnterPress(inputField);
// Track the message to update it after sending
trackSentMessage(timestamp);
} catch (error) {
console.error('General Bots: Error processing message', error);
// Let the original message be sent if there's an error
simulateEnterPress(inputField);
}
}
}
});
}
// Process message with server
async function processMessage(text) {
console.log('General Bots: Processing message with server');
try {
const response = await fetch(settings.serverUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: text,
timestamp: Date.now()
})
});
if (!response.ok) {
throw new Error(`Server responded with status: ${response.status}`);
}
const data = await response.json();
return data.processedText || text;
} catch (error) {
console.error('General Bots: Failed to process message', error);
return text; // Return original text if processing fails
}
}
// Simulate Enter key press
function simulateEnterPress(element) {
const enterEvent = new KeyboardEvent('keydown', {
key: 'Enter',
code: 'Enter',
keyCode: 13,
which: 13,
bubbles: true
});
element.dispatchEvent(enterEvent);
}
// Track sent message to update it after sending
function trackSentMessage(timestamp) {
// Monitor for the message to appear in the chat
const observer = new MutationObserver(mutations => {
// Look for recently sent messages
const messageContainers = document.querySelectorAll('.message-out');
if (messageContainers.length > 0) {
// Get the last sent message
const lastMessage = messageContainers[messageContainers.length - 1];
// Check if this message has our data
if (!lastMessage.getAttribute('gb-processed')) {
// Get message info
const messageInfo = originalMessages.get(timestamp);
if (messageInfo) {
// Mark as processed
lastMessage.setAttribute('gb-processed', timestamp);
// Update message text if different from original
if (messageInfo.original !== messageInfo.processed) {
updateSentMessageDisplay(lastMessage, messageInfo);
}
// Clean up
setTimeout(() => {
originalMessages.delete(timestamp);
}, 60000); // Remove after 1 minute
// Stop observing
observer.disconnect();
}
}
}
});
// Start observing chat container
const chatContainer = document.querySelector('.copyable-area');
if (chatContainer) {
observer.observe(chatContainer, {
childList: true,
subtree: true
});
// Stop observing after a reasonable timeout
setTimeout(() => {
observer.disconnect();
}, 10000); // 10 seconds timeout
}
}
// Update the displayed message after sending
function updateSentMessageDisplay(messageElement, messageInfo) {
const textElement = messageElement.querySelector('.selectable-text');
if (textElement) {
// Create a small indicator that the message was processed
const indicator = document.createElement('div');
indicator.className = 'gb-processed-indicator';
indicator.title = `Original: "${messageInfo.original}"`;
indicator.textContent = '✓ AI processed';
// Add the indicator to the message
messageElement.appendChild(indicator);
// Add tooltip behavior
messageElement.classList.add('gb-processed-message');
}
}
// Listen for messages from popup or background
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'settingsUpdated') {
settings = message.settings;
applyContactVisibility();
console.log('General Bots: Settings updated', settings);
} else if (message.action === 'tabReady') {
init();
}
return true;
});
// Initialize on load
document.addEventListener('DOMContentLoaded', init);
// Also try to initialize now in case the page is already loaded
init();