// ==UserScript== // @name Mistral AI - Delete All Chats // @namespace http://tampermonkey.net/ // @version 1.0 // @description Adds a native-looking "Delete All Chats" button to Mistral AI interface with multi-language support // @author Ognisty321 // @match https://chat.mistral.ai/* // @license MIT // @grant none // @run-at document-end // @downloadURL none // ==/UserScript== (function() { 'use strict'; const translations = { en: { deleteAllChats: "Delete All Chats", confirmDeleteAll: "Are you sure you want to delete ALL chats? This action cannot be undone!", modalTitle: "Deleting Chats", modalClose: "Close", startingDeletion: "Starting deletion process...", fetchingChats: "Fetching chats...", foundChats: "Found {0} chats to delete.", noMoreChats: "No more chats to delete!", deletionComplete: "✅ Deletion complete! Successfully deleted {0} chats in total.", startingBatch: "Starting batch #{0}...", completedBatch: "Completed batch #{0}: Deleted {1} chats", deletedChat: "Deleted chat: {0} ({1}...)", failedChat: "Failed to delete chat {0}: {1}", errorFetchingChats: "Error fetching chats: {0}", buttonAdded: "Delete all chats button added successfully", confirmButtonLog: "Attempting to add native delete button..." }, es: { deleteAllChats: "Borrar todos los chats", confirmDeleteAll: "¿Estás seguro de que quieres borrar TODOS los chats? ¡Esta acción no se puede deshacer!", modalTitle: "Borrando Chats", modalClose: "Cerrar", startingDeletion: "Iniciando el proceso de borrado...", fetchingChats: "Obteniendo lista de chats...", foundChats: "Se encontraron {0} chats para borrar.", noMoreChats: "¡No hay más chats para borrar!", deletionComplete: "✅ ¡Borrado completo! Se han borrado {0} chats en total.", startingBatch: "Iniciando lote #{0}...", completedBatch: "Lote #{0} completado: {1} chats borrados", deletedChat: "Chat borrado: {0} ({1}...)", failedChat: "No se pudo borrar el chat {0}: {1}", errorFetchingChats: "Error al obtener la lista de chats: {0}", buttonAdded: "Botón para borrar todos los chats agregado exitosamente", confirmButtonLog: "Intentando agregar botón de borrado nativo..." }, pl: { deleteAllChats: "Usuń wszystkie czaty", confirmDeleteAll: "Czy na pewno chcesz usunąć WSZYSTKIE czaty? Tej operacji nie można cofnąć!", modalTitle: "Usuwanie czatów", modalClose: "Zamknij", startingDeletion: "Rozpoczynam proces usuwania...", fetchingChats: "Pobieranie czatów...", foundChats: "Znaleziono {0} czatów do usunięcia.", noMoreChats: "Brak kolejnych czatów do usunięcia!", deletionComplete: "✅ Usuwanie zakończone! Pomyślnie usunięto {0} czatów w sumie.", startingBatch: "Rozpoczynam partię nr {0}...", completedBatch: "Zakończono partię nr {0}: usunięto {1} czatów", deletedChat: "Usunięto czat: {0} ({1}...)", failedChat: "Nie udało się usunąć czatu {0}: {1}", errorFetchingChats: "Błąd podczas pobierania czatów: {0}", buttonAdded: "Przycisk \"Usuń wszystkie czaty\" został pomyślnie dodany", confirmButtonLog: "Próba dodania natywnego przycisku usuwania..." }, de: { deleteAllChats: "Alle Chats löschen", confirmDeleteAll: "Sind Sie sicher, dass Sie ALLE Chats löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden!", modalTitle: "Chats löschen", modalClose: "Schließen", startingDeletion: "Löschvorgang wird gestartet...", fetchingChats: "Chats werden abgerufen...", foundChats: "Es wurden {0} Chats zum Löschen gefunden.", noMoreChats: "Keine weiteren Chats zum Löschen!", deletionComplete: "✅ Löschvorgang abgeschlossen! Insgesamt {0} Chats erfolgreich gelöscht.", startingBatch: "Starte Batch #{0}...", completedBatch: "Batch #{0} abgeschlossen: {1} Chats gelöscht", deletedChat: "Chat gelöscht: {0} ({1}...)", failedChat: "Löschen des Chats {0} fehlgeschlagen: {1}", errorFetchingChats: "Fehler beim Abrufen der Chats: {0}", buttonAdded: "Button \"Alle Chats löschen\" erfolgreich hinzugefügt", confirmButtonLog: "Versuch, den nativen Lösch-Button hinzuzufügen..." } }; function formatString(template, ...args) { return template.replace(/\{(\d+)\}/g, (match, index) => { return typeof args[index] !== 'undefined' ? args[index] : match; }); } const userLang = (navigator.language || navigator.userLanguage || 'en').slice(0, 2); const i18n = translations[userLang] || translations.en; function addNativeDeleteButton() { console.log(i18n.confirmButtonLog); const sidebarMenu = document.querySelector('ul[data-sidebar="menu"]'); if (!sidebarMenu) { console.log('Sidebar menu not found, retrying in 1 second...'); setTimeout(addNativeDeleteButton, 1000); return; } if (document.getElementById('delete-all-chats-button')) { console.log('Delete button already exists'); return; } const menuItem = document.createElement('li'); menuItem.setAttribute('data-sidebar', 'menu-item'); menuItem.className = 'group/menu-item relative'; const button = document.createElement('button'); button.id = 'delete-all-chats-button'; button.setAttribute('data-sidebar', 'menu-button'); button.setAttribute('data-size', 'default'); button.setAttribute('data-active', 'false'); button.className = 'peer/menu-button ring-default active:bg-muted active:text-default data-[active=true]:bg-muted data-[active=true]:text-default data-[state=open]:hover:bg-muted data-[state=open]:hover:text-default outline-hidden group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left transition-colors focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:font-medium [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 hover:bg-red-100 hover:text-red-700 h-8 text-sm text-red-600'; button.type = 'button'; button.innerHTML = ` ${i18n.deleteAllChats} `; button.addEventListener('click', () => { confirmAndDeleteAllChats(); }); menuItem.appendChild(button); sidebarMenu.appendChild(menuItem); console.log(i18n.buttonAdded); createStatusModal(); } function createStatusModal() { if (document.getElementById('delete-status-modal')) { return; } const modal = document.createElement('div'); modal.id = 'delete-status-modal'; modal.style.position = 'fixed'; modal.style.top = '0'; modal.style.left = '0'; modal.style.right = '0'; modal.style.bottom = '0'; modal.style.backgroundColor = 'rgba(0, 0, 0, 0.75)'; modal.style.zIndex = '9999'; modal.style.display = 'none'; modal.style.overflow = 'auto'; modal.style.alignItems = 'flex-start'; modal.style.justifyContent = 'center'; modal.style.paddingTop = '50px'; modal.style.paddingBottom = '50px'; const modalContent = document.createElement('div'); modalContent.className = 'relative w-full max-w-md rounded-lg bg-gray-900 shadow-lg text-gray-100'; modalContent.style.margin = '0 auto'; modalContent.style.boxShadow = '0 10px 25px -5px rgba(0, 0, 0, 0.3)'; modalContent.style.display = 'flex'; modalContent.style.flexDirection = 'column'; modalContent.style.maxHeight = '80vh'; const modalHeader = document.createElement('div'); modalHeader.className = 'flex items-center justify-between border-b border-gray-700 pb-3 px-4 pt-4'; modalHeader.style.position = 'sticky'; modalHeader.style.top = '0'; modalHeader.style.backgroundColor = 'rgb(17,24,39)'; modalHeader.style.zIndex = '1'; modalHeader.style.borderTopLeftRadius = '0.5rem'; modalHeader.style.borderTopRightRadius = '0.5rem'; modalHeader.innerHTML = `