Aller au contenu

MediaWiki:Gadget-QuickBlock.js

De Wiki Undertale FR

Note : après avoir publié vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

  • Firefox / Safari : maintenez la touche Maj (Shift) en cliquant sur le bouton Actualiser ou appuyez sur Ctrl + F5 ou Ctrl + R (⌘ + R sur un Mac).
  • Google Chrome : appuyez sur Ctrl + Maj + R (⌘ + Shift + R sur un Mac).
  •  Edge : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl + F5.
/* TODO: MediaWiki 1.45 allows loading .vue files in Gadgets (T340460) */
const {computed, createMwApp, ref} = mw.loader.require('vue');
const {
    CdxCheckbox,
    CdxDialog,
    CdxField,
    CdxMessage,
    CdxSelect,
    CdxTextInput
} = mw.loader.require('@wikimedia/codex');
const {
    parseReasonDropdown,
    getTitleFromUrl,
    getSpecialPageTarget
} = mw.loader.require('ext.gadget.Util');
const api = new mw.Api();

const blockDialogOpen = ref(false);
const unblockDialogOpen = ref(false);
const dialogTargetUser = ref('');
const blockReasonSelection = ref(null);
const blockReasonCustom = ref('');
const blockDuration = ref('2 weeks');
const blockDurationCustom = ref('');
const unblockReason = ref('');
const actionMessage = ref('');
const actionMessageType = ref('');
const nocreate = ref(true);
const allowusertalk = ref(true);
const autoblock = ref(true);

const primaryActionBlock = {
    label: 'Block',
    actionType: 'progressive'
};

const primaryActionUnblock = {
    label: 'Unblock',
    actionType: 'progressive'
};

const defaultAction = {
    label: 'Cancel'
};

function openBlockDialog(target) {
    dialogTargetUser.value = target;
    blockReasonSelection.value = null;
    blockReasonCustom.value = '';
    blockDuration.value = '2 weeks';
    blockDurationCustom.value = '';
    actionMessage.value = '';
    blockDialogOpen.value = true;
    setTimeout(() => document.querySelector('#quick-block-reason .cdx-select-vue__handle').focus(), 0);
}

function openUnblockDialog(target) {
    dialogTargetUser.value = target;
    unblockReason.value = '';
    actionMessage.value = '';
    unblockDialogOpen.value = true;
    setTimeout(() => document.querySelector('#quick-unblock-reason input').focus(), 0);
}

function onSubmit(action) {
    const reason = action === 'block'
        ? [blockReasonSelection.value, blockReasonCustom.value].filter(Boolean).join(': ')
        : unblockReason.value;
    const params = {
        action,
        user: dialogTargetUser.value,
        reason,
        tags: ['quickblock'],
        bot: true
    };
    if (action === 'block') {
        params.expiry = blockDuration.value === 'custom' ?
            blockDurationCustom.value :
            blockDuration.value;
        params.reblock = true;
        params.nocreate = nocreate.value;
        params.allowusertalk = allowusertalk.value;
        params.autoblock = autoblock.value;
    }
    api.postWithToken('csrf', params).done(() => {
        actionMessageType.value = 'success';
        actionMessage.value = 'Success!';
    }).fail(code => {
        actionMessageType.value = 'error';
        actionMessage.value = `Failed to ${action} ${dialogTargetUser.value}: ${code}`;
    });
}

function keydownHandler(event, action) {
    if (event.key === 'Enter') {
        onSubmit(action);
    }
}

// <nowiki>
const blockDialog = createMwApp({
    name: 'quick-block',
    components: {CdxCheckbox, CdxDialog, CdxField, CdxMessage, CdxSelect, CdxTextInput},
    template: `
    <cdx-dialog
        v-model:open="blockDialogOpen"
        :title="'Blocking ' + dialogTargetUser"
        :primary-action="primaryActionBlock"
        :default-action="defaultAction"
        @primary="onSubmit('block')"
        @default="blockDialogOpen = false"
        :use-close-button="true"
    >
        <cdx-field id="quick-block-reason">
            <cdx-select
                v-model:selected="blockReasonSelection"
                :menu-items="blockReasons"
                default-label="Select a reason..."
            />
            <template #label>Block reason</template>
        </cdx-field>
        <cdx-field>
            <cdx-text-input v-model="blockReasonCustom" @keydown="keydownHandler($event, 'block')" />
            <template #label>Custom reason</template>
        </cdx-field>
        <cdx-field>
            <cdx-select
                v-model:selected="blockDuration"
                :menu-items="blockDurations"
                default-label="Select a duration..."
            />
            <cdx-text-input
                v-model="blockDurationCustom"
                v-if="blockDuration == 'custom'"
                @keydown="keydownHandler($event, 'block')"
            />
            <template #label>Block duration</template>
        </cdx-field>
        <cdx-field>
            <cdx-checkbox v-model="nocreate">Prevent account creation</cdx-checkbox>
            <cdx-checkbox v-model="allowusertalk">Allow editing their own talk page</cdx-checkbox>
            <cdx-checkbox v-model="autoblock">Automatically block user's IP addresses for 1 day</cdx-checkbox>
            <template #label>Block details</template>
        </cdx-field>
        <cdx-message
            v-if="actionMessage"
            :type="actionMessageType"
            :fade-in="true"
            :auto-dismiss="true"
            :display-time="5000"
            @auto-dismissed="blockDialogOpen = false"
        >{{ actionMessage }}</cdx-message>
    </cdx-dialog>
    `,
    setup() {
        return {
            actionMessage,
            actionMessageType,
            blockDialogOpen,
            dialogTargetUser,
            blockReasonSelection,
            blockReasonCustom,
            blockDuration,
            blockDurationCustom,
            blockDurations: computed(() => [
                    ...mw.msg('ipboptions')
                        .split(',')
                        .map(option => option.split(':'))
                        .map(([label, value]) => ({label, value})),
                    {
                        label: 'Custom duration',
                        value: 'custom'
                    }
                ]
            ),
            blockReasons: parseReasonDropdown('ipbreason-dropdown'),
            primaryActionBlock,
            defaultAction,
            nocreate,
            allowusertalk,
            autoblock,
            onSubmit,
            keydownHandler
        };
    }
});

const unblockDialog = createMwApp({
    name: 'quick-unblock',
    components: {CdxDialog, CdxField, CdxMessage, CdxTextInput},
    template: `
    <cdx-dialog
        v-model:open="unblockDialogOpen"
        :title="'Unblocking ' + dialogTargetUser"
        :primary-action="primaryActionUnblock"
        :default-action="defaultAction"
        @primary="onSubmit('unblock')"
        @default="unblockDialogOpen = false"
        :use-close-button="true"
    >
        <cdx-field id="quick-unblock-reason">
            <cdx-text-input v-model="unblockReason" @keydown="keydownHandler($event, 'unblock')" />
            <template #label>Reason</template>
        </cdx-field>
        <cdx-message
            v-if="actionMessage"
            :type="actionMessageType"
            :fade-in="true"
            :auto-dismiss="true"
            :display-time="5000"
            @auto-dismissed="unblockDialogOpen = false"
        >{{ actionMessage }}</cdx-message>
    </cdx-dialog>
    `,
    setup() {
        return {
            actionMessage,
            actionMessageType,
            unblockDialogOpen,
            dialogTargetUser,
            unblockReason,
            primaryActionUnblock,
            defaultAction,
            onSubmit,
            keydownHandler
        };
    }
});
// </nowiki>

document.addEventListener('click', event => {
    const target = event.target.closest('a[href]');
    if (
        !target ||
        event.ctrlKey ||
        event.shiftKey ||
        event.metaKey ||
        event.altKey
    ) {
        return;
    }
    let url;
    try {
        url = new URL(target.href);
    } catch (error) {
        return;
    }
    const pageTitle = getTitleFromUrl(url);
    if (!pageTitle) {
        return;
    }
    // TODO: Fetch localized special page aliases.
    const blockTarget = getSpecialPageTarget(url, pageTitle, ['block']);
    if (blockTarget) {
        event.preventDefault();
        openBlockDialog(blockTarget);
        return;
    }
    const unblockTarget = getSpecialPageTarget(url, pageTitle, ['unblock']);
    if (unblockTarget) {
        event.preventDefault();
        openUnblockDialog(unblockTarget);
    }
});

const blockRoot = document.createElement('div');
document.body.appendChild(blockRoot);
blockDialog.mount(blockRoot);
const unblockRoot = document.createElement('div');
document.body.appendChild(unblockRoot);
unblockDialog.mount(unblockRoot);