User:Euphoria/common.js

From Test Wiki
Revision as of 07:50, 25 September 2025 by Euphoria (talk | contribs) (fix)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
//<nowiki>
$(() => {
    const VfDResolver = {
        config: {
            vfdPrefix: 'User:Euphoria/TestVfD/' // or 'Wikiquote:Votes_for_deletion/'
        },

        actionOptions: [
            { data: 'delete', label: 'Close as delete' },
            { data: 'keep', label: 'Close as keep' },
            { data: 'no consensus', label: 'Close as no consensus' }
        ],

        init() {
            const currentPage = mw.config.get('wgPageName');
            if (!currentPage.startsWith(this.config.vfdPrefix)) return;

            mw.loader.using(['oojs-ui', 'mediawiki.util', 'mediawiki.api'], this.run.bind(this));
        },

        run() {
            this.addStyle();
            this.addButtons();
        },

        addStyle() {
            const darkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
            const bg = darkMode ? '#202122' : '#f5f5f5';
            const border = darkMode ? '#343434' : '#ccc';
            const text = darkMode ? '#eaecf0' : '#000';
            const previewBg = darkMode ? '#101418' : 'white';

            mw.util.addCSS(`
                .vfd-closure-panel {
                    background-color: ${bg};
                    border: 1px solid ${border};
                    margin: 10px 0;
                    padding: 10px;
                    border-radius: 5px;
                    color: ${text};
                    position: relative;
                }
                .vfd-closure-preview {
                    background-color: ${previewBg};
                    color: ${text};
                    border: 1px solid ${border};
                    padding: 10px;
                    margin: 10px 0;
                    border-radius: 3px;
                }
                .vfd-closure-copy-icons {
                    display: flex;
                    gap: 6px;
                    position: absolute;
                    right: 8px;
                    bottom: 5px;
                    z-index: 10;
                }
                .vfd-closure-copy-icon {
                    width: 16px;
                    height: 16px;
                    cursor: pointer;
                    opacity: 0.7;
                    transition: opacity 0.1s;
                    background: none;
                    border: none;
                    padding: 0;
                }
                .vfd-closure-copy-icon:hover { opacity: 1; }
                .vfd-closure-copy-icon-copied { opacity: 1; box-shadow: 0 0 2px 2px #a2e37c; }
                .vfd-closure-copy-tooltip {
                    position: absolute;
                    right: 24px;
                    bottom: 24px;
                    padding: 1px 6px;
                    border-radius: 2px;
                    font-size: 11px;
                    white-space: nowrap;
                    box-shadow: 0 1px 3px #0003;
                }
            `);
        },

        addButtons() {
            this.actionOptions.forEach(opt => {
                mw.util.addPortletLink('p-cactions', '#', opt.label, `ca-close-${opt.data}`, `Close this VfD as ${opt.data}`)
                    .addEventListener('click', e => {
                        e.preventDefault();
                        this.openPanel(opt.data);
                    });
            });
        },

        openPanel(action) {
            const textbox = document.getElementById('wpTextbox1');
            if (!textbox) return alert('Edit box not found!');

            const panelId = 'vfd-closure-panel';
            $('#' + panelId).remove();

            const $panel = $('<div>').attr('id', panelId).addClass('vfd-closure-panel');
            $panel.append($('<h4>').text(`VfD Closure: ${action}`));

            const commentInput = new OO.ui.MultilineTextInputWidget({
                placeholder: 'Optional comment',
                autosize: true
            });
            $panel.append(new OO.ui.FieldLayout(commentInput, { label: 'Comment:', align: 'left' }).$element);

            const markResolvedCheckbox = new OO.ui.CheckboxInputWidget({ selected: true });
            $panel.append(new OO.ui.FieldLayout(markResolvedCheckbox, { label: 'Add {{subst:vb}} template', align: 'inline' }).$element);

            const $previewArea = $('<div>').addClass('vfd-closure-preview').hide();
            $panel.append($previewArea);

            const submitBtn = new OO.ui.ButtonWidget({ label: 'Insert', flags: ['progressive'] });
            const previewBtn = new OO.ui.ButtonWidget({ label: 'Preview' });
            const cancelBtn = new OO.ui.ButtonWidget({ label: 'Cancel', flags: ['destructive'] });

            const $btnArea = $('<div>').css('margin-top', '10px').append(previewBtn.$element).append(' ').append(submitBtn.$element).append(' ').append(cancelBtn.$element);
            $panel.append($btnArea);

            $(textbox).before($panel);

            previewBtn.on('click', () => {
                const wikitext = this.generateWikitext(action, commentInput.getValue(), markResolvedCheckbox.isSelected());
                $previewArea.show().html('<p>Loading preview...</p>');

                const api = new mw.Api();
                api.get({
                    action: 'parse',
                    text: wikitext,
                    prop: 'text',
                    formatversion: 2,
                    pst: true,
                    disableeditsection: true,
                    sectionpreview: true
                }).then(resp => {
                    $previewArea.html(resp.parse && resp.parse.text ? resp.parse.text : '<p>Error loading preview.</p>');
                }).catch(() => { $previewArea.html('<p>Error loading preview.</p>'); });
            });

            submitBtn.on('click', () => {
                const wikitext = this.generateWikitext(action, commentInput.getValue(), markResolvedCheckbox.isSelected());
                textbox.value = wikitext;

                const summaryBox = document.getElementById('wpSummary');
                if (summaryBox) summaryBox.value = `Closed as ${action}`;

                $panel.remove();
            });

            cancelBtn.on('click', () => { $panel.remove(); });
        },

        generateWikitext(action, comment, markResolved) {
            const timestamp = '~~~~';
            let topText = `{{subst:vt|${action}. --${timestamp}${comment ? ' ' + comment : ''}}}\n\n`;
            let bottomText = markResolved ? '\n\n{{subst:vb}}' : '';
            return topText + bottomText;
        }
    };

    VfDResolver.init();
});
//</nowiki>