Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name ViGGO Sletter - Endelige Version 2
- // @namespace http://tampermonkey.net/
- // @version 2025-06-26
- // @description Sletter overflødige ViGGO beskeder lynhurtigt!
- // @author Oliver AAE 24-25
- // @match https://aae.viggo.dk/Basic*
- // @icon https://www.google.com/s2/favicons?sz=64&domain=viggo.dk
- // @grant none
- // ==/UserScript==
- (function() {
- 'use strict';
- const addStyles = () => {
- const style = document.createElement('style');
- style.textContent = `
- .trash-icon {
- position: absolute;
- top: 8px;
- right: 8px;
- width: 18px;
- height: 18px;
- background-color: #f44336;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- color: white;
- font-size: 10px;
- font-weight: bold;
- z-index: 10;
- box-shadow: 0 0 3px rgba(0,0,0,0.5);
- }
- .trash-icon::after {
- content: "🗑️";
- }
- .help-popup {
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 90%;
- max-width: 600px;
- max-height: 90vh;
- background: #1a1a1a;
- color: #f1f1f1;
- padding: 25px;
- border-radius: 15px;
- box-shadow: 0 10px 30px rgba(0,0,0,0.5);
- z-index: 10001;
- overflow-y: auto;
- font-family: 'Arial', sans-serif;
- display: none;
- }
- .help-overlay {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: rgba(0,0,0,0.7);
- backdrop-filter: blur(5px);
- z-index: 10000;
- display: none;
- }
- .help-popup h2 {
- color: #007BFF;
- margin-top: 0;
- border-bottom: 1px solid #333;
- padding-bottom: 10px;
- }
- .help-popup ol {
- text-align: left;
- padding-left: 20px;
- }
- .help-popup li {
- margin-bottom: 15px;
- line-height: 1.5;
- }
- .close-help {
- position: absolute;
- top: 15px;
- right: 15px;
- background: #555;
- border: none;
- color: white;
- width: 30px;
- height: 30px;
- border-radius: 50%;
- cursor: pointer;
- font-size: 18px;
- }
- `;
- document.head.appendChild(style);
- };
- (() => {
- addStyles();
- let lastFolderId = null;
- let markedForDeletion = new Set();
- const monitorFolderChange = () => {
- setInterval(() => {
- const urlParams = new URLSearchParams(window.location.search);
- const currentFolderId = urlParams.get('folder');
- if (currentFolderId !== lastFolderId) {
- lastFolderId = currentFolderId;
- markedForDeletion.clear();
- const notificationBanner = document.getElementById('viggo-folder-notification');
- if (notificationBanner) notificationBanner.remove();
- if (currentFolderId === '0') {
- const banner = document.createElement('div');
- banner.id = 'viggo-folder-notification';
- banner.textContent = '📨 Du er nu i "Sendt post" mappen!';
- banner.style.position = 'fixed';
- banner.style.top = '0';
- banner.style.left = '0';
- banner.style.width = '100%';
- banner.style.padding = '12px';
- banner.style.backgroundColor = '#ff9800';
- banner.style.color = 'black';
- banner.style.textAlign = 'center';
- banner.style.zIndex = '9999';
- banner.style.fontWeight = 'bold';
- banner.style.fontSize = '16px';
- banner.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.3)';
- document.body.appendChild(banner);
- }
- }
- }, 1000);
- };
- let cancelRequested = false;
- const styleButton = (button, bgColor) => {
- button.style.padding = '12px 18px';
- button.style.width = '100%';
- button.style.backgroundColor = bgColor;
- button.style.border = 'none';
- button.style.color = 'white';
- button.style.borderRadius = '10px';
- button.style.cursor = 'pointer';
- button.style.fontSize = '16px';
- button.style.transition = 'background-color 0.3s ease-in-out';
- button.style.marginBottom = '10px';
- };
- const styleInput = (input) => {
- input.style.width = '100%';
- input.style.padding = '10px';
- input.style.marginBottom = '15px';
- input.style.borderRadius = '10px';
- input.style.border = '1px solid #333';
- input.style.backgroundColor = '#2b2b2b';
- input.style.color = '#f1f1f1';
- input.style.fontSize = '16px';
- };
- const extractMessageIds = () => {
- const isSentFolder = window.location.pathname.includes("/Folder/0");
- markedForDeletion.clear();
- if (isSentFolder) {
- const messageList = document.querySelector("ul.list-messages");
- if (!messageList) return [];
- const checkboxes = messageList.querySelectorAll('input[type="checkbox"][name="MessageId"]');
- return Array.from(checkboxes)
- .map(cb => cb.value)
- .filter(id => /^\d{5,6}$/.test(id)); // Accept 5 or 6 digit IDs
- } else {
- const messageElements = document.querySelectorAll('li[data-drag-id]');
- return Array.from(messageElements)
- .map(el => el.getAttribute('data-drag-id'))
- .filter(id => /^\d{5,6}$/.test(id));
- }
- };
- const markMessagesForDeletion = (idsToDelete) => {
- // Remove existing trash icons
- document.querySelectorAll('.trash-icon').forEach(icon => icon.remove());
- if (window.location.pathname.includes("/Folder/0")) {
- // Sent messages
- idsToDelete.forEach(id => {
- const checkbox = document.querySelector(`input[type="checkbox"][value="${id}"]`);
- if (checkbox) {
- const listItem = checkbox.closest('li');
- if (listItem) {
- const trashIcon = document.createElement('div');
- trashIcon.className = 'trash-icon';
- listItem.appendChild(trashIcon);
- }
- }
- });
- } else {
- idsToDelete.forEach(id => {
- const message = document.querySelector(`li[data-drag-id="${id}"]`);
- if (message) {
- const trashIcon = document.createElement('div');
- trashIcon.className = 'trash-icon';
- message.appendChild(trashIcon);
- }
- });
- }
- };
- const showLoadingEffect = () => {
- const messageList = document.getElementById('message-list');
- if (messageList) {
- messageList.style.filter = 'blur(5px)';
- messageList.style.transition = 'filter 0.3s ease';
- document.getElementById("message-list").style.pointerEvents = "none";
- document.getElementById("message-list").style.userSelect = "none";
- document.getElementById("message-list").style.opacity = "0.6";
- }
- const loadingContainer = document.createElement('div');
- loadingContainer.classList.add('custom-loading-container');
- loadingContainer.innerHTML = `
- <style>
- .custom-loading-container {
- position: fixed;
- top: 50vh;
- left: 50%;
- transform: translate(-250%, -50%);
- z-index: 9999;
- text-align: center;
- font-family: sans-serif;
- color: #333;
- }
- .spinner {
- width: 40px;
- height: 40px;
- margin: 10px auto 0;
- border-radius: 50%;
- border: 5px solid #ccc;
- border-top-color: #007bff;
- animation: spin 1s linear infinite;
- }
- @keyframes spin {
- to { transform: rotate(360deg); }
- }
- .checkmark {
- width: 40px;
- height: 40px;
- display: inline-block;
- border-radius: 50%;
- background-color: #28a745;
- position: relative;
- animation: fadeIn 0.5s ease-in-out forwards;
- }
- .checkmark::after {
- content: '';
- position: absolute;
- left: 12px;
- top: 6px;
- width: 10px;
- height: 20px;
- border: solid white;
- border-width: 0 4px 4px 0;
- transform: rotate(45deg);
- }
- @keyframes fadeIn {
- from { opacity: 0; transform: scale(0.8); }
- to { opacity: 1; transform: scale(1); }
- }
- </style>
- <div id="loading-text">Sletter</div>
- <div class="spinner" id="spinner"></div>
- `;
- document.body.appendChild(loadingContainer);
- return loadingContainer;
- };
- const finishLoadingEffect = (container) => {
- const spinner = container.querySelector('#spinner');
- const text = container.querySelector('#loading-text');
- if (spinner) spinner.remove();
- if (text) text.textContent = 'Sådan!';
- const checkmark = document.createElement('div');
- checkmark.className = 'checkmark';
- container.appendChild(checkmark);
- const audio = new Audio('https://notificationsounds.com/storage/sounds/file-sounds-1085-definite.mp3');
- audio.volume = 0.6;
- audio.play().catch(err => console.warn('Audio failed to play:', err));
- setTimeout(() => location.reload(), 1500);
- };
- const deleteMessages = async (messageIds, statusText, progressBar, loadingContainer) => {
- let url;
- if (window.location.href.includes("/Folder/0")) {
- url = 'https://aae.viggo.dk/Basic/Message/DeleteMessages/?folderId=0';
- } else {
- url = 'https://aae.viggo.dk/Basic/Message/DeleteMessages/?folderId=11';
- }
- let deleted = 0;
- let i = 0;
- while (i < messageIds.length) {
- if (cancelRequested) {
- statusText.textContent = `Annulleret efter ${deleted} / ${messageIds.length} beskeder.`;
- return;
- }
- const bulkSize = Math.floor(Math.random() * (175 - 75 + 1)) + 75;
- const chunk = messageIds.slice(i, i + bulkSize);
- const payload = chunk.map(id => `MessageId=${encodeURIComponent(id)}`).join('&');
- try {
- const res = await fetch(url, {
- method: 'DELETE',
- headers: {
- 'Accept': '*/*',
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'X-Requested-With': 'XMLHttpRequest'
- },
- body: payload,
- credentials: 'include'
- });
- if (res.ok) {
- deleted += chunk.length;
- progressBar.value = (deleted / messageIds.length) * 100;
- statusText.textContent = `Sletter ${deleted} / ${messageIds.length}`;
- } else {
- console.error('Sletning fejlede:', res.statusText);
- }
- } catch (err) {
- console.error('Netværksfejl ved sletning:', err);
- }
- i += bulkSize;
- }
- statusText.textContent = 'Sletning færdig - opdaterer siden...';
- finishLoadingEffect(loadingContainer);
- };
- const showConfirmation = (count, onConfirm) => {
- const overlay = document.createElement('div');
- overlay.style.position = 'fixed';
- overlay.style.top = 0;
- overlay.style.left = 0;
- overlay.style.width = '100%';
- overlay.style.height = '100%';
- overlay.style.backgroundColor = 'rgba(0, 0, 0, 0)';
- overlay.style.backdropFilter = 'blur(0px)';
- overlay.style.transition = 'background-color 300ms ease, backdrop-filter 300ms ease';
- overlay.style.zIndex = '9999';
- overlay.style.pointerEvents = 'auto';
- document.body.appendChild(overlay);
- requestAnimationFrame(() => {
- overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.3)';
- overlay.style.backdropFilter = 'blur(5px)';
- });
- const confirmBox = document.createElement('div');
- confirmBox.style.position = 'fixed';
- confirmBox.style.top = '50%';
- confirmBox.style.left = '50%';
- confirmBox.style.transform = 'translate(-50%, -50%) scale(0.9)';
- confirmBox.style.opacity = '0';
- confirmBox.style.transition = 'transform 250ms ease, opacity 250ms ease';
- confirmBox.style.background = '#1a1a1a';
- confirmBox.style.color = '#fff';
- confirmBox.style.padding = '20px';
- confirmBox.style.borderRadius = '12px';
- confirmBox.style.boxShadow = '0 0 15px rgba(0,0,0,0.5)';
- confirmBox.style.zIndex = '10000';
- confirmBox.innerHTML = `<p style="font-size:16px;margin-bottom:15px;">Er du sikker på, at du vil slette <strong>${count}</strong> besked(er)?</p>`;
- const btnYes = document.createElement('button');
- btnYes.textContent = '✅ Ja, slet';
- styleButton(btnYes, '#f44336');
- btnYes.style.width = '45%';
- btnYes.style.marginRight = '10%';
- const btnNo = document.createElement('button');
- btnNo.textContent = '❌ Annuller';
- styleButton(btnNo, '#555');
- btnNo.style.width = '45%';
- [btnYes, btnNo].forEach(btn => {
- btn.style.transition = 'transform 150ms ease';
- btn.addEventListener('mouseenter', () => btn.style.transform = 'scale(1.05)');
- btn.addEventListener('mouseleave', () => btn.style.transform = 'scale(1)');
- });
- const removePopup = () => {
- overlay.style.backgroundColor = 'rgba(0, 0, 0, 0)';
- overlay.style.backdropFilter = 'blur(0px)';
- confirmBox.style.opacity = '0';
- confirmBox.style.transform = 'translate(-50%, -50%) scale(0.9)';
- setTimeout(() => {
- confirmBox.remove();
- overlay.remove();
- }, 250);
- };
- btnYes.addEventListener('click', () => {
- removePopup();
- onConfirm();
- });
- btnNo.addEventListener('click', () => {
- removePopup();
- });
- confirmBox.appendChild(btnYes);
- confirmBox.appendChild(btnNo);
- document.body.appendChild(confirmBox);
- requestAnimationFrame(() => {
- confirmBox.style.opacity = '1';
- confirmBox.style.transform = 'translate(-50%, -50%) scale(1)';
- });
- };
- const createUI = () => {
- setInterval(() => {
- const isSentView = window.location.href.includes("/Folder/0");
- const existingBanner = document.getElementById('sent-mode-banner');
- if (isSentView && !existingBanner) {
- const sentModeBanner = document.createElement('div');
- sentModeBanner.id = 'sent-mode-banner';
- sentModeBanner.textContent = '📤 Du ser sendte beskeder';
- sentModeBanner.style.backgroundColor = '#444';
- sentModeBanner.style.color = '#ffc107';
- sentModeBanner.style.padding = '8px';
- sentModeBanner.style.borderRadius = '8px';
- sentModeBanner.style.marginBottom = '10px';
- sentModeBanner.style.textAlign = 'center';
- uiContainer.appendChild(sentModeBanner);
- } else if (!isSentView && existingBanner) {
- existingBanner.remove();
- }
- }, 1000);
- // Create help popup elements
- const helpOverlay = document.createElement('div');
- helpOverlay.className = 'help-overlay';
- const helpPopup = document.createElement('div');
- helpPopup.className = 'help-popup';
- helpPopup.innerHTML = `
- <h2>Brugsanvisning</h2>
- <ol>
- <li>Klik "🔎 Find alle besked ID(er)" for at samle ID'erne.</li>
- <li>Udfyld antallet af beskeder, du vil beholde fra toppen af indbakken.</li>
- <li>Klik "🗑️ Slet Beskeder" for at starte sletningen.</li>
- <li>Du kan manuelt fjerne ID(er) på enkelte beskeder fra bunden eller midten af mængden, hvis du ønsker det. Rækkefølgen på ID(erne) i tekstfeltet er den samme som i indbakken.</li>
- <li>⛔ Du kan afbryde sletningen med "Annuller".</li>
- <li>✅ Når sletningen er færdig, genindlæses siden automatisk.</li>
- </ol>
- <button class="close-help">×</button>
- `;
- document.body.appendChild(helpOverlay);
- document.body.appendChild(helpPopup);
- // Help popup controls
- document.querySelector('.close-help').addEventListener('click', () => {
- helpOverlay.style.display = 'none';
- helpPopup.style.display = 'none';
- });
- helpOverlay.addEventListener('click', (e) => {
- if (e.target === helpOverlay) {
- helpOverlay.style.display = 'none';
- helpPopup.style.display = 'none';
- }
- });
- const uiContainer = document.createElement('div');
- uiContainer.style.width = '300px';
- uiContainer.style.position = 'fixed';
- uiContainer.style.top = '85px';
- uiContainer.style.right = '2px';
- uiContainer.style.backgroundColor = '#1a1a1a';
- uiContainer.style.color = '#f1f1f1';
- uiContainer.style.padding = '20px';
- uiContainer.style.borderRadius = '15px';
- uiContainer.style.boxShadow = '0 6px 12px rgba(0, 0, 0, 0.3)';
- uiContainer.style.zIndex = '9999';
- uiContainer.style.fontFamily = "'Arial', sans-serif";
- uiContainer.style.display = 'none';
- const header = document.createElement('div');
- header.innerHTML = '🗑️ <strong>Viggo Besked Sletter</strong>';
- header.style.marginBottom = '15px';
- header.style.fontSize = '18px';
- uiContainer.appendChild(header);
- const label = document.createElement('label');
- label.textContent = 'Skriv Besked ID(er) (komma-separeret):';
- label.style.display = 'block';
- label.style.marginBottom = '5px';
- const textarea = document.createElement('textarea');
- textarea.style.width = '100%';
- textarea.style.height = '100px';
- textarea.style.padding = '10px';
- textarea.style.borderRadius = '10px';
- textarea.style.border = '1px solid #333';
- textarea.style.marginBottom = '15px';
- textarea.style.backgroundColor = '#2b2b2b';
- textarea.style.color = '#f1f1f1';
- textarea.style.resize = 'none';
- const extractButton = document.createElement('button');
- extractButton.textContent = '🔎 Find alle besked ID(er)';
- styleButton(extractButton, '#4CAF50');
- extractButton.addEventListener('click', () => {
- document.getElementById("message-list").style.pointerEvents = "none";
- document.getElementById("message-list").style.userSelect = "none";
- document.getElementById("message-list").style.opacity = "0.6";
- (function autoScrollMessageList() {
- const element = document.getElementById('message-list');
- if (!element) return console.warn('Element #message-list not found');
- const interval = setInterval(() => {
- const maxScroll = element.scrollHeight - element.clientHeight;
- const currentScroll = element.scrollTop;
- element.scrollTop += 10;
- if (currentScroll >= maxScroll - 1) {
- clearInterval(interval);
- const messageIds = extractMessageIds();
- textarea.value = messageIds.join(', ');
- console.log('Reached bottom of #message-list');
- document.getElementById("message-list").style.pointerEvents = "auto";
- document.getElementById("message-list").style.userSelect = "auto";
- document.getElementById("message-list").style.opacity = "1";
- // Update deletion marks
- const topCount = parseInt(topExclusionInput.value) || 0;
- const allIds = textarea.value.split(',').map(id => id.trim()).filter(Boolean);
- const idsToDelete = topCount > 0 ? allIds.slice(topCount) : allIds;
- markMessagesForDeletion(idsToDelete);
- }
- }, 1);
- })();
- });
- const topExclusionLabel = document.createElement('label');
- topExclusionLabel.textContent = 'Antal beskeder der skal beholdes fra toppen:';
- topExclusionLabel.style.display = 'block';
- topExclusionLabel.style.marginBottom = '5px';
- const topExclusionInput = document.createElement('input');
- topExclusionInput.type = 'number';
- styleInput(topExclusionInput);
- topExclusionInput.addEventListener('input', () => {
- const topCount = parseInt(topExclusionInput.value) || 0;
- const allIds = textarea.value.split(',').map(id => id.trim()).filter(Boolean);
- const idsToDelete = topCount > 0 ? allIds.slice(topCount) : allIds;
- markMessagesForDeletion(idsToDelete);
- });
- const statusText = document.createElement('div');
- statusText.style.marginBottom = '10px';
- const progressBar = document.createElement('progress');
- progressBar.style.width = '100%';
- progressBar.max = 100;
- progressBar.value = 0;
- const cancelButton = document.createElement('button');
- cancelButton.textContent = '⛔ Annuller';
- styleButton(cancelButton, '#555');
- cancelButton.style.marginTop = '10px';
- cancelButton.addEventListener('click', () => {
- cancelRequested = true;
- });
- const deleteButton = document.createElement('button');
- deleteButton.textContent = '🗑️ Slet Beskeder';
- styleButton(deleteButton, '#f44336');
- deleteButton.addEventListener('click', () => {
- cancelRequested = false;
- const topCount = parseInt(topExclusionInput.value) || 0;
- const allIds = textarea.value.split(',').map(id => id.trim()).filter(Boolean);
- const idsToDelete = topCount > 0 ? allIds.slice(topCount) : allIds;
- if (idsToDelete.length === 0) {
- statusText.textContent = 'Ingen beskeder valgt.';
- return;
- }
- showConfirmation(idsToDelete.length, async () => {
- deleteButton.disabled = true;
- deleteButton.style.opacity = '0.5';
- deleteButton.textContent = '⏳ Sletter...';
- statusText.textContent = `Sletter 0 / ${idsToDelete.length}`;
- const loadingContainer = showLoadingEffect();
- await deleteMessages(idsToDelete, statusText, progressBar, loadingContainer);
- deleteButton.disabled = false;
- deleteButton.style.opacity = '1';
- deleteButton.textContent = '🗑️ Slet Beskeder';
- });
- });
- const helpButton = document.createElement('button');
- helpButton.textContent = '📘 Brugsanvisning';
- styleButton(helpButton, '#007BFF');
- helpButton.addEventListener('click', () => {
- helpOverlay.style.display = 'block';
- helpPopup.style.display = 'block';
- });
- uiContainer.appendChild(label);
- uiContainer.appendChild(textarea);
- uiContainer.appendChild(extractButton);
- uiContainer.appendChild(topExclusionLabel);
- uiContainer.appendChild(topExclusionInput);
- uiContainer.appendChild(deleteButton);
- uiContainer.appendChild(cancelButton);
- uiContainer.appendChild(statusText);
- uiContainer.appendChild(progressBar);
- uiContainer.appendChild(helpButton);
- document.body.appendChild(uiContainer);
- const toggleButton = document.createElement('button');
- toggleButton.textContent = '🔽 Åben Sletter';
- toggleButton.id = 'customToggleButton';
- toggleButton.style.position = 'fixed';
- toggleButton.style.top = '41px';
- toggleButton.style.right = '-2px';
- toggleButton.style.backgroundColor = '#2b2a2d';
- toggleButton.style.color = '#f1f1f1';
- toggleButton.style.padding = '8px 14px';
- toggleButton.style.border = 'none';
- toggleButton.style.cursor = 'pointer';
- toggleButton.style.width = '164px';
- toggleButton.style.fontSize = '18px';
- toggleButton.style.zIndex = '10000';
- toggleButton.addEventListener('click', () => {
- const isVisible = uiContainer.style.display === 'block';
- uiContainer.style.display = isVisible ? 'none' : 'block';
- toggleButton.textContent = isVisible ? '🔽 Åben Sletter' : '🔼 Luk Sletter';
- toggleButton.classList.toggle('active');
- });
- document.body.appendChild(toggleButton);
- const style = document.createElement('style');
- style.textContent = `
- #customToggleButton {
- border-radius: 0 0 0 5px;
- position: relative;
- overflow: hidden;
- background-color: rgba(43, 42, 45, 1);
- }
- #customToggleButton::after {
- content: '';
- position: absolute;
- bottom: 0;
- left: 50%;
- height: 2px;
- width: 0%;
- background-color: #f1f1f1;
- transition: width 0.3s ease, left 0.3s ease;
- transform: translateX(-50%);
- }
- #customToggleButton::after {
- content: '';
- position: absolute;
- bottom: 0;
- left: 50%;
- height: 2px;
- width: 0%;
- background-color: #f1f1f1;
- transform: translateX(-50%);
- transition: none;
- }
- #customToggleButton:hover::after {
- width: 100%;
- left: 0;
- transform: none;
- transition: width 0.3s ease, left 0.3s ease;
- }
- #customToggleButton:hover {
- background-color: rgba(43, 42, 45, 0.1);
- }
- #customToggleButton:focus {
- outline: none;
- box-shadow: none;
- }
- #customToggleButton:hover::after {
- width: 100%;
- left: 0;
- transform: none;
- }
- #customToggleButton.active::after {
- background-color: #117596;
- height: 4px;
- }
- `;
- document.head.appendChild(style);
- };
- createUI();
- monitorFolderChange();
- })();
- })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement