לדלג לתוכן

משתמשת:Neriah/QuickBlock.js

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

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

  • פיירפוקס / ספארי: להחזיק את המקש Shift בעת לחיצה על טעינה מחדש (Reload) או ללחוץ על צירוף המקשים Ctrl-F5 או Ctrl-R (במחשב מק: ⌘-R).
  • גוגל כרום: ללחוץ על צירוף המקשים Ctrl-Shift-R (במחשב מק: ⌘-Shift-R).
  • אדג': להחזיק את המקש Ctrl בעת לחיצה על רענן (Refresh) או ללחוץ על צירוף המקשים Ctrl-F5.
// סקריפט לחסימה מהירה דרך דף השינויים האחרונים, מחליף את הקישור לדף החסימה המפורט. לשימוש מפעילי מערכת בלבד. 
// נכתב ע"י [[User:Neriah]]
// <nowiki>
mw.loader.using(['mediawiki.util', 'mediawiki.api'], function() {
    mw.util.addCSS(`
        .quick-block-dialog {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            border-radius: 4px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
            z-index: 1000;
            max-width: 600px;
            width: 90%;
            max-height: 80vh;
            overflow-y: auto;
        }
        
        .quick-block-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.5);
            z-index: 999;
        }
        
        .quick-block-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            border-bottom: 1px solid #eee;
            padding-bottom: 10px;
        }
        
        .quick-block-title {
            font-size: 1.2em;
            font-weight: bold;
            margin: 0;
        }
        
        .quick-block-close {
            background: none;
            border: none;
            cursor: pointer;
            padding: 5px;
            font-size: 1.2em;
        }
        
        .quick-block-button-group {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
            gap: 8px;
            margin-bottom: 1em;
        }
        
        .quick-block-button {
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background: white;
            cursor: pointer;
            min-height: 32px;
            transition: all 0.2s ease;
        }
        
        .quick-block-button.selected {
            background-color: #36c;
            color: white;
            font-weight: bold;
        }
        
        .quick-block-reason-group {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 8px;
            margin-bottom: 1em;
        }
        
        .quick-block-custom-input {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            margin-top: 8px;
            display: none;
        }
        
        .quick-block-field {
            margin-bottom: 16px;
        }
        
        .quick-block-label {
            display: block;
            margin-bottom: 8px;
            font-weight: bold;
        }
        
        .quick-block-actions {
            display: flex;
            justify-content: flex-end;
            gap: 8px;
            margin-top: 20px;
        }
        
        .quick-block-submit {
            background: #36c;
            color: white;
            border: none;
            padding: 8px 16px;
            border-radius: 4px;
            cursor: pointer;
        }
        
        .quick-block-cancel {
            background: #eee;
            border: none;
            padding: 8px 16px;
            border-radius: 4px;
            cursor: pointer;
        }
    `);

    class QuickBlockDialog {
        constructor(username) {
            this.username = username;
            this.isIP = mw.util.isIPAddress(username);
            this.selectedDuration = this.isIP ? '6 hours' : 'infinite';
            this.selectedReason = '';
            this.createDialog();
        }

        createDialog() {
            this.overlay = document.createElement('div');
            this.overlay.className = 'quick-block-overlay';
            
            this.dialog = document.createElement('div');
            this.dialog.className = 'quick-block-dialog';
            
            this.dialog.innerHTML = `
                <div class="quick-block-header">
                    <h3 class="quick-block-title">חסימת ${this.username}</h3>
                    <button class="quick-block-close">×</button>
                </div>
                
                <div class="quick-block-field">
                    <label class="quick-block-label">משך החסימה</label>
                    <div class="quick-block-button-group" id="duration-buttons"></div>
                    <input type="text" class="quick-block-custom-input" id="custom-duration" placeholder="קציבת זמן החסימה (בפורמט 3 days, 2 weeks, 1 month)">
                </div>
                
                <div class="quick-block-field">
                    <label class="quick-block-label">סיבת החסימה</label>
                    <div class="quick-block-reason-group" id="reason-buttons"></div>
                    <input type="text" class="quick-block-custom-input" id="custom-reason" placeholder="סיבת חסימה">
                </div>
                
                <div class="quick-block-field">
                    <label>
                        <input type="checkbox" id="block-talk"> חסימת דף השיחה האישי
                    </label>
                </div>
                
                <div class="quick-block-actions">
                    <button class="quick-block-cancel">ביטול</button>
                    <button class="quick-block-submit">חסום</button>
                </div>
            `;
            
            this.setupButtons();
            this.setupEventListeners();
            
            document.body.appendChild(this.overlay);
            document.body.appendChild(this.dialog);
        }

        setupButtons() {
            const durations = [
                { data: '2 hours', label: 'שעתיים' },
                { data: '6 hours', label: '6 שעות' },
                { data: '24 hours', label: 'יום' },
                { data: '1 week', label: 'שבוע' },
                { data: '2 weeks', label: 'שבועיים' },
                { data: '1 month', label: 'חודש' },
                { data: '1 year', label: 'שנה' },
                { data: 'infinite', label: 'זמן בלתי מוגבל' },
                { data: 'custom', label: 'זמן אחר' }
            ];

            const reasons = [
                { data: 'השחתה לאחר אזהרה ([[תבנית:נחסמת|מידע נוסף]])', label: 'השחתה' },
                { data: 'הפרעה ([[תבנית:נחסמת|מידע נוסף]])', label: 'הפרעה' },
                { data: 'הסרת תוכן ([[תבנית:נחסמת|מידע נוסף]])', label: 'הסרת תוכן' },
                { data: 'טרול ([[ויקיפדיה:התמודדות עם טרולים|מידע נוסף]])', label: 'טרול' },
                { data: 'custom', label: 'סיבה אחרת' }
            ];

            const durationContainer = this.dialog.querySelector('#duration-buttons');
            const reasonContainer = this.dialog.querySelector('#reason-buttons');

            durations.forEach(duration => {
                const button = document.createElement('button');
                button.className = 'quick-block-button';
                if (duration.data === this.selectedDuration) {
                    button.classList.add('selected');
                }
                button.textContent = duration.label;
                button.dataset.duration = duration.data;
                durationContainer.appendChild(button);
            });

            reasons.forEach(reason => {
                const button = document.createElement('button');
                button.className = 'quick-block-button';
                button.textContent = reason.label;
                button.dataset.reason = reason.data;
                reasonContainer.appendChild(button);
            });
        }

        setupEventListeners() {
            this.dialog.querySelector('.quick-block-close').addEventListener('click', () => this.close());
            this.overlay.addEventListener('click', () => this.close());
            this.dialog.querySelector('.quick-block-cancel').addEventListener('click', () => this.close());
            this.dialog.querySelector('.quick-block-submit').addEventListener('click', () => this.handleBlock());

            this.dialog.querySelectorAll('#duration-buttons .quick-block-button').forEach(button => {
                button.addEventListener('click', (e) => {
                    this.dialog.querySelectorAll('#duration-buttons .quick-block-button').forEach(b => b.classList.remove('selected'));
                    button.classList.add('selected');
                    this.selectedDuration = button.dataset.duration;
                    this.dialog.querySelector('#custom-duration').style.display = 
                        this.selectedDuration === 'custom' ? 'block' : 'none';
                });
            });

            this.dialog.querySelectorAll('#reason-buttons .quick-block-button').forEach(button => {
                button.addEventListener('click', (e) => {
                    this.dialog.querySelectorAll('#reason-buttons .quick-block-button').forEach(b => b.classList.remove('selected'));
                    button.classList.add('selected');
                    this.selectedReason = button.dataset.reason;
                    this.dialog.querySelector('#custom-reason').style.display = 
                        this.selectedReason === 'custom' ? 'block' : 'none';
                });
            });
        }

        async handleBlock() {
            let finalDuration = this.selectedDuration;
            if (finalDuration === 'custom') {
                finalDuration = this.dialog.querySelector('#custom-duration').value;
                if (!finalDuration) {
                    mw.notify('יש להזין משך חסימה', {type: 'error'});
                    return;
                }
            }

            let finalReason = this.selectedReason;
            if (finalReason === 'custom') {
                finalReason = this.dialog.querySelector('#custom-reason').value;
                if (!finalReason) {
                    mw.notify('יש להזין סיבת חסימה', {type: 'error'});
                    return;
                }
            }

            const blockTalk = this.dialog.querySelector('#block-talk').checked;
            const api = new mw.Api();

            try {
                await api.postWithToken('csrf', {
                    action: 'block',
                    user: this.username,
                    expiry: finalDuration,
                    reason: finalReason,
                    nocreate: true,
                    autoblock: true,
                    noemail: true,
                    allowusertalk: !blockTalk
                });

                await api.postWithToken('csrf', {
                    action: 'edit',
                    title: 'שיחת משתמש:' + this.username,
                    section: 'new',
                    sectiontitle: 'נחסמת',
                    text: '{{נחסמת|' + finalReason + '}}~~~~',
                    summary: 'הודעת חסימה'
                });

                mw.notify('המשתמש ' + this.username + ' נחסם בהצלחה והודעת חסימה נשלחה לדף שיחתו', {type: 'success'});
                this.close();
                location.reload();
            } catch (error) {
                console.error('Block error:', error);
                mw.notify('שגיאה בחסימת המשתמש: ' + (error.message || 'שגיאה לא ידועה'), {type: 'error'});
            }
        }

        close() {
            this.overlay.remove();
            this.dialog.remove();
        }
    }

    $(document).ready(function() {
        $('.mw-changeslist').find('.mw-usertoollinks-block').each(function() {
            const $blockLink = $(this);
            const $userLink = $blockLink.closest('li').find('.mw-userlink');
            const username = $userLink.text().trim();
            
            if (!username) {
                console.error('לא נמצא שם משתמש עבור ביצוע החסימה:', $blockLink);
                return;
            }
            
            $blockLink.on('click', function(e) {
                e.preventDefault();
                new QuickBlockDialog(username);
            });
        });
    });
});
// </nowiki>