Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

User:Justarandomamerican/globalUserLock.js: Difference between revisions

From WikiOasis Meta
No edit summary
No edit summary
 
(3 intermediate revisions by the same user not shown)
Line 14: Line 14:
const TOOL_TITLE  = 'Global User Lock';
const TOOL_TITLE  = 'Global User Lock';
const PORTLET_ID  = 'ca-global-user-lock';
const PORTLET_ID  = 'ca-global-user-lock';
const API_ENDPOINT = mw.config.get( 'wgScriptPath' ) + '/api.php';
const MAX_ACCOUNTS = 200;
const MAX_ACCOUNTS = 200;


Line 238: Line 237:
<div class="gul-checkbox-row">
<div class="gul-checkbox-row">
<input type="checkbox" id="gul-hide" />
<input type="checkbox" id="gul-hide" />
<label for="gul-hide" style="margin:0;">Hide username (<code>hidden</code> flag — requires suppressor right)</label>
<label for="gul-hide" style="margin:0;">Hide username (<code>hidden = 1</code> flag — requires suppressor right)</label>
</div>
</div>
<div class="gul-checkbox-row">
<div class="gul-checkbox-row">
<input type="checkbox" id="gul-suppress" />
<input type="checkbox" id="gul-suppress" />
<label for="gul-suppress" style="margin:0;">Suppress username (<code>suppressed</code> flag — requires suppressor right)</label>
<label for="gul-suppress" style="margin:0;">Suppress username (<code>hidden = 2</code> flag — requires suppressor right)</label>
</div>
</div>
<div class="gul-checkbox-row">
<div class="gul-checkbox-row">
Line 374: Line 373:
}
}


return api.postWithToken( 'csrf', payload );
return api.postWithToken( 'setglobalaccountstatus', payload );
}
}


Line 462: Line 461:
if ( selected.length === 0 ) { setStatus( 'No accounts selected.', 'warning' ); return; }
if ( selected.length === 0 ) { setStatus( 'No accounts selected.', 'warning' ); return; }


const confirmMessage = 'You are about to globally lock ' + selected.length + ' account(s).\n\n' +
const $btn = $( '#gul-btn-lock' );
'Reason: ' + reason + '\n' +
( hide ? 'Hide username: YES\n' : '' ) +
( suppress ? 'Suppress username: YES\n' : '' ) +
'\nThis action will be logged. Proceed?';


OO.ui.confirm( confirmMessage ).done( function ( confirmed ) {
// ── INLINE CONFIRMATION ──
if ( !confirmed ) { return; }
// First click: Change button state and wait for second click
if ( !$btn.data( 'ready-to-lock' ) ) {
$btn.data( 'ready-to-lock', true )
.text( '⚠️ Confirm Lock (' + selected.length + ')' )
.css( { 'background-color': '#5a1010', 'border-color': '#3a0000' } );


$( '#gul-btn-lock, #gul-btn-search' ).prop( 'disabled', true );
setStatus( '⚠️ <strong>WARNING:</strong> You are about to lock ' + selected.length + ' account(s). Click the button again to proceed.', 'warning' );
$( '#gul-progress' ).addClass( 'visible' );
setProgress( 0, selected.length );
setStatus( 'Locking ' + selected.length + ' account(s)', 'info' );
let done = 0, locked = 0, skipped = 0, failed = 0;


function processNext( i ) {
// Reset if they don't click within 5 seconds
if ( i >= selected.length ) {
setTimeout( function () {
setProgress( done, selected.length );
if ( $btn.data( 'ready-to-lock' ) ) {
setStatus( 'Done. <strong>' + locked + '</strong> locked, <strong>' + skipped + '</strong> skipped, <strong>' + failed + '</strong> failed.', failed > 0 ? 'warning' : 'success' );
$btn.data( 'ready-to-lock', false )
$( '#gul-btn-search' ).prop( 'disabled', false );
.text( '🔒 Lock Selected' )
$( '#gul-lock-summary' ).remove();
.css( { 'background-color': '', 'border-color': '' } );
$( '#gul-results-wrap' ).append( $( '<div id="gul-lock-summary">' ).addClass( 'gul-summary' ).html( '<strong>Summary:</strong> ' + locked + ' locked · ' + skipped + ' skipped · ' + failed + ' failed' ) );
clearStatus();
return;
}
}
}, 5000 );
return;
}


const username = selected[ i ];
// Second click: Reset button visuals and proceed
const wasLocked = $( 'tr[data-user="' + $.escapeSelector( username ) + '"] td:nth-child(3)' ).text().trim() === 'Locked';
$btn.data( 'ready-to-lock', false ).css( { 'background-color': '', 'border-color': '' } );
$( '#gul-btn-lock, #gul-btn-search' ).prop( 'disabled', true );
$( '#gul-progress' ).addClass( 'visible' );
setProgress( 0, selected.length );
setStatus( 'Locking ' + selected.length + ' account(s)…', 'info' );
let done = 0, locked = 0, skipped = 0, failed = 0;


if ( skipLocked && wasLocked ) {
function processNext( i ) {
skipped++; done++;
if ( i >= selected.length ) {
setBadge( username, 'skipped', 'Skipped' );
setProgress( done, selected.length );
setProgress( done, selected.length );
setStatus( 'Done. <strong>' + locked + '</strong> locked, <strong>' + skipped + '</strong> skipped, <strong>' + failed + '</strong> failed.', failed > 0 ? 'warning' : 'success' );
processNext( i + 1 );
$( '#gul-btn-search' ).prop( 'disabled', false );
return;
$( '#gul-lock-summary' ).remove();
}
$( '#gul-results-wrap' ).append( $( '<div id="gul-lock-summary">' ).addClass( 'gul-summary' ).html( '<strong>Summary:</strong> ' + locked + ' locked · ' + skipped + ' skipped · ' + failed + ' failed' ) );
return;
}


setBadge( username, 'pending', 'Locking…' );
const username = selected[ i ];
const wasLocked = $( 'tr[data-user="' + $.escapeSelector( username ) + '"] td:nth-child(3)' ).text().trim() === 'Locked';


lockAccount( username, reason, hide, suppress )
if ( skipLocked && wasLocked ) {
.done( function ( data ) {
skipped++; done++;
if ( data.error ) {
setBadge( username, 'skipped', 'Skipped' );
failed++;
setProgress( done, selected.length );
setBadge( username, 'failed', 'Error: ' + mw.html.escape( data.error.info || data.error.code ) );
processNext( i + 1 );
} else {
return;
locked++;
setBadge( username, 'locked', 'Locked ✓' );
}
} )
.fail( function ( code, result ) {
failed++;
const errMsg = (result && result.error && result.error.info) ? result.error.info : code;
setBadge( username, 'failed', 'Error: ' + mw.html.escape( errMsg ) );
} )
.always( function () {
done++;
setProgress( done, selected.length );
setStatus( 'Processing ' + done + ' / ' + selected.length + '…', 'info' );
setTimeout( function () { processNext( i + 1 ); }, 300 );
} );
}
}
processNext( 0 );
 
} );
setBadge( username, 'pending', 'Locking…' );
 
lockAccount( username, reason, hide, suppress )
.done( function ( result ) {
if ( result.error ) {
failed++;
setBadge( username, 'failed', 'Error: ' + mw.html.escape( result.error.info || result.error.code ) );
} else {
locked++;
setBadge( username, 'locked', 'Locked ✓' );
}
} )
.fail( function ( code, result ) {
failed++;
const errMsg = (result && result.error && result.error.info) ? result.error.info : code;
setBadge( username, 'failed', 'Error: ' + mw.html.escape( errMsg ) );
} )
.always( function () {
done++;
setProgress( done, selected.length );
setStatus( 'Processing ' + done + ' / ' + selected.length + '…', 'info' );
setTimeout( function () { processNext( i + 1 ); }, 300 );
} );
}
processNext( 0 );
}
}


function onClear() {
function onClear() {
// Reset the confirmation button state if clear is clicked
const $btn = $( '#gul-btn-lock' );
$btn.data( 'ready-to-lock', false )
.text( '🔒 Lock Selected' )
.css( { 'background-color': '', 'border-color': '' } )
.prop( 'disabled', true );
$( '#gul-query, #gul-from, #gul-reason' ).val( '' );
$( '#gul-query, #gul-from, #gul-reason' ).val( '' );
$( '#gul-hide, #gul-suppress' ).prop( 'checked', false );
$( '#gul-hide, #gul-suppress' ).prop( 'checked', false );
Line 535: Line 557:
$( '#gul-progress-bar' ).css( 'width', '0%' );
$( '#gul-progress-bar' ).css( 'width', '0%' );
clearStatus();
clearStatus();
$( '#gul-btn-lock' ).prop( 'disabled', true );
}
}


Cookies help us deliver our services. By using our services, you agree to our use of cookies.