Discord Server Search

Search and navigate to a Discord server by name

目前为 2024-10-01 提交的版本。查看 最新版本

// ==UserScript==
// @name         Discord Server Search
// @namespace    Made by @hakav
// @version      1.5
// @description  Search and navigate to a Discord server by name
// @match        https://discord.com/*
// @grant        none
// @icon         https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSrWjmWEq2JeU0yKb2ArlyAAJA4QQLkhbuihw&s
// @licence      @hakav
// ==/UserScript==

(function() {
    'use strict';

    // Create the search icon
    const searchIcon = document.createElement('div');
    searchIcon.innerHTML = '🔍';
    searchIcon.style.position = 'fixed';
    searchIcon.style.bottom = '20px';
    searchIcon.style.right = '20px';
    searchIcon.style.backgroundColor = 'rgba(255, 255, 255, 0.3)'; // Light color with transparency
    searchIcon.style.color = 'black'; // Darker text color to contrast with light background
    searchIcon.style.border = '2px solid rgba(0, 0, 0, 0.3)'; // Subtle border to make it clearer
    searchIcon.style.borderRadius = '50%';
    searchIcon.style.padding = '10px';
    searchIcon.style.cursor = 'pointer';
    searchIcon.style.zIndex = '1000';
    searchIcon.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.2)'; // Slight shadow for more visibility
    searchIcon.style.transition = 'background-color 0.3s ease, box-shadow 0.3s ease, opacity 0.5s ease'; // Smooth transition for blinking
    document.body.appendChild(searchIcon);

    // Add hover effect to make it even clearer when hovering
    searchIcon.onmouseenter = function() {
        searchIcon.style.backgroundColor = 'rgba(255, 255, 255, 0.8)'; // Brighter when hovered
        searchIcon.style.boxShadow = '0 0 15px rgba(0, 0, 0, 0.5)'; // Stronger shadow on hover
    };

    searchIcon.onmouseleave = function() {
        searchIcon.style.backgroundColor = 'rgba(255, 255, 255, 0.3)'; // Return to normal transparency
        searchIcon.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.2)'; // Return to subtle shadow
    };

    // Create the "Designed by @hakav" label
    const designerLabel = document.createElement('div');
    designerLabel.innerHTML = 'Designed by @hakav';
    designerLabel.style.position = 'fixed';
    designerLabel.style.bottom = '60px';
    designerLabel.style.right = '20px';
    designerLabel.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
    designerLabel.style.color = 'white';
    designerLabel.style.padding = '5px 10px';
    designerLabel.style.borderRadius = '5px';
    designerLabel.style.fontFamily = 'Arial, sans-serif';
    designerLabel.style.fontSize = '12px';
    designerLabel.style.zIndex = '1001';
    designerLabel.style.opacity = '0'; // Initially hidden
    designerLabel.style.transition = 'opacity 0.5s ease'; // Smooth fade-in and fade-out
    designerLabel.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.5)';
    document.body.appendChild(designerLabel);

    // Function to show and hide the designer label on click
    const showDesignerLabel = () => {
        designerLabel.style.opacity = '1'; // Fade in
        setTimeout(() => {
            designerLabel.style.opacity = '0'; // Fade out after 3 seconds
        }, 3000); // Display the label for 3 seconds
    };

    // Blinking animation (blinks for 5 seconds after Discord loads)
    function blinkIcon() {
        let blinkInterval = setInterval(() => {
            searchIcon.style.opacity = searchIcon.style.opacity === '0' ? '1' : '0'; // Toggle opacity for blinking effect
        }, 500); // Blink every 500ms

        // Stop blinking after 5 seconds
        setTimeout(() => {
            clearInterval(blinkInterval); // Stop the blinking
            searchIcon.style.opacity = '1'; // Ensure it's fully visible after blinking stops
        }, 5000); // Stop after 5 seconds
    }

    // Run the blink animation when Discord is fully loaded
    window.addEventListener('load', () => {
        blinkIcon(); // Trigger blinking when Discord finishes loading
    });

    // Create the search input popup
    const searchPopup = document.createElement('div');
    searchPopup.style.position = 'fixed';
    searchPopup.style.bottom = '80px';
    searchPopup.style.right = '20px';
    searchPopup.style.backgroundColor = 'white';
    searchPopup.style.padding = '15px';
    searchPopup.style.borderRadius = '5px';
    searchPopup.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.5)';
    searchPopup.style.display = 'none';
    searchPopup.style.zIndex = '1001';
    searchPopup.style.opacity = '0';
    searchPopup.style.transform = 'translateY(20px)';
    searchPopup.style.transition = 'opacity 0.3s ease, transform 0.3s ease';  // Add animation

    const searchInput = document.createElement('input');
    searchInput.placeholder = 'Enter server name...';
    searchInput.style.width = '200px';
    searchPopup.appendChild(searchInput);

    const searchButton = document.createElement('button');
    searchButton.innerText = 'Search';
    searchButton.style.marginLeft = '10px';
    searchButton.onclick = function() {
        const serverName = searchInput.value.trim();
        if (serverName) {
            // Get the list of servers from the sidebar
            const servers = Array.from(document.querySelectorAll('[data-list-id="guildsnav"] [aria-label]'));
            const matchedServer = servers.find(server =>
                server.getAttribute('aria-label').toLowerCase().includes(serverName.toLowerCase())
            );

            if (matchedServer) {
                matchedServer.click(); // Click the server to open it
            } else {
                alert('Server not found!');
            }
        }
    };
    searchPopup.appendChild(searchButton);
    document.body.appendChild(searchPopup);

    // Function to show the popup with animation
    const showPopup = () => {
        searchPopup.style.display = 'block';
        setTimeout(() => {
            searchPopup.style.opacity = '1';
            searchPopup.style.transform = 'translateY(0)';
        }, 10); // Small delay to trigger the transition
    };

    // Function to hide the popup with animation
    const hidePopup = () => {
        searchPopup.style.opacity = '0';
        searchPopup.style.transform = 'translateY(20px)';
        setTimeout(() => {
            searchPopup.style.display = 'none';
        }, 300); // Wait for the transition to complete before hiding
    };

    // Show/hide popup and label on icon click with animation
    searchIcon.onclick = function() {
        if (searchPopup.style.display === 'none' || searchPopup.style.opacity === '0') {
            showPopup();
            showDesignerLabel(); // Show "Designed by @hakav" label when the icon is clicked
            searchInput.focus();
        } else {
            hidePopup();
        }
    };

    // Hide popup when clicking outside with animation
    window.onclick = function(event) {
        if (!searchIcon.contains(event.target) && !searchPopup.contains(event.target)) {
            hidePopup();
        }
    };

})();