WME PLN Module - Stats Handler

Módulo de estadísticas para WME Place Normalizer. No funciona por sí solo.

Este script no debería instalarse directamente. Es una biblioteca que utilizan otros scripts mediante la meta-directiva de inclusión // @require https://update.greasyforks.org/scripts/548858/1657861/WME%20PLN%20Module%20-%20Stats%20Handler.js

// ==UserScript==
// @name         WME PLN Module - Stats Handler
// @version      9.0.0
// @description  Módulo de estadísticas para WME Place Normalizer. No funciona por sí solo.
// @author       mincho77
// @license      MIT
// @grant        none
// ==/UserScript==
// Clave para almacenar las estadísticas en localStorage
const STATS_STORAGE_KEY = (window.PLN_META ? `WME_PLN_stats_${window.PLN_META.version}` : 'WME_PLN_stats');
let statsPanelElement = null;
// Crea el panel de estadísticas flotante en la interfaz de usuario.
function createStatsPanel()
{
    // Evitar crear múltiples paneles
    if (document.getElementById('wme-pln-stats-panel')) return;
    // Contenedor principal del panel
    statsPanelElement = document.createElement('div');
    statsPanelElement.id = 'wme-pln-stats-panel';
    statsPanelElement.setAttribute('role', 'region');
    statsPanelElement.setAttribute('aria-label', 'NrmliZer Stats');
    plnLog('ui', '[stats] Panel de estadísticas creado');
    Object.assign(statsPanelElement.style, 
    {
        position: 'fixed',
        bottom: '60px',
        left: '23%', // <-- Ancla el panel a 20px del borde izquierdo
        // Se elimina la propiedad 'transform' que ya no es necesaria
        backgroundColor: 'rgba(45, 45, 45, 0.9)',
        color: 'white',
        padding: '5px 12px',
        borderRadius: '15px',
        fontSize: '13px',
        fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
        zIndex: '10000',
        cursor: 'pointer',
        display: 'none', // Oculto inicialmente
        border: '1px solid #555',
        boxShadow: '0 2px 10px rgba(0,0,0,0.5)',
        userSelect: 'none',
        whiteSpace: 'nowrap'
    });
    // Vista de resumen (la que siempre está visible)
    const summaryView = document.createElement('div');
    summaryView.id = 'stats-summary-view';
    Object.assign(summaryView.style, 
        {
        display: 'flex',
        alignItems: 'center',
        gap: '6px'
    });
    // Texto resumen
    const summaryText = document.createElement('span');
    summaryText.id = 'stats-summary-text';
    summaryText.textContent = '📊 0 NrmliZer Stats';
    // Flecha desplegable
    const dropdownArrow = document.createElement('span');
    dropdownArrow.id = 'stats-arrow';
    dropdownArrow.textContent = '▼';
    dropdownArrow.style.fontSize = '10px';
    // Ensamblar la vista de resumen
    summaryView.appendChild(summaryText);
    summaryView.appendChild(dropdownArrow);
    // Vista detallada (la que se expande)
    const detailView = document.createElement('div');
    detailView.id = 'stats-detail-view';
    Object.assign(detailView.style, {
        display: 'none',
        marginTop: '8px',
        paddingTop: '8px',
        borderTop: '1px solid #666'
    });
    // Lista de estadísticas
    const list = document.createElement('ul');
    Object.assign(list.style, {
        margin: '0',
        padding: '0',
        listStyle: 'none',
        textAlign: 'left'
    });
    // Crear elementos de la lista
    const items = {
        'Hoy': 'stats-count-today',
        'Esta Semana': 'stats-count-week',
        'Este Mes': 'stats-count-month',
        'Total': 'stats-count-total'
    };
    // Recorre los items para crear cada entrada en la lista
    for (const [label, id] of Object.entries(items)) 
    {
        const listItem = document.createElement('li');
        listItem.style.marginBottom = '4px';
        // Etiqueta y contador
        const countBold = document.createElement('b');
        countBold.id = id;
        countBold.textContent = '0';
        // Ensamblar el item
        listItem.append(`${label}: `, countBold);
        list.appendChild(listItem);
    }
    detailView.appendChild(list);
    // Ensamblar el panel
    statsPanelElement.appendChild(summaryView);
    statsPanelElement.appendChild(detailView);
    document.body.appendChild(statsPanelElement);
    // Lógica para desplegar/contraer
    statsPanelElement.addEventListener('click', () => {
        const isHidden = detailView.style.display === 'none';
        detailView.style.display = isHidden ? 'block' : 'none';
        dropdownArrow.textContent = isHidden ? '▲' : '▼';
    });
    // Lógica para cerrar al hacer clic fuera
    document.addEventListener('click', (e) => {
        if (!statsPanelElement.contains(e.target)) 
        {
            detailView.style.display = 'none';
            dropdownArrow.textContent = '▼';
        }
    }, true);
    // Mostrar el panel
    if (typeof window.toggleStatsPanelVisibility === 'function') {
        window.toggleStatsPanelVisibility();
    } else {
        statsPanelElement.style.display = 'block';
    }
}// createStatsPanel

// Muestra los contadores en el panel flotante
function updateStatsDisplay()
{
    // Asegura que el panel y la info del usuario estén disponibles
    if (!statsPanelElement || !window.currentGlobalUserInfo || !window.currentGlobalUserInfo.id) return;
    const userId = String(window.currentGlobalUserInfo.id);
    // Obtiene los datos guardados o valores por defecto si no existen
    const stats = (window.editorStats && window.editorStats[userId]) || 
    {
        daily_count: 0,
        weekly_count: 0,
        monthly_count: 0,
        total_count: 0
    };
    // Actualiza los elementos de la UI con los valores guardados
    const summaryText = statsPanelElement.querySelector('#stats-summary-text');
    const todayCountSpan = statsPanelElement.querySelector('#stats-count-today');
    const weekCountSpan = statsPanelElement.querySelector('#stats-count-week');
    const monthCountSpan = statsPanelElement.querySelector('#stats-count-month');
    const totalCountSpan = statsPanelElement.querySelector('#stats-count-total');
    // Actualiza los textos
    if (summaryText) summaryText.textContent = `📊 ${stats.daily_count || 0} Places NrmliZed`;
    if (todayCountSpan) todayCountSpan.textContent = stats.daily_count || 0;
    if (weekCountSpan) weekCountSpan.textContent = stats.weekly_count || 0;
    if (monthCountSpan) monthCountSpan.textContent = stats.monthly_count || 0;
    if (totalCountSpan) totalCountSpan.textContent = stats.total_count || 0;
    plnLog('ui', `[stats] Display actualizado: hoy=${stats.daily_count||0}, semana=${stats.weekly_count||0}, mes=${stats.monthly_count||0}, total=${stats.total_count||0}`);
}// updateStatsDisplay
// Carga las estadísticas desde localStorage
function loadEditorStats()
{
    // Intenta cargar las estadísticas guardadas
    const savedStats = localStorage.getItem(STATS_STORAGE_KEY);
    if (savedStats)
    {
        try
        {
            window.editorStats = JSON.parse(savedStats);
            if (typeof window.editorStats !== 'object' || window.editorStats === null)
            {
                window.editorStats = {};
            }
        }
        catch (e)
        {
            plnLog('error','[WME PLN Stats] Error al parsear estadísticas desde localStorage:', e);
            window.editorStats = {};
        }
    }
    else
    {
        window.editorStats = {};
    }
}// loadEditorStats

// Guarda las estadísticas en localStorage
function saveEditorStats()
{
    try
    {
        localStorage.setItem(STATS_STORAGE_KEY, JSON.stringify(window.editorStats || {}));
    }
    catch (e)
    {
        plnLog('error','[WME PLN Stats] Error al guardar estadísticas en localStorage:', e);
    }
}// Guarda una acción de normalización para el usuario actual

// Registra una edición y actualiza los contadores
function recordNormalizationEvent()
{
    const user = window.currentGlobalUserInfo || {};
    const userId = user.id;
    const userName = user.name;

    if (!userId || userId === 0 || userName === 'No detectado')
    {
        plnLog('warn','[stats] No se registró evento: usuario no detectado.');
        return;
    }
    // Obtiene las estadísticas del usuario o las inicializa si no existen
    window.editorStats = window.editorStats || {};
    const userKey = String(userId);
    let userStats = window.editorStats[userKey];
    if (!userStats)
    {
        userStats = 
        {
            userName: userName,
            total_count: 0,
            monthly_count: 0,
            monthly_period: "N/A",
            weekly_count: 0,
            weekly_period: "N/A",
            daily_count: 0,
            daily_period: "N/A",
            last_update: 0
        };
        window.editorStats[userKey] = userStats;
    }
    // Obtiene los periodos de tiempo actuales
    const todayStr = PLNCore.utils.getCurrentDateString();
    const weekStr = PLNCore.utils.getCurrentISOWeekString();
    const monthStr = PLNCore.utils.getCurrentMonthString();
    // --- Lógica de reseteo de contadores ---
    // Si la fecha guardada es diferente a la de hoy, resetea el contador diario.
    if (userStats.daily_period !== todayStr)
    {
        userStats.daily_count = 0;
        userStats.daily_period = todayStr;
    }
    // Si la semana guardada es diferente a la de hoy, resetea el contador semanal.
    if (userStats.weekly_period !== weekStr)
    {
        userStats.weekly_count = 0;
        userStats.weekly_period = weekStr;
    }
    // Si el mes guardado es diferente al de hoy, resetea el contador mensual.
    if (userStats.monthly_period !== monthStr)
    {
        userStats.monthly_count = 0;
        userStats.monthly_period = monthStr;
    }
    // --- Incrementar los contadores ---
    userStats.daily_count++;
    userStats.weekly_count++;
    userStats.monthly_count++;
    userStats.total_count++;
    userStats.last_update = Date.now();
    userStats.userName = userName; // Asegurarse de que el nombre esté actualizado
    // Guardar los nuevos datos y actualizar la pantalla
    saveEditorStats();
    updateStatsDisplay();
}// recordNormalizationEvent
长期地址
遇到问题?请前往 GitHub 提 Issues。