您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A toggleable panel with information about the character and other stuff
// ==UserScript== // @name c.ai Neo Panel // @namespace c.ai Neo Panel // @version 3.2 // @description A toggleable panel with information about the character and other stuff // @author vishanka // @license MIT // @match https://*.character.ai/chat* // @icon https://i.imgur.com/iH2r80g.png // @grant none // ==/UserScript== (function() { 'use strict'; var original_prototype_open = XMLHttpRequest.prototype.open; const intercepted_data_object = {}; XMLHttpRequest.prototype.open = function(method, url, async) { if ( url.startsWith('https://plus.character.ai/chat/history/continue/') || url.startsWith('https://plus.character.ai/chat/character/info') || url.startsWith('https://beta.character.ai/chat/history/continue/') || url.startsWith('https://beta.character.ai/chat/character/info') ) { this.addEventListener('load', function() { let info1 = JSON.parse(this.responseText); intercepted_data_object.external_id = info1.character.external_id; console.log("character_id:",intercepted_data_object.external_id); let info2 = JSON.parse(this.responseText); intercepted_data_object.tgt = info2.character.participant__user__username; intercepted_data_object.name = info2.character.name; intercepted_data_object.participant__num_interactions = info2.character.participant__num_interactions; intercepted_data_object.greeting = info2.character.greeting; intercepted_data_object.title = info2.character.title; intercepted_data_object.description = info2.character.description; intercepted_data_object.avatar_file_name = info2.character.avatar_file_name; intercepted_data_object.base_img_prompt = info2.character.base_img_prompt; intercepted_data_object.visibility = info2.character.visibility; intercepted_data_object.username = info2.character.user__username; // Only create the toggle button and the panel once if (!document.getElementById('descriptionPanel')) { createToggleButton(); createPermanentPanel(); createNeoPanelDelete(); } }); } else if (url.startsWith(`https://neo.character.ai/chats/recent/${intercepted_data_object.external_id}`)) { this.addEventListener('load', function() { let info3 = JSON.parse(this.responseText); intercepted_data_object.chat_id = info3.chats[0].chat_id; console.log("chat_id:",intercepted_data_object.chat_id); }); } else if (url.startsWith('https://beta.character.ai/chat/user/') || url.startsWith('https://plus.character.ai/chat/user/') ) { this.addEventListener('load', function() { let info_user = JSON.parse(this.responseText); intercepted_data_object.info_username = info_user.user.name; console.log("Username You:",intercepted_data_object.info_username); }); } else if (url.startsWith(`https://neo.character.ai/turns/${intercepted_data_object.chat_id}`)) { this.addEventListener('load', function() { let info4 = JSON.parse(this.responseText); intercepted_data_object.turn_id = info4.turns[0].turn_key.turn_id; intercepted_data_object.total_turns = info4.turns.length; intercepted_data_object.turns_name = info4.turns[0].author.name; console.log("turn_id:",intercepted_data_object.turn_id); console.log("total_turns:", intercepted_data_object.total_turns); console.log("turns_name:", intercepted_data_object.turns_name); // Extract data from the last turn_id if there are turns if (intercepted_data_object.total_turns > 0) { const lastTurnIndex = intercepted_data_object.total_turns - 1; const lastTurnData = info4.turns[lastTurnIndex]; intercepted_data_object.lastTurnId = lastTurnData.turn_key.turn_id; // Store lastTurnId in intercepted_data_object console.log("Last turn_id:", intercepted_data_object.lastTurnId); } // Extract candidates for "turn 0", used for fetching limit if (intercepted_data_object.total_turns > 0) { const firstTurnData = info4.turns[0]; intercepted_data_object.candidatesForTurn0 = firstTurnData.candidates; intercepted_data_object.numberOfCandidatesForTurn0 = intercepted_data_object.candidatesForTurn0.length; console.log("Number of candidates for turn 0:", intercepted_data_object.numberOfCandidatesForTurn0); if (intercepted_data_object.numberOfCandidatesForTurn0 > 0) { intercepted_data_object.first_raw = intercepted_data_object.candidatesForTurn0[0].raw_content; console.log("Raw content of the first candidate for turn 0:", intercepted_data_object.first_raw); } } XHR_interception_resolve(intercepted_data_object); }); } original_prototype_open.apply(this, [method, url, async]); }; let XHR_interception_resolve; const XHR_interception_promise = new Promise(function(resolve, reject) { XHR_interception_resolve = resolve; }); XHR_interception_promise.then(function() { console.log("Intercepted Data:", intercepted_data_object); // Fetch Command const fetch10_commandJson = `{ "command": "generate_turn_candidate", "payload": { "character_id": "${intercepted_data_object.external_id}", "turn_key": { "turn_id": "${intercepted_data_object.turn_id}", "chat_id": "${intercepted_data_object.chat_id}" } }, "origin_id": "" }`; // Delete First Message const delete_first_commandJson = `{ "command": "remove_turns", "request_id": "", "payload": { "chat_id": "${intercepted_data_object.chat_id}", "turn_ids": ["${intercepted_data_object.lastTurnId}"] }, "origin_id": "" }`; const delete_last_commandJson = `{ "command": "remove_turns", "request_id": "", "payload": { "chat_id": "${intercepted_data_object.chat_id}", "turn_ids": ["${intercepted_data_object.turn_id}"] }, "origin_id": "" }`; // Rest of the WebSocket logic (same as in your original script) // Create Fetch Button let disableMouseOut = false; const fetch_button = document.createElement('button'); fetch_button.textContent = 'Fetch 10 Replies'; fetch_button.style.padding = '5px 10px'; fetch_button.style.backgroundColor = '#007bff'; fetch_button.style.borderRadius = '5px'; fetch_button.style.color = 'white'; fetch_button.style.border = 'none'; fetch_button.style.cursor = 'pointer'; fetch_button.style.transition = 'background-color 0.2s, transform 0.1s'; fetch_button.style.display = 'block'; fetch_button.style.width = '100%'; fetch_button.style.marginTop = '10px'; // Mouseover animation fetch_button.addEventListener('mouseover', () => { fetch_button.style.backgroundColor = '#0056b3'; fetch_button.style.transform = 'scale(1.0)'; }); // Mouseout animation fetch_button.addEventListener('mouseout', () => { if (!disableMouseOut) { fetch_button.style.backgroundColor = '#007bff'; fetch_button.style.transform = 'scale(1)'; } }); // Click animation and logic fetch_button.addEventListener('click', () => { // Change button text and background color fetch_button.textContent = 'Please wait...'; fetch_button.style.backgroundColor = 'darkgray'; fetch_button.disabled = true; // Disable the button during fetching disableMouseOut = true; // Disable mouseout behavior fetch10(); }); // Create Delete First Button const delete_first_message_button = createStyledButton('Delete First Message', showDeleteConfirmation); delete_first_message_button.style.marginTop = '10px'; // Create Delete Last Button const delete_last_message_button = createStyledButton('Delete Last Message', showDeleteLastConfirmation); delete_last_message_button.style.marginTop = '10px'; //----------------------------------------- BUTTON FOR DELETE PANEL ---------------------------------------- // Triggert Panel aus Neo Panel Delete script const delete_panel_button = createStyledButton('Toggle Delete Panel', toggleNeoPanelDelete); delete_panel_button.style.marginTop = '10px'; // Append Buttons to Panel const panel = document.getElementById('descriptionPanel'); panel.appendChild(fetch_button); panel.appendChild(delete_first_message_button); panel.appendChild(delete_last_message_button); panel.appendChild(delete_panel_button); //panel.appendChild(delete_last_message_button); // Add reload_information to the panel const general_information = document.createElement('p'); general_information.textContent = 'Version 3.1'; general_information.style.textAlign = 'center'; general_information.style.marginBottom = '5px'; general_information.style.setProperty('font-size', '12px', 'important'); // Set style with !important panel.appendChild(general_information); // Add home button to the panel /* const home_button = document.createElement('img'); home_button.style.maxWidth = '15%'; home_button.style.display = 'block'; // Ensures that the image occupies full width home_button.style.margin = '0 auto'; // Centers the image horizontally home_button.style.marginBottom = '10px'; home_button.src = 'https://i.imgur.com/79IBd1P.png'; panel.appendChild(home_button); */ // Function to create styled buttons function createStyledButton(text, clickFunction) { const button = document.createElement('button'); button.textContent = text; button.style.padding = '5px 10px'; button.style.backgroundColor = '#007bff'; button.style.borderRadius = '5px'; button.style.color = 'white'; button.style.border = 'none'; button.style.cursor = 'pointer'; button.style.transition = 'background-color 0.2s, transform 0.1s'; button.style.display = 'block'; button.style.width = '100%'; // Mouseover animation button.addEventListener('mouseover', () => { button.style.backgroundColor = '#0056b3'; }); // Mouseout animation button.addEventListener('mouseout', () => { button.style.backgroundColor = '#007bff'; }); // Click animation and logic button.addEventListener('click', () => { clickFunction(); button.style.backgroundColor = 'darkgray'; }); return button; } //--------------------------Here begins the fetching craze ------------------------------- // Initialize WebSocket const socket = new WebSocket('wss://neo.character.ai/ws/'); socket.addEventListener('open', () => { console.log('Socket connection opened.'); }); socket.addEventListener('error', (error) => { console.error('Socket error:', error); }); socket.addEventListener('close', () => { console.log('Socket connection closed.'); }); let lastWebSocketMessageTime = 0; let fetchAlertTimeout; // Function to handle WebSocket messages function handleWebSocketMessage() { lastWebSocketMessageTime = Date.now(); if (fetchAlertTimeout) { clearTimeout(fetchAlertTimeout); } fetchAlertTimeout = setTimeout(() => { if (shouldShowFetchAlert()) { const maxCandidates = 31; const remainingCandidates = maxCandidates - intercepted_data_object.numberOfCandidatesForTurn0; const candidatesToFetch = Math.min(remainingCandidates, 10); if (candidatesToFetch > 0) { // Create a custom modal_fetched_messages const modal_fetched_messages = document.createElement('div'); modal_fetched_messages.style.position = 'fixed'; modal_fetched_messages.style.top = '0'; modal_fetched_messages.style.left = '0'; modal_fetched_messages.style.width = '100%'; modal_fetched_messages.style.height = '100%'; modal_fetched_messages.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; modal_fetched_messages.style.display = 'flex'; modal_fetched_messages.style.justifyContent = 'center'; modal_fetched_messages.style.alignItems = 'center'; modal_fetched_messages.style.zIndex = '9999'; // Set a higher z-index // Create modal_fetched_messages content const modal_fetched_messagesContent = document.createElement('div'); modal_fetched_messagesContent.style.backgroundColor = '#fff'; modal_fetched_messagesContent.style.padding = '20px'; modal_fetched_messagesContent.style.borderRadius = '5px'; modal_fetched_messagesContent.style.textAlign = 'center'; // Add content to modal_fetched_messages const modal_fetched_messagesText = document.createElement('div'); modal_fetched_messagesText.textContent = `${candidatesToFetch} messages fetched. Click below to reload the page.`; modal_fetched_messagesText.style.marginBottom = '20px'; modal_fetched_messagesContent.appendChild(modal_fetched_messagesText); // Create a button within the modal_fetched_messages const reloadButton = document.createElement('button'); reloadButton.textContent = 'Reload Page'; reloadButton.style.backgroundColor = '#3E4040'; // Example button color reloadButton.style.color = 'white'; // Example text color reloadButton.style.border = 'none'; reloadButton.style.borderRadius = '3px'; reloadButton.style.padding = '5px 15px'; // Add an event listener to the reload button reloadButton.addEventListener('click', () => { window.location.reload(); // Reload the page }); // Add button to modal_fetched_messages content modal_fetched_messagesContent.appendChild(reloadButton); // Add modal_fetched_messages content to modal_fetched_messages modal_fetched_messages.appendChild(modal_fetched_messagesContent); // Add modal_fetched_messages to the document document.body.appendChild(modal_fetched_messages); } } }, 10000); } // Function to determine if the fetch alert should be shown function shouldShowFetchAlert() { const currentTime = Date.now(); const timeSinceLastMessage = currentTime - lastWebSocketMessageTime; return timeSinceLastMessage >= 10000; } // Function to determine if the fetch alert should be shown function fetch10() { const maxCandidates = 31; const command = JSON.parse(fetch10_commandJson); if (intercepted_data_object.info_username === intercepted_data_object.turns_name) { // ------------------- Create an extra Style for the User Message Popup const modal_user_message = document.createElement('div'); modal_user_message.style.position = 'fixed'; modal_user_message.style.top = '0'; modal_user_message.style.left = '0'; modal_user_message.style.width = '100%'; modal_user_message.style.height = '100%'; modal_user_message.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; modal_user_message.style.display = 'flex'; modal_user_message.style.justifyContent = 'center'; modal_user_message.style.alignItems = 'center'; modal_user_message.style.zIndex = '9999'; // Set a higher z-index // Create modal_user_message content const modal_user_messageContent = document.createElement('div'); modal_user_messageContent.style.backgroundColor = '#fff'; modal_user_messageContent.style.padding = '20px'; modal_user_messageContent.style.borderRadius = '5px'; modal_user_messageContent.style.textAlign = 'center'; // Add content to modal_user_message const modal_user_messageText = document.createElement('div'); modal_user_messageText.textContent = `You tried to fetch on a user message. Reload or generate a reply.`; modal_user_messageText.style.marginBottom = '20px'; modal_user_messageContent.appendChild(modal_user_messageText); // Create reload button const reloadButton = document.createElement('button'); reloadButton.textContent = 'Reload Page'; reloadButton.style.marginRight = '10px'; reloadButton.style.backgroundColor = 'red'; // Example button color reloadButton.style.color = 'white'; // Example text color reloadButton.style.border = 'none'; reloadButton.style.borderRadius = '3px'; reloadButton.style.padding = '5px 15px'; // Add event listener to reload button reloadButton.addEventListener('click', () => { window.location.reload(); // Reload the page }); // Create cancel button const cancelButton = document.createElement('button'); cancelButton.textContent = 'Cancel'; cancelButton.style.backgroundColor = '#DDDDDD'; // Example button color cancelButton.style.border = 'none'; cancelButton.style.borderRadius = '3px'; cancelButton.style.padding = '5px 15px'; // Add event listener to cancel button cancelButton.addEventListener('click', () => { modal_user_message.remove(); // Remove the modal fetch_button.textContent = 'Fetch 10 Replies'; fetch_button.style.backgroundColor = '#007bff'; }); // Add buttons to modal_user_message content modal_user_messageContent.appendChild(reloadButton); modal_user_messageContent.appendChild(cancelButton); // Add modal_user_message content to modal_user_message modal_user_message.appendChild(modal_user_messageContent); // Add modal_user_message to the document document.body.appendChild(modal_user_message); // ------------------- END Create an extra Style for the User Message Popup fetch_button.textContent = 'Reload Page Please'; fetch_button.disabled = false; // Disable the button during fetching disableMouseOut = true; // Disable mouseout behavior } else { proceedWithFetch(); observer.disconnect(); // Disconnect the observer after finding the text const observer = new MutationObserver(performTextSearch); observer.observe(document, { subtree: true, childList: true }); } } // Function to proceed with the fetch logic function proceedWithFetch() { const maxCandidates = 31; const command = JSON.parse(fetch10_commandJson); if (intercepted_data_object.numberOfCandidatesForTurn0 < maxCandidates) { const remainingCandidates = maxCandidates - intercepted_data_object.numberOfCandidatesForTurn0; const candidatesToFetch = Math.min(remainingCandidates, 10); for (let i = 0; i < candidatesToFetch; i++) { sendSocketMessage(socket, command, false); } } else { clearTimeout(fetchAlertTimeout); // Clear the timeout here // Create a custom modal const modal = document.createElement('div'); modal.style.position = 'fixed'; modal.style.top = '0'; modal.style.left = '0'; modal.style.width = '100%'; modal.style.height = '100%'; modal.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; modal.style.display = 'flex'; modal.style.justifyContent = 'center'; modal.style.alignItems = 'center'; modal.style.zIndex = '9999'; const modalContent = document.createElement('div'); modalContent.style.backgroundColor = '#fff'; modalContent.style.padding = '20px'; modalContent.style.borderRadius = '5px'; modalContent.style.textAlign = 'center'; const modalText = document.createElement('div'); modalText.innerHTML = 'Max swipes reached.<br>Messages fetched beyond this point will be unavailable.<br><br>Proceed?'; modalContent.appendChild(modalText); const yesButton = document.createElement('button'); yesButton.textContent = 'Confirm'; yesButton.style.marginRight = '10px'; yesButton.style.backgroundColor = 'red'; // Example button color yesButton.style.color = 'white'; // Example text color yesButton.style.border = 'none'; yesButton.style.borderRadius = '3px'; yesButton.style.padding = '5px 15px'; yesButton.style.marginTop = '10px'; let activityTimeout; let candidatesToFetch = 10; // You need to set this value const modal_yes_fetch = createModal(); function createModal() { const modal = document.createElement('div'); modal.style.position = 'fixed'; modal.style.top = '0'; modal.style.left = '0'; modal.style.width = '100%'; modal.style.height = '100%'; modal.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; modal.style.display = 'flex'; modal.style.justifyContent = 'center'; modal.style.alignItems = 'center'; modal.style.zIndex = '9999'; const modalContent = document.createElement('div'); modalContent.style.backgroundColor = '#fff'; modalContent.style.padding = '20px'; modalContent.style.borderRadius = '5px'; modalContent.style.textAlign = 'center'; const modalText = document.createElement('div'); modalText.textContent = `${candidatesToFetch} messages fetched. Click below to reload the page.`; modalText.style.marginBottom = '20px'; modalContent.appendChild(modalText); const reloadButton = document.createElement('button'); reloadButton.textContent = 'Reload Page'; reloadButton.style.marginRight = '10px'; reloadButton.style.backgroundColor = '#3E4040'; // Example button color reloadButton.style.color = 'white'; // Example text color reloadButton.style.border = 'none'; reloadButton.style.borderRadius = '3px'; reloadButton.style.padding = '5px 15px'; reloadButton.addEventListener('click', () => { window.location.reload(); }); modalContent.appendChild(reloadButton); modal.appendChild(modalContent); return modal; } yesButton.addEventListener('click', () => { document.body.removeChild(modal); fetch_button.textContent = 'Please wait...'; fetch_button.style.backgroundColor = 'darkgray'; fetch_button.disabled = true; // Disable the button during fetching disableMouseOut = true; // Disable mouseout behavior clearTimeout(activityTimeout); for (let i = 0; i < candidatesToFetch; i++) { sendSocketMessage(socket, command, false); } activityTimeout = setTimeout(() => { document.body.appendChild(modal_yes_fetch); }, 10000); }); socket.addEventListener('message', () => { clearTimeout(activityTimeout); activityTimeout = setTimeout(() => { document.body.appendChild(modal_yes_fetch); }, 10000); }); const noButton = document.createElement('button'); noButton.textContent = 'Cancel'; noButton.style.backgroundColor = 'gray'; // Example button color noButton.style.color = 'white'; // Example text color noButton.style.border = 'none'; noButton.style.borderRadius = '3px'; noButton.style.padding = '5px 15px'; noButton.addEventListener('click', () => { document.body.removeChild(modal); }); modalContent.appendChild(yesButton); modalContent.appendChild(noButton); modal.appendChild(modalContent); document.body.appendChild(modal); fetch_button.textContent = 'Fetch 10 Replies'; fetch_button.style.backgroundColor = '#007bff'; fetch_button.disabled = false; disableMouseOut = false; } } // Attach message event listener to the WebSocket socket.addEventListener('message', handleWebSocketMessage); //------------------------------------ END OF FETCHING FUNCTION------------------------------------ //------------------------------------ START OF DELETE FIRST FUNCTION------------------------------------ // Delete first message command logic // Delete first message command logic function deleteFirstMessage() { const deleteCommand = JSON.parse(delete_first_commandJson); sendSocketMessage(socket, deleteCommand, true); // Pass `true` for reload argument } // Show confirmation modal function showDeleteConfirmation() { const modal_delete_first = document.createElement('div'); modal_delete_first.style.position = 'fixed'; modal_delete_first.style.top = '0'; modal_delete_first.style.left = '0'; modal_delete_first.style.width = '100%'; modal_delete_first.style.height = '100%'; modal_delete_first.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; modal_delete_first.style.display = 'flex'; modal_delete_first.style.justifyContent = 'center'; modal_delete_first.style.alignItems = 'center'; modal_delete_first.style.zIndex = '9999'; const modal_content = document.createElement('div'); modal_content.style.backgroundColor = 'white'; modal_content.style.padding = '20px'; modal_content.style.borderRadius = '5px'; modal_content.style.textAlign = 'center'; const modal_text = document.createElement('p'); modal_text.textContent = "The first message will be deleted. Proceed?"; modal_text.style.marginBottom = '20px'; const modal_buttons = document.createElement('div'); modal_buttons.style.display = 'flex'; modal_buttons.style.justifyContent = 'center'; const modal_confirm_button = document.createElement('button'); modal_confirm_button.textContent = 'Confirm'; modal_confirm_button.style.marginRight = '10px'; modal_confirm_button.style.backgroundColor = 'red'; // Example button color modal_confirm_button.style.color = 'white'; // Example text color modal_confirm_button.style.border = 'none'; modal_confirm_button.style.borderRadius = '3px'; modal_confirm_button.style.padding = '5px 15px'; modal_confirm_button.addEventListener('click', () => { document.body.removeChild(modal_delete_first); deleteFirstMessage(); }); const modal_cancel_button = document.createElement('button'); modal_cancel_button.textContent = 'Cancel'; modal_cancel_button.style.backgroundColor = 'gray'; // Example button color modal_cancel_button.style.color = 'white'; // Example text color modal_cancel_button.style.border = 'none'; modal_cancel_button.style.borderRadius = '3px'; modal_cancel_button.style.padding = '5px 15px'; modal_cancel_button.addEventListener('click', () => { document.body.removeChild(modal_delete_first); }); modal_buttons.appendChild(modal_confirm_button); modal_buttons.appendChild(modal_cancel_button); modal_content.appendChild(modal_text); modal_content.appendChild(modal_buttons); modal_delete_first.appendChild(modal_content); document.body.appendChild(modal_delete_first); } //------------------------------------ END OF DELETE FIRST FUNCTION------------------------------------ //------------------------------------ START OF DELETE LAST FUNCTION------------------------------------ // Delete last message command logic function deleteLastMessage() { const deleteCommand = JSON.parse(delete_last_commandJson); sendSocketMessage(socket, deleteCommand, true); // Pass `true` for the reload argument } // Show confirmation modal function showDeleteLastConfirmation() { const modal_delete_last = document.createElement('div'); modal_delete_last.style.position = 'fixed'; modal_delete_last.style.top = '0'; modal_delete_last.style.left = '0'; modal_delete_last.style.width = '100%'; modal_delete_last.style.height = '100%'; modal_delete_last.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; modal_delete_last.style.display = 'flex'; modal_delete_last.style.justifyContent = 'center'; modal_delete_last.style.alignItems = 'center'; modal_delete_last.style.zIndex = '9999'; const modal_content = document.createElement('div'); modal_content.style.backgroundColor = 'white'; modal_content.style.padding = '20px'; modal_content.style.borderRadius = '5px'; modal_content.style.textAlign = 'center'; const modal_text = document.createElement('p'); modal_text.textContent = "The first message will be deleted. Proceed?"; modal_text.style.marginBottom = '20px'; const modal_buttons = document.createElement('div'); modal_buttons.style.display = 'flex'; modal_buttons.style.justifyContent = 'center'; const modal_confirm_button = document.createElement('button'); modal_confirm_button.textContent = 'Confirm'; modal_confirm_button.style.marginRight = '10px'; modal_confirm_button.style.backgroundColor = 'red'; // Example button color modal_confirm_button.style.color = 'white'; // Example text color modal_confirm_button.style.border = 'none'; modal_confirm_button.style.borderRadius = '3px'; modal_confirm_button.style.padding = '5px 15px'; modal_confirm_button.addEventListener('click', () => { document.body.removeChild(modal_delete_last); deleteLastMessage(); }); const modal_cancel_button = document.createElement('button'); modal_cancel_button.textContent = 'Cancel'; modal_cancel_button.style.backgroundColor = 'gray'; // Example button color modal_cancel_button.style.color = 'white'; // Example text color modal_cancel_button.style.border = 'none'; modal_cancel_button.style.borderRadius = '3px'; modal_cancel_button.style.padding = '5px 15px'; modal_cancel_button.addEventListener('click', () => { document.body.removeChild(modal_delete_last); }); modal_buttons.appendChild(modal_confirm_button); modal_buttons.appendChild(modal_cancel_button); modal_content.appendChild(modal_text); modal_content.appendChild(modal_buttons); modal_delete_last.appendChild(modal_content); document.body.appendChild(modal_delete_last); } //------------------------------------ END OF DELETE FUNCTION------------------------------------ // wenn ich den anderen button hier rein mache dann muss der promise erfüllt sein // Function to send socket message function sendSocketMessage(socket, command, shouldReload) { try { socket.send(JSON.stringify(command)); console.log('Socket message sent:', command); if (shouldReload) { location.reload(); // Reload the page after sending the message } } catch (error) { console.error('Error sending socket message:', error); } } }); //------------------------------------ END OF XHR INTERCEPTION PROMISE ------------------------------------ function createToggleButton() { const toggleButton = document.createElement('button'); toggleButton.textContent = 'Details'; toggleButton.style.position = 'fixed'; toggleButton.style.bottom = '0px'; toggleButton.style.left = '0%'; toggleButton.style.backgroundColor = '#3E4040'; toggleButton.style.color = 'white'; toggleButton.style.fontWeight = 'bold'; toggleButton.style.padding = '4px'; toggleButton.style.margin = '0px'; toggleButton.style.width = '15%'; toggleButton.style.border = 'none'; toggleButton.style.borderRadius = '0px'; toggleButton.style.cursor = 'pointer'; toggleButton.style.userSelect = 'none'; toggleButton.style.zIndex = '101'; toggleButton.addEventListener('click', togglePanel); document.body.appendChild(toggleButton); } //--------------------------------------------------------- PERMANENT PANEL ------------------------------------------------------- function createPermanentPanel() { const panel = document.createElement('div'); panel.id = 'descriptionPanel'; panel.style.position = 'fixed'; panel.style.bottom = '32px'; panel.style.left = '0%'; panel.style.width = '15%'; panel.style.height = '100%'; panel.style.backgroundColor = 'white'; panel.style.borderRight = '1px solid #ccc'; panel.style.padding = '10px'; panel.style.zIndex = '100'; panel.style.resize = 'horizontal'; panel.style.direction = 'ltr'; panel.style.overflow = 'auto'; // Set the initial display state to 'none' panel.style.display = 'block'; //--------------------------------------------------------- ALL ELEMENTS IN THE PANEL ------------------------------------------------------- // Add headline to the panel const name_h = document.createElement('h4'); name_h.textContent = intercepted_data_object.name; name_h.style.marginTop = '35px'; name_h.style.textAlign = 'center'; // Center-align the text panel.appendChild(name_h); // Create a container div for the name and the new div const containerDiv = document.createElement('div'); containerDiv.style.display = 'flex'; // Use flexbox to arrange items in a row containerDiv.style.alignItems = 'center'; // Vertically center items containerDiv.style.justifyContent = 'center'; // Center items horizontally containerDiv.style.textAlign = 'center'; panel.appendChild(containerDiv); // Append the name_h to the container div containerDiv.appendChild(name_h); // Assuming you have access to the intercepted_data_object and containerDiv if ( intercepted_data_object.external_id === "EEI6sjnddRIJTVC59MODiYjL0-JyDIVI2IEGLkPx2Jk" || intercepted_data_object.external_id === "qtEICpGfFS8f5Zr5kCHR1EsGsHlawNutYSZJq_IEZDY" || intercepted_data_object.external_id === "0FGHpcylr6O0l46xHrTMzRGnqAU6beVz0k3i294wbUQ" || intercepted_data_object.external_id === "iV5qb8ttzD7Ytl69U_-ONcW2tW_lrFrOVKExyKJHlJM" || intercepted_data_object.external_id === "YntB_ZeqRq2l_aVf2gWDCZl4oBttQzDvhj9cXafWcF8" ) { const caitagDiv = document.createElement('div'); caitagDiv.innerHTML = '<div class="rounded py-0 px-1" style="vertical-align: middle; margin-top: 31px; margin-left: 5px; background-color: rgb(60, 133, 246); color: white; font-weight: 600; font-size: 12px;" aria-label="AI Character using new C1.2 Model. See Community Announcements to learn more." data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><div class="d-flex flex-row"><div class="d-flex flex-column">[email protected]</div></div></div>'; containerDiv.appendChild(caitagDiv); } else { const aiCharacterDiv = document.createElement('div'); aiCharacterDiv.className = 'rounded py-0 px-1'; aiCharacterDiv.style.marginLeft = '5px'; aiCharacterDiv.style.backgroundColor = 'rgb(60, 133, 246)'; aiCharacterDiv.style.color = 'white'; aiCharacterDiv.style.fontWeight = '600'; aiCharacterDiv.style.fontSize = '12px'; aiCharacterDiv.textContent = 'c.ai'; aiCharacterDiv.style.verticalAlign = 'middle'; // Adjust vertical alignment aiCharacterDiv.style.marginTop = '31px'; // Adjust margin-top containerDiv.appendChild(aiCharacterDiv); } // Function to map visibility strings to symbols or numbers function mapVisibilityToContent(visibility) { switch (visibility) { case 'PRIVATE': return '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="18" width="18" xmlns="http://www.w3.org/2000/svg" style="vertical-align: middle; margin-top: -3px;"><path fill="none" d="M0 0h24v24H0z"></path><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"></path></svg>'; case 'UNLISTED': return '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" class="mb-1" height="18" width="18" xmlns="http://www.w3.org/2000/svg" style="vertical-align: middle; margin-top: 5px;"><path fill="none" d="M0 0h24v24H0z"></path><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg>'; case 'PUBLIC': return '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg" style="vertical-align: middle; margin-top: -2px;"><path fill="none" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M87.49 380c1.19-4.38-1.44-10.47-3.95-14.86a44.86 44.86 0 00-2.54-3.8 199.81 199.81 0 01-33-110C47.65 139.09 140.73 48 255.83 48 356.21 48 440 117.54 459.58 209.85a199 199 0 014.42 41.64c0 112.41-89.49 204.93-204.59 204.93-18.3 0-43-4.6-56.47-8.37s-26.92-8.77-30.39-10.11a31.09 31.09 0 00-11.12-2.07 30.71 30.71 0 00-12.09 2.43l-67.83 24.48a16 16 0 01-4.67 1.22 9.6 9.6 0 01-9.57-9.74 15.85 15.85 0 01.6-3.29z"></path></svg>'; default: return 0; // Handle other cases, if needed } } // Example visibility value from intercepted data const visibilityValue = intercepted_data_object.visibility; // Map visibility to an SVG icon or number const visibilityContent = mapVisibilityToContent(visibilityValue); // Create the visibility element and set its content const visibilityElement = document.createElement('div'); visibilityElement.style.display = 'flex'; // Use flexbox visibilityElement.style.alignItems = 'center'; // Align items vertically visibilityElement.style.justifyContent = 'center'; // Center items horizontally visibilityElement.style.textAlign = 'center'; visibilityElement.innerHTML = visibilityContent; panel.appendChild(visibilityElement); // Function to format the interaction count function formatInteractionCount(count) { if (count < 10000) { return count.toString(); // Display full number } else if (count < 100000) { return (count / 1000).toFixed(1) + 'k'; // Display as X.Xk } else if (count < 1000000) { return (count / 1000).toFixed(0) + 'k'; // Display as Xk } else { return (count / 1000000).toFixed(1) + 'm'; // Display as X.Xm } } // Interaction count from intercepted data const numInteractions = intercepted_data_object.participant__num_interactions; // Format the interaction count const formattedInteractions = formatInteractionCount(numInteractions); // Create a span for the interaction count const interactionCountSpan = document.createElement('span'); interactionCountSpan.textContent = `${formattedInteractions}`; interactionCountSpan.style.marginLeft = '5px'; // Add margin to the left //interactionCountSpan.style.marginTop = '-6px'; // Add margin to the left // Add the interaction count span to the visibility element visibilityElement.appendChild(interactionCountSpan); // Add a horizontal line (divider) const divider = document.createElement('hr'); panel.appendChild(divider); // Add longdescription header to the panel const longdescription_h = document.createElement('h5'); longdescription_h.textContent = 'Long Description'; longdescription_h.style.marginTop = '0'; longdescription_h.style.textAlign = 'center'; // Center-align the text longdescription_h.style.display = 'block'; panel.appendChild(longdescription_h); // Add longdescription to the panel const longdescription = document.createElement('p'); longdescription.textContent = intercepted_data_object.description; longdescription.style.textAlign = 'center'; // Center-align the text longdescription.style.display = 'none'; // Initially hide the long description longdescription.style.marginBottom = '7px'; longdescription.style.whiteSpace = 'normal'; longdescription.style.overflowWrap = 'break-word'; panel.appendChild(longdescription); const expandButton = document.createElement('button'); //expandButton.style.margin = '10px auto'; // Center the button horizontally with top margin expandButton.style.backgroundColor = 'transparent'; // Set background color to transparent expandButton.style.border = 'none'; // Remove the button border expandButton.style.width = '100%'; const buttonTextContainer = document.createElement('div'); buttonTextContainer.style.textAlign = 'center'; // Center-align the text inside the container /*const line1Span = document.createElement('span'); line1Span.textContent = 'Long Description'; line1Span.style.fontSize = '20px'; // Set font size for the first line line1Span.style.color = '#C8C5BE'; // Set the color for the first line */ const line2Span = document.createElement('span'); line2Span.textContent = 'click to expand'; line2Span.style.fontSize = '14px'; // Set smaller font size for the second line line2Span.style.marginTop = '0px'; //buttonTextContainer.appendChild(line1Span); //buttonTextContainer.appendChild(document.createElement('br')); // Add a line break buttonTextContainer.appendChild(line2Span); expandButton.appendChild(buttonTextContainer); expandButton.addEventListener('click', () => { if (longdescription.style.display === 'none') { // longdescription_h.style.display = 'block'; longdescription.style.display = 'block'; // Show the long description // line1Span.style.color = 'transparent'; // Hide the long description title line2Span.textContent = 'click to collapse'; // Change the second line text } else { // longdescription_h.style.display = 'none'; longdescription.style.display = 'none'; // line1Span.style.color = '#C8C5BE'; // Show the long description line2Span.textContent = 'click to expand'; // Change the second line text } }); panel.appendChild(expandButton); // Add a horizontal line (divider) const divider1 = document.createElement('hr'); panel.appendChild(divider1); // Add image to the panel const image = document.createElement('img'); image.style.maxWidth = '100%'; image.style.marginTop = '10px'; image.style.display = 'block'; // Ensures that the image occupies full width image.style.margin = '0 auto'; // Centers the image horizontally // Set the original image source image.src = `https://characterai.io/i/400/static/avatars/${intercepted_data_object.avatar_file_name}`; // Add an event listener to handle image load error image.onerror = function() { // Load the fallback image if the original image fails to load image.src = 'https://i.imgur.com/G19HeCH.png'; }; panel.appendChild(image); // Add short description (title) to the panel const shortdescription = document.createElement('p'); shortdescription.textContent = intercepted_data_object.title; shortdescription.style.textAlign = 'center'; // Center-align the text shortdescription.style.marginTop = '10px'; panel.appendChild(shortdescription); // Add a horizontal line (divider) const divider2 = document.createElement('hr'); divider2.style.marginTop = '-5px'; panel.appendChild(divider2); // Create the username element and set its content using string interpolation const username = document.createElement('p'); username.textContent = `${intercepted_data_object.name} and their greeting was authored by @${intercepted_data_object.username}`; username.style.textAlign = 'center'; // Center-align the text username.style.marginTop = '5px'; username.style.setProperty('font-size', '14px', 'important'); // Set style with !important panel.appendChild(username); //--------------------------------------------------------- QPR BUTTON ------------------------------------------------------- const qpr_button = document.createElement('button'); qpr_button.textContent = 'Send a QPR'; qpr_button.style.padding = '5px 10px'; qpr_button.style.backgroundColor = '#007bff'; qpr_button.style.borderRadius = '5px'; qpr_button.style.color = 'white'; qpr_button.style.border = 'none'; qpr_button.style.cursor = 'pointer'; qpr_button.style.transition = 'background-color 0.3s, transform 0.2s'; qpr_button.style.display = 'block'; qpr_button.style.width = '100%'; // Mouseover animation qpr_button.addEventListener('mouseover', () => { qpr_button.style.backgroundColor = '#0056b3'; qpr_button.style.transform = 'scale(1.0)'; }); // Mouseout animation qpr_button.addEventListener('mouseout', () => { qpr_button.style.backgroundColor = '#007bff'; qpr_button.style.transform = 'scale(1)'; }); // Click animation and open URL qpr_button.addEventListener('click', () => { // Open the URL in a new tab window.open('https://docs.google.com/forms/d/e/1FAIpQLSe4I9TQAc32ghQLWBaVhzSjTp7mIADBVDxcrb-UmP4EqdM57w/viewform', '_blank'); }); // Append the QPR button to the panel panel.appendChild(qpr_button); //--------------------------------------------------------- AUTOSCROLL BUTTON ------------------------------------------------------- const autoscroll_button = document.createElement('button'); autoscroll_button.textContent = 'Autoscroll'; autoscroll_button.style.padding = '5px 10px'; autoscroll_button.style.marginTop = '10px'; autoscroll_button.style.backgroundColor = '#007bff'; autoscroll_button.style.borderRadius = '5px'; autoscroll_button.style.color = 'white'; autoscroll_button.style.border = 'none'; autoscroll_button.style.cursor = 'pointer'; autoscroll_button.style.transition = 'background-color 0.3s, transform 0.2s'; autoscroll_button.style.display = 'block'; autoscroll_button.style.width = '100%'; // Mouseover animation autoscroll_button.addEventListener('mouseover', () => { if (autoscroll_button.style.backgroundColor !== 'red') { // Check if background color is not red autoscroll_button.style.backgroundColor = '#0056b3'; autoscroll_button.style.transform = 'scale(1.0)'; } }); // Mouseout animation autoscroll_button.addEventListener('mouseout', () => { if (autoscroll_button.style.backgroundColor !== 'red') { // Check if background color is not red autoscroll_button.style.backgroundColor = '#007bff'; autoscroll_button.style.transform = 'scale(1)'; } }); // Click animation and scroll autoscroll_button.addEventListener('click', () => { event.stopPropagation(); toggleAutoscroll(autoscroll_button); autoscroll_button.removeEventListener('mouseover', mouseoverHandler); // Remove the mouseover listener autoscroll_button.removeEventListener('mouseout', mouseoutHandler); // Remove the mouseout listener }); // Append the autoscroll button to the panel panel.appendChild(autoscroll_button); function mouseoverHandler() { autoscroll_button.style.backgroundColor = '#0056b3'; autoscroll_button.style.transform = 'scale(1.0)'; } function mouseoutHandler() { autoscroll_button.style.backgroundColor = '#007bff'; autoscroll_button.style.transform = 'scale(1)'; } function ArrowRightKeyDown() { document.body.dispatchEvent( new KeyboardEvent('keydown', { bubbles: true, key: 'ArrowRight', }) ); console.log("Arrow right pressed"); } function scroll_totheright() { if (document.querySelector('div[class="swiper-button-next"]')) { ArrowRightKeyDown(); setTimeout(scroll_totheright, 100); // Add a delay between scrolls } else { scroll_totheright_observer.observe(document.querySelector('div[class*="swiper swiper-initialized swiper-horizontal"]'), { childList: true, subtree: true }); } } const scroll_totheright_observer = new MutationObserver(scroll_totheright); function toggleAutoscroll(autoscroll_button) { if (sessionStorage.getItem("RAs_Autoscroll") === "true") { sessionStorage.removeItem("RAs_Autoscroll"); autoscroll_button.innerHTML = 'Autoscroll'; autoscroll_button.style.backgroundColor = ''; scroll_totheright_observer.disconnect(); } else { sessionStorage.setItem("RAs_Autoscroll", "true"); autoscroll_button.innerHTML = 'Autoscroll ⏭️'; autoscroll_button.style.backgroundColor = 'red'; // Set background color to red scroll_totheright(); scroll_totheright_observer.observe(document.querySelector('div[class*="swiper swiper-initialized swiper-horizontal"]'), { childList: true, subtree: true }); } } function createAutoscrollButton(panel) { const autoscroll_button = document.createElement('button'); autoscroll_button.innerHTML = 'Autoscroll'; autoscroll_button.addEventListener('click', function(event) { event.stopPropagation(); toggleAutoscroll(autoscroll_button); }); const buttonContainer = document.createElement('div'); buttonContainer.style.marginTop = '10px'; // Adjust margin as needed buttonContainer.appendChild(autoscroll_button); panel.appendChild(buttonContainer); if (sessionStorage.getItem("RAs_Autoscroll") === "true") { toggleAutoscroll(autoscroll_button); } } //--------------------------------------------------------- AUTOSCROLL BUTTON END ------------------------------------------------------- document.body.appendChild(panel); } //--------------------------------------------------------- NEO PANEL DELETE ------------------------------------------------------- /*function createNeoPanelDelete() { const NeoPanelDelete = document.createElement('div'); NeoPanelDelete.id = 'NeoPanelDelete'; NeoPanelDelete.style.position = 'absolute'; NeoPanelDelete.style.bottom = '32px'; NeoPanelDelete.style.left = '15%'; NeoPanelDelete.style.width = '15%'; NeoPanelDelete.style.height = '100%'; NeoPanelDelete.style.backgroundColor = 'white'; NeoPanelDelete.style.borderLeft = '1px solid #ccc'; NeoPanelDelete.style.padding = '10px'; NeoPanelDelete.style.zIndex = '100'; NeoPanelDelete.style.resize = 'horizontal'; NeoPanelDelete.style.direction = 'rtl'; NeoPanelDelete.style.overflow = 'auto'; // Set the initial display state to 'none' NeoPanelDelete.style.display = 'block'; // Add longdescription header to the panel const Delete_headline = document.createElement('h5'); Delete_headline.textContent = 'Delete'; Delete_headline.style.marginTop = '30px'; Delete_headline.style.textAlign = 'center'; // Center-align the text NeoPanelDelete.appendChild(Delete_headline); // Add a horizontal line (divider) const divider_Delete1 = document.createElement('hr'); NeoPanelDelete.appendChild(divider_Delete1); document.body.appendChild(NeoPanelDelete); } */ function toggleNeoPanelDelete() { const NeoPanelDelete = document.getElementById('NeoPanelDelete'); if (NeoPanelDelete.style.display === 'block') { NeoPanelDelete.style.display = 'none'; } else { NeoPanelDelete.style.display = 'block'; } } //--------------------------------------------------------- ERROR 500 maybe ------------------------------------------------------- waitForElement('div[id="root"]>div[class="Toastify"]', 60000).then(function() { //console.log("Toastify observer SUCCESS"); const error500_observer = new MutationObserver (function () { //console.log("error500_observer observer fired"); if (document.querySelector('div[class*="Toastify__toast--error"]')) { console.log("500 Internal Server Error detected"); document.querySelector('textarea[id="user-input"]').style.setProperty("background-color", "lightpink", "important"); document.querySelector('textarea[id="user-input"]').setAttribute("placeholder", " “500 Internal Server Error” was fired! Refresh the page!"); }; }); error500_observer.observe(document.querySelector('div[id="root"]>div[class="Toastify"]'), {childList: true, subtree: true}); }).catch(function() { console.log("Toastify observer ERROR"); }); //--------------------------------------------------------- ERROR 500 maybe END ------------------------------------------------------- function togglePanel() { const panel = document.getElementById('descriptionPanel'); if (panel.style.display === 'block') { panel.style.display = 'none'; } else { panel.style.display = 'block'; } } })();