לדלג לתוכן

משתמש:ממוני גבך/כמה חסר לזכות הצבעה.js

מתוך המכלול, האנציקלופדיה היהודית

לתשומת ליבך: לאחר הפרסום, ייתכן שיהיה צורך לנקות את זיכרון המטמון (cache) של הדפדפן כדי להבחין בשינויים.

  • פיירפוקס / ספארי: להחזיק את המקש Shift בעת לחיצה על טעינה מחדש (Reload) או ללחוץ על צירוף המקשים Ctrl-F5 או Ctrl-R (במחשב מק: ⌘-R).
  • גוגל כרום: ללחוץ על צירוף המקשים Ctrl-Shift-R (במחשב מק: ⌘-Shift-R).
  • אדג': להחזיק את המקש Ctrl בעת לחיצה על רענן (Refresh) או ללחוץ על צירוף המקשים Ctrl-F5.
/**
 * סקריפט לבדיקת חוסר בעריכות לזכות הצבעה במכלול
 * בודק 100 עריכות ב-90 הימים האחרונים במרחבי התוכן המשיקים בלבד.
 * מרחבי תוכן: ראשי (0), קבצים (6), תבניות (10), קטגוריות (14), פורטלים (100), יחידות (828).
 * החרגות: דפי שיחה אינם נספרים. תבניות "תיבת משתמש" אינן נספרות.
 */
(function () {
    const REQUIRED_EDITS = 100;
    const DAYS_LIMIT = 90;

    // מזהי מרחבי השם המשיקים (מרחבי תוכן בלבד - זוגיים)
    const NAMESPACES_MAP = {
        0: 'ערכים',
        6: 'קבצים',
        10: 'תבניות',
        14: 'קטגוריות',
        100: 'פורטלים',
        828: 'יחידות'
    };
    const CONTENT_NAMESPACES = Object.keys(NAMESPACES_MAP).join('|');

    async function checkVotingRights() {
        let targetUser = mw.config.get('wgRelevantUserName') || mw.config.get('wgUserName');

        if (!targetUser) {
            mw.notify('לא נמצא משתמש לבדיקה.');
            return;
        }

        showInitialModal(targetUser);

        const dateLimit = new Date();
        dateLimit.setDate(dateLimit.getDate() - DAYS_LIMIT);
        const ucend = dateLimit.toISOString();

        try {
            const response = await $.ajax({
                url: mw.util.wikiScript('api'),
                data: {
                    action: 'query',
                    list: 'usercontribs',
                    ucuser: targetUser,
                    ucnamespace: CONTENT_NAMESPACES,
                    uclimit: 'max', 
                    ucend: ucend,   
                    ucprop: 'timestamp|title|ns|revid|tags',
                    format: 'json'
                }
            });

            if (!response.query || !response.query.usercontribs) {
                throw new Error("מבנה נתונים לא תקין");
            }

            // סינון וסיווג עריכות
            const stats = { 0: 0, 6: 0, 10: 0, 14: 0, 100: 0, 828: 0 };
            const filteredEdits = response.query.usercontribs.filter(edit => {
                // החרגת תיבות משתמש במרחב תבנית
                if (edit.ns === 10 && edit.title.includes('תיבת משתמש')) {
                    return false;
                }
                
                // ספירה לסטטיסטיקה
                if (stats[edit.ns] !== undefined) {
                    stats[edit.ns]++;
                }
                return true;
            });

            const editsCount = filteredEdits.length;
            const hasMore = !!response.continue;
            
            updateModalWithResults(targetUser, editsCount, filteredEdits, hasMore, stats);

        } catch (error) {
            console.error("Error fetching contributions:", error);
            $('#vote-checker-content').html('<p style="color: #d33;">אירעה שגיאה במשיכת הנתונים. ודאו שאתם מחוברים.</p>');
        }
    }

    function showInitialModal(username) {
        $('#vote-checker-modal, #modal-overlay').remove();

        const modalHtml = `
            <div id="modal-overlay" style="position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.2); z-index:9999;"></div>
            <div id="vote-checker-modal" style="position:fixed; top:50%; left:50%; transform:translate(-50%, -50%); background:#fff; color:#202122; border:1px solid #a2a9b1; padding:0; z-index:10000; box-shadow:0 4px 15px rgba(0,0,0,0.15); border-radius:4px; min-width:450px; text-align:right; font-family: system-ui, -apple-system, sans-serif; direction: rtl;">
                <div style="background:#f8f9fa; border-bottom:1px solid #a2a9b1; padding:12px 15px; font-weight:bold; display:flex; justify-content:space-between; align-items:center; border-radius:4px 4px 0 0;">
                    <span style="font-size:1.1em;">בדיקת זכות הצבעה (מרחבים משיקים)</span>
                    <span id="close-vote-modal-x" style="cursor:pointer; font-size:22px; color:#72777d; line-height:1;">&times;</span>
                </div>
                <div id="vote-checker-content" style="padding:20px 15px; max-height: 500px; overflow-y: auto;">
                    <div style="display:flex; align-items:center; gap:12px;">
                        <img src="https://upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif" alt="טוען...">
                        <span>מנתח עריכות עבור <b>${username}</b>...</span>
                    </div>
                </div>
                <div style="padding:12px 15px; background:#f8f9fa; border-top:1px solid #a2a9b1; text-align:left; border-radius:0 0 4px 4px;">
                    <button id="close-vote-modal-btn" style="padding:6px 16px; cursor:pointer; background:#36c; color:#fff; border:1px solid #36c; border-radius:2px; font-weight:bold; font-size:13px;">סגור</button>
                </div>
            </div>
        `;

        $('body').append(modalHtml);

        $('#close-vote-modal-btn, #close-vote-modal-x, #modal-overlay').on('click', function() {
            $('#vote-checker-modal, #modal-overlay').remove();
        });
    }

    function updateModalWithResults(username, count, filteredEdits, hasMore, stats) {
        let titleColor = "#36c";
        const isEligible = count >= REQUIRED_EDITS || hasMore;
        const countDisplay = hasMore ? "מעל 500" : count;

        // בניית רשימת עריכות
        const recentEditsList = filteredEdits.map((edit, index) => {
            const time = new Date(edit.timestamp).toLocaleTimeString('he-IL', {hour: '2-digit', minute:'2-digit'});
            const date = new Date(edit.timestamp).toLocaleDateString('he-IL', {day: '2-digit', month:'2-digit'});
            
            // הקישור מוביל כעת ישירות לערך עצמו
            const pageUrl = mw.util.getUrl(edit.title);

            return `
                <li style="font-size: 0.85em; border-bottom: 1px solid #eee; padding: 4px 0; display: flex; justify-content: space-between; align-items: center;">
                    <span style="color: #72777d; min-width: 90px; font-size: 0.9em;">${index + 1}. ${date} ${time}</span>
                    <a href="${pageUrl}" target="_blank" style="text-decoration: none; color: #36c; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 280px; flex-grow: 1; text-align: right; margin-right: 10px;" title="מעבר לדף: ${edit.title}">
                        ${edit.title}
                    </a>
                </li>
            `;
        }).join('');

        let statsHtml = `
            <div id="vote-details" style="display:none; margin-top:15px; padding:10px; background:#f1f3f5; border-radius:4px; font-size:0.9em;">
                <div style="font-weight:bold; border-bottom:1px solid #ccc; margin-bottom:8px; padding-bottom:3px;">סיכום לפי מרחבים:</div>
                <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5px; margin-bottom: 15px;">
                    ${Object.entries(NAMESPACES_MAP).map(([id, name]) => `
                        <div style="display:flex; justify-content:space-between; background: #fff; padding: 4px 8px; border: 1px solid #e2e2e2; border-radius: 2px;">
                            <span>${name}:</span>
                            <span style="font-weight:bold;">${stats[id]}</span>
                        </div>
                    `).join('')}
                </div>
                
                <div style="font-weight:bold; border-bottom:1px solid #ccc; margin-bottom:8px; padding-bottom:3px;">רשימת העריכות שנספרו (לחיצה למעבר לערך):</div>
                <div style="max-height: 250px; overflow-y: auto; background: #fff; padding: 5px 10px; border: 1px solid #e2e2e2; border-radius: 2px;">
                    <ul style="list-style:none; padding:0; margin:0;">
                        ${recentEditsList || '<li>לא נמצאו עריכות בטווח הזמן.</li>'}
                    </ul>
                </div>
                <div style="text-align: center; color: #72777d; font-size: 0.8em; margin-top: 8px;">סה"כ מוצגות ${filteredEdits.length} עריכות</div>
            </div>
        `;

        let message = "";
        if (isEligible) {
            titleColor = "#14866d"; 
            message = `
                <div style="color:${titleColor}; font-weight:bold; margin-bottom:12px; font-size:1.2em; border-right:4px solid ${titleColor}; padding-right:10px;">נמצאה זכות הצבעה!</div>
                למשתמש יש <b>${countDisplay}</b> עריכות במרחבי התוכן ב-90 הימים האחרונים.
            `;
        } else {
            titleColor = "#d33"; 
            const missing = REQUIRED_EDITS - count;
            message = `
                <div style="color:${titleColor}; font-weight:bold; margin-bottom:12px; font-size:1.2em; border-right:4px solid ${titleColor}; padding-right:10px;">אין זכות הצבעה כרגע</div>
                נמצאו רק <b>${count}</b> עריכות במרחבי התוכן ב-90 הימים האחרונים.
                <br>חסרות עוד <b>${missing}</b> עריכות להשלמת המכסה.
            `;
        }

        message += `
            <div style="margin-top:15px; font-size:0.9em; color:#54595d;">
                <button id="toggle-stats" style="background:#eaecf0; border:1px solid #a2a9b1; color:#202122; cursor:pointer; padding:4px 12px; border-radius:2px; font-size:0.9em; font-weight: bold;">הצג פירוט וכל העריכות שנספרו</button>
            </div>
            ${statsHtml}
        `;

        $('#vote-checker-content').html(message);

        $('#toggle-stats').on('click', function() {
            const isVisible = $('#vote-details').is(':visible');
            $(this).text(isVisible ? 'הצג פירוט וכל העריכות שנספרו' : 'הסתר פירוט עריכות');
            $('#vote-details').slideToggle();
        });
    }

    $(document).ready(function () {
        const link = mw.util.addPortletLink(
            'p-tb',
            '#',
            'כמה חסר לזכות הצבעה',
            't-check-missing-edits',
            'בדיקה כמה עריכות חסרות במרחבי התוכן ב-90 הימים האחרונים'
        );

        if (link) {
            $(link).on('click', function (e) {
                e.preventDefault();
                checkVotingRights();
            });
        }
    });
})();