Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Mammouth.ai Ultimate Lazy Loader + Network Optimizer
- // @namespace chartreus_ultimate_loader
- // @version 3.0
- // @description Lazy load + interception réseau pour ne charger QUE les 120 derniers messages
- // @author Chartreus (Claude Sonnet 4)
- // @match https://mammouth.ai/app/a/*
- // @grant none
- // ==/UserScript==
- (function() {
- 'use strict';
- // 🎯 Config optimisée
- const LAZY_CONFIG = {
- DISPLAY_LIMIT: 120,
- BATCH_SIZE: 15,
- SCROLL_THRESHOLD: 150,
- CACHE_KEY: 'mammouth_messages',
- DEBOUNCE_DELAY: 250,
- MAX_NETWORK_MESSAGES: 120
- };
- let currentConversationId = null;
- let lazyLoaderInstance = null;
- let originalFetch = null;
- let networkInterceptionActive = false;
- // 🌐 Intercepteur réseau ultime
- function setupNetworkInterception() {
- if (networkInterceptionActive) return;
- networkInterceptionActive = true;
- // Sauvegarde de la fonction fetch originale
- originalFetch = window.fetch;
- // Interception de fetch
- window.fetch = async function(...args) {
- const [url, options] = args;
- // Détection des requêtes de messages
- if (typeof url === 'string' && (
- url.includes('/messages') ||
- url.includes('/conversation') ||
- url.includes('/history') ||
- url.includes('/chat')
- )) {
- console.log('🕵️ Intercepting message request:', url);
- // Modification de la requête pour limiter les résultats
- let modifiedUrl = url;
- let modifiedOptions = {...options};
- // Si c'est une requête GET, ajouter des paramètres de limite
- if (!options?.method || options.method === 'GET') {
- const urlObj = new URL(url, window.location.origin);
- urlObj.searchParams.set('limit', LAZY_CONFIG.MAX_NETWORK_MESSAGES);
- urlObj.searchParams.set('recent', 'true');
- modifiedUrl = urlObj.toString();
- }
- // Si c'est une requête POST avec un body JSON
- if (options?.body && options?.method === 'POST') {
- try {
- const bodyData = JSON.parse(options.body);
- if (bodyData) {
- bodyData.limit = LAZY_CONFIG.MAX_NETWORK_MESSAGES;
- bodyData.recent = true;
- bodyData.maxMessages = LAZY_CONFIG.MAX_NETWORK_MESSAGES;
- modifiedOptions.body = JSON.stringify(bodyData);
- }
- } catch (e) {
- console.log('📝 Could not modify POST body, proceeding with original');
- }
- }
- console.log('🚀 Modified request URL:', modifiedUrl);
- return originalFetch(modifiedUrl, modifiedOptions);
- }
- // Pour toutes les autres requêtes, utiliser fetch original
- return originalFetch(...args);
- };
- // Interception de XMLHttpRequest aussi
- const originalXHROpen = XMLHttpRequest.prototype.open;
- XMLHttpRequest.prototype.open = function(method, url, ...args) {
- if (typeof url === 'string' && (
- url.includes('/messages') ||
- url.includes('/conversation') ||
- url.includes('/history') ||
- url.includes('/chat')
- )) {
- console.log('🕵️ Intercepting XHR request:', url);
- const urlObj = new URL(url, window.location.origin);
- urlObj.searchParams.set('limit', LAZY_CONFIG.MAX_NETWORK_MESSAGES);
- urlObj.searchParams.set('recent', 'true');
- url = urlObj.toString();
- console.log('🚀 Modified XHR URL:', url);
- }
- return originalXHROpen.call(this, method, url, ...args);
- };
- console.log('🌐 Network interception setup complete!');
- }
- // 🛡️ Observateur DOM pour limiter les messages affichés
- function setupDOMMessageLimiter() {
- const messageObserver = new MutationObserver((mutations) => {
- mutations.forEach((mutation) => {
- if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
- setTimeout(() => limitDisplayedMessages(), 100);
- }
- });
- });
- messageObserver.observe(document.body, {
- childList: true,
- subtree: true
- });
- console.log('👁️ DOM message limiter active!');
- }
- function limitDisplayedMessages() {
- const allMessages = document.querySelectorAll('[data-index]');
- if (allMessages.length > LAZY_CONFIG.DISPLAY_LIMIT) {
- console.log(`✂️ Limiting messages: ${allMessages.length} -> ${LAZY_CONFIG.DISPLAY_LIMIT}`);
- const messagesToHide = Array.from(allMessages).slice(0, allMessages.length - LAZY_CONFIG.DISPLAY_LIMIT);
- messagesToHide.forEach((msg, index) => {
- if (!msg.hasAttribute('data-hidden-by-optimizer')) {
- replaceWithOptimizedPlaceholder(msg, index);
- }
- });
- // Créer un méga-placeholder pour les messages cachés
- if (messagesToHide.length > 0) {
- createNetworkOptimizedPlaceholder(messagesToHide.length);
- }
- }
- }
- function replaceWithOptimizedPlaceholder(msg, index) {
- const placeholder = document.createElement('div');
- placeholder.setAttribute('data-hidden-by-optimizer', 'true');
- placeholder.setAttribute('data-network-placeholder', index);
- placeholder.style.cssText = `
- height: 15px;
- width: 100%;
- max-width: 100%;
- opacity: 0;
- pointer-events: none;
- position: relative;
- display: block;
- box-sizing: border-box;
- overflow: hidden;
- margin: 0;
- padding: 0;
- `;
- msg.parentNode.insertBefore(placeholder, msg);
- msg.remove();
- }
- function createNetworkOptimizedPlaceholder(hiddenCount) {
- // Supprimer l'ancien placeholder s'il existe
- const existingPlaceholder = document.querySelector('.network-optimized-placeholder');
- if (existingPlaceholder) {
- existingPlaceholder.remove();
- }
- const megaPlaceholder = document.createElement('div');
- megaPlaceholder.className = 'network-optimized-placeholder';
- megaPlaceholder.style.cssText = `
- background: linear-gradient(135deg, #0f172a, #1e293b, #334155);
- border: 2px dashed #22d3ee;
- border-radius: 16px;
- padding: 32px;
- margin: 20px 0;
- text-align: center;
- color: #e2e8f0;
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
- position: relative;
- overflow: hidden;
- cursor: pointer;
- transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
- max-width: 100%;
- box-sizing: border-box;
- width: 100%;
- display: block;
- box-shadow: 0 10px 40px rgba(34, 211, 238, 0.1);
- `;
- megaPlaceholder.innerHTML = `
- <div style="font-size: 2.5rem; margin-bottom: 16px; animation: pulse 2s infinite;">🚀💨</div>
- <div style="font-size: 1.4rem; font-weight: 700; margin-bottom: 12px; color: #22d3ee;">
- ${hiddenCount} messages optimisés (non chargés)
- </div>
- <div style="font-size: 1rem; opacity: 0.9; margin-bottom: 20px; line-height: 1.5;">
- <div>⚡ Requêtes réseau limitées à ${LAZY_CONFIG.MAX_NETWORK_MESSAGES} messages</div>
- <div style="margin-top: 8px;">💾 Mémoire économisée • Performance maximale</div>
- </div>
- <div style="font-size: 0.9rem; padding: 12px 20px; background: rgba(34, 211, 238, 0.15); border: 1px solid rgba(34, 211, 238, 0.3); border-radius: 8px; display: inline-block;">
- 💡 Messages anciens non chargés pour optimiser les performances
- </div>
- <div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(45deg, transparent 30%, rgba(34, 211, 238, 0.05) 50%, transparent 70%); animation: shimmer 3s infinite;"></div>
- `;
- // Ajouter les animations CSS
- const style = document.createElement('style');
- style.textContent = `
- @keyframes pulse {
- 0%, 100% { transform: scale(1); opacity: 1; }
- 50% { transform: scale(1.1); opacity: 0.8; }
- }
- @keyframes shimmer {
- 0% { transform: translateX(-100%); }
- 100% { transform: translateX(100%); }
- }
- `;
- document.head.appendChild(style);
- megaPlaceholder.addEventListener('mouseenter', () => {
- megaPlaceholder.style.transform = 'scale(1.02) translateY(-2px)';
- megaPlaceholder.style.borderColor = '#06b6d4';
- megaPlaceholder.style.boxShadow = '0 20px 60px rgba(34, 211, 238, 0.2)';
- });
- megaPlaceholder.addEventListener('mouseleave', () => {
- megaPlaceholder.style.transform = 'scale(1) translateY(0)';
- megaPlaceholder.style.borderColor = '#22d3ee';
- megaPlaceholder.style.boxShadow = '0 10px 40px rgba(34, 211, 238, 0.1)';
- });
- const firstVisibleMessage = document.querySelector('[data-index]:not([data-hidden-by-optimizer])');
- if (firstVisibleMessage) {
- firstVisibleMessage.parentNode.insertBefore(megaPlaceholder, firstVisibleMessage);
- }
- }
- // [Garde la classe UltimateMammouthLoader originale mais simplifiée]
- class UltimateMammouthLoader {
- constructor() {
- this.messagesContainer = null;
- this.isInitialized = false;
- this.initWhenReady();
- }
- initWhenReady() {
- const checkReady = () => {
- const messages = document.querySelectorAll('[data-index]');
- if (messages.length > 0 && !this.isInitialized) {
- console.log(`📊 Found ${messages.length} messages, checking if limitation needed...`);
- setTimeout(() => limitDisplayedMessages(), 500);
- this.isInitialized = true;
- } else if (messages.length === 0) {
- setTimeout(checkReady, 1000);
- }
- };
- checkReady();
- }
- }
- // [Garde les fonctions d'enhancement identiques...]
- function enhanceMammothAI() {
- const textarea = document.querySelector('textarea[placeholder="Posez votre question"]');
- if (textarea && !textarea.hasAttribute('data-enhanced')) {
- textarea.maxLength = 199900;
- textarea.setAttribute('data-enhanced', 'true');
- ['input', 'focus', 'click', 'keydown'].forEach(eventType => {
- textarea.addEventListener(eventType, function() {
- if (this.value && !this.value.startsWith('[')) {
- const now = new Date();
- const timestamp = `[${now.toLocaleString('fr-FR')}] `;
- this.value = timestamp + this.value;
- this.setSelectionRange(this.value.length, this.value.length);
- }
- });
- });
- }
- // [Garde le reste de la fonction identique...]
- const messageContents = document.querySelectorAll('[data-index] div[class*="message_content"]:not([data-timestamped])');
- messageContents.forEach(content => {
- if (content.closest('[data-index]') && content.querySelector('p strong')) {
- const timestamp = document.createElement('div');
- timestamp.className = 'text-xs text-gray-500 mb-2 font-mono';
- timestamp.style.cssText = 'opacity: 0.7; border-left: 2px solid #10b981; padding-left: 8px;';
- timestamp.textContent = `📅 ${new Date().toLocaleString('fr-FR')}`;
- content.insertBefore(timestamp, content.firstChild);
- content.setAttribute('data-timestamped', 'true');
- }
- });
- const copyButtons = document.querySelectorAll('.copy-button-2le1:not([data-enhanced])');
- copyButtons.forEach(btn => {
- btn.setAttribute('data-enhanced', 'true');
- btn.addEventListener('click', () => {
- btn.style.backgroundColor = '#10b981';
- btn.style.transform = 'scale(0.95)';
- setTimeout(() => {
- btn.style.backgroundColor = '';
- btn.style.transform = '';
- }, 200);
- });
- });
- }
- function initialize() {
- console.log('🚀 Ultimate Network-Optimized Mammouth Loader starting...');
- // 🆕 Démarrer l'interception réseau AVANT tout le reste
- setupNetworkInterception();
- setupDOMMessageLimiter();
- setTimeout(() => {
- lazyLoaderInstance = new UltimateMammouthLoader();
- }, 1000);
- // Setup watchers
- let lastUrl = window.location.href;
- const observer = new MutationObserver(() => {
- const currentUrl = window.location.href;
- if (currentUrl !== lastUrl) {
- lastUrl = currentUrl;
- console.log(`🌐 Conversation changed: ${currentUrl}`);
- setTimeout(() => {
- lazyLoaderInstance = new UltimateMammouthLoader();
- }, 1000);
- }
- });
- observer.observe(document.body, { childList: true, subtree: true });
- const enhanceObserver = new MutationObserver(() => {
- enhanceMammothAI();
- });
- enhanceObserver.observe(document.body, { childList: true, subtree: true });
- // Lancer les améliorations
- setTimeout(enhanceMammothAI, 750);
- setTimeout(enhanceMammothAI, 2250);
- setTimeout(enhanceMammothAI, 4500);
- }
- // Démarrage ultra-précoce pour intercepter les requêtes
- if (document.readyState === 'loading') {
- setupNetworkInterception();
- document.addEventListener('DOMContentLoaded', initialize);
- } else {
- initialize();
- }
- console.log('🌐⚡ Network-Optimized Mammouth Loader ready!');
- })();
Advertisement
Add Comment
Please, Sign In to add comment