Onche Auto-Refresh

Actualise la liste des sujets sur Onche. Intègre une icône d'engrenage discrète pour les réglages.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name         Onche Auto-Refresh
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Actualise la liste des sujets sur Onche. Intègre une icône d'engrenage discrète pour les réglages.
// @author       Bkz1
// @match        https://onche.org/*
// @license MIT
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // ==========================================
    // PARAMÈTRES ET VARIABLES GLOBALES
    // ==========================================

    const TOPIC_LIST_SELECTOR = '.topics';
    let intervalTimerId = null;
    let refreshIntervalSeconds = parseInt(localStorage.getItem('onche_refresh_interval')) || 30;

    // ==========================================
    // LOGIQUE DE RAFRAÎCHISSEMENT (AJAX)
    // ==========================================

    function refreshTopics() {
        const currentUrl = window.location.href;

        fetch(currentUrl)
            .then(response => {
                if (!response.ok) throw new Error('Erreur réseau');
                return response.text();
            })
            .then(html => {
                const parser = new DOMParser();
                const doc = parser.parseFromString(html, 'text/html');
                const newTopicList = doc.querySelector(TOPIC_LIST_SELECTOR);
                const currentTopicList = document.querySelector(TOPIC_LIST_SELECTOR);

                if (newTopicList && currentTopicList) {
                    currentTopicList.innerHTML = newTopicList.innerHTML;
                    console.log(`✅ [Auto-Refresh] Sujets mis à jour (Intervalle : ${refreshIntervalSeconds}s)`);
                }
            })
            .catch(error => console.error('⚠️ [Auto-Refresh] Erreur :', error));
    }

    // ==========================================
    // GESTION DU CHRONOMÈTRE
    // ==========================================

    function startTimer() {
        if (intervalTimerId !== null) {
            clearInterval(intervalTimerId);
        }
        intervalTimerId = setInterval(refreshTopics, refreshIntervalSeconds * 1000);
    }

    // ==========================================
    // INTÉGRATION DE L'ENGRENAGE ET DU MENU
    // ==========================================

    function injectSettingsIntoPage() {
        const topicList = document.querySelector(TOPIC_LIST_SELECTOR);
        if (!topicList) return;

        // 1. Création d'un conteneur "wrapper" qui va englober l'icône et le menu
        // Ce conteneur est en "position: relative" pour que le menu puisse s'afficher juste en dessous de lui
        const wrapper = document.createElement('div');
        wrapper.id = 'onche-refresh-wrapper';
        wrapper.style.position = 'relative';
        wrapper.style.display = 'flex';
        wrapper.style.justifyContent = 'flex-end'; // Aligne l'engrenage tout à droite
        wrapper.style.marginBottom = '8px';
        wrapper.style.paddingRight = '5px';

        // 2. Structure HTML : L'icône ⚙️ et le menu caché par défaut (display: none)
        // Les couleurs sont neutres (rgba) pour s'adapter au mode sombre/clair
        wrapper.innerHTML = `
            <div id="onche-gear-icon" title="Réglages Auto-Refresh"
                 style="cursor: pointer; font-size: 18px; opacity: 0.5; transition: all 0.3s ease; user-select: none;">
                ⚙️
            </div>

            <div id="onche-settings-popup"
                 style="display: none; position: absolute; top: 28px; right: 0; background: rgba(30, 30, 30, 0.95);
                        border: 1px solid rgba(255, 255, 255, 0.1); padding: 12px; border-radius: 8px;
                        box-shadow: 0px 8px 16px rgba(0,0,0,0.5); z-index: 1000; color: #eee; width: max-content; font-family: sans-serif;">

                <div style="margin-bottom: 10px; font-size: 13px; font-weight: bold; border-bottom: 1px solid rgba(255,255,255,0.1); padding-bottom: 5px;">
                    🔄 Auto-Refresh
                </div>

                <div style="display: flex; gap: 8px; align-items: center;">
                    <input type="number" id="onche-refresh-input" value="${refreshIntervalSeconds}" min="5" max="600"
                           style="width: 50px; padding: 4px; border-radius: 4px; border: 1px solid #555; background: #111; color: white; text-align: center; font-size: 13px;">
                    <span style="font-size: 12px;">secondes</span>
                    <button id="onche-refresh-save"
                            style="cursor: pointer; padding: 4px 10px; border-radius: 4px; border: 1px solid #555; background: #333; color: white; font-size: 12px; font-weight: bold; transition: background 0.2s;">
                        OK
                    </button>
                </div>

                <div id="onche-refresh-feedback" style="color: #4ade80; display: none; font-size: 12px; margin-top: 8px; text-align: center; font-weight: bold;">
                    ✔ Intervalle enregistré
                </div>
            </div>
        `;

        // 3. Insertion dans la page, juste au-dessus de la liste des sujets
        topicList.parentNode.insertBefore(wrapper, topicList);

        // 4. Ciblage des éléments que l'on vient de créer
        const gear = document.getElementById('onche-gear-icon');
        const popup = document.getElementById('onche-settings-popup');
        const saveBtn = document.getElementById('onche-refresh-save');

        // 5. Animations au survol de l'engrenage (opacité et rotation)
        gear.addEventListener('mouseenter', () => {
            gear.style.opacity = '1';
            gear.style.transform = 'rotate(45deg)';
        });
        gear.addEventListener('mouseleave', () => {
            gear.style.opacity = '0.5';
            gear.style.transform = 'rotate(0deg)';
        });

        // 6. Afficher/Cacher le menu quand on clique sur l'engrenage
        gear.addEventListener('click', (event) => {
            event.stopPropagation(); // Empêche le clic de se propager au reste de la page
            const isHidden = popup.style.display === 'none';
            popup.style.display = isHidden ? 'block' : 'none';
        });

        // 7. Cacher le menu si on clique n'importe où ailleurs sur la page (ergonomie)
        document.addEventListener('click', (event) => {
            if (popup.style.display === 'block' && !wrapper.contains(event.target)) {
                popup.style.display = 'none';
            }
        });

        // 8. Sauvegarder les paramètres
        saveBtn.addEventListener('click', () => {
            const inputVal = parseInt(document.getElementById('onche-refresh-input').value, 10);

            if (inputVal >= 5) {
                refreshIntervalSeconds = inputVal;
                localStorage.setItem('onche_refresh_interval', refreshIntervalSeconds);
                startTimer();

                // Animation de confirmation
                const feedback = document.getElementById('onche-refresh-feedback');
                feedback.style.display = 'block';

                // On cache le message de confirmation ET le menu après 1.5 secondes
                setTimeout(() => {
                    feedback.style.display = 'none';
                    popup.style.display = 'none';
                }, 1500);
            } else {
                alert("Pour ne pas surcharger les serveurs, le minimum est de 5 secondes.");
                document.getElementById('onche-refresh-input').value = 5;
            }
        });

        // Effet de survol sur le bouton OK
        saveBtn.addEventListener('mouseenter', () => saveBtn.style.background = '#444');
        saveBtn.addEventListener('mouseleave', () => saveBtn.style.background = '#333');
    }

    // ==========================================
    // INITIALISATION DU SCRIPT
    // ==========================================

    if (document.querySelector(TOPIC_LIST_SELECTOR)) {
        injectSettingsIntoPage();
        startTimer();
    }
})();