User:Mathnerd314159/displayLibrary.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
![]() | Documentation for this user script can be added at User:Mathnerd314159/displayLibrary. |
/* Helper for the "10+ edits in past 30 days" criterion for the Wikipedia Library.
Displays how long you can go without editing until access expires and
the required edit rate to maintain the threshold. */
$(document).ready(function () {
// Ensure that mediawiki.user and mediawiki.api modules are loaded before proceeding.
mw.loader.using(['mediawiki.user', 'mediawiki.api'], function() {
// Get the current username from MediaWiki configuration.
const username = mw.config.get('wgUserName');
// Check if a username is available. If not, there's no user to query.
if (!username) {
console.log('No user logged in or username not available.');
return;
}
// Initialize a new MediaWiki API object.
(new mw.Api()).get({
action: 'query', // Specify the action as 'query'
list: 'usercontribs', // Request a list of user contributions
ucuser: username, // Specify the user whose contributions to query
uclimit: 10, // Limit the results to the 10 most recent contributions
ucprop: 'timestamp' // Request the timestamp property for each contribution
}).done(function(result) {
// Check if the query was successful and user contributions were returned.
// Ensure there are at least 10 edits to perform calculations.
if (result.query && result.query.usercontribs && result.query.usercontribs.length >= 10) {
const userContribs = result.query.usercontribs; // Array of user contributions
// Get the timestamp of the 10th most recent edit (index 9, as arrays are 0-indexed).
const tenthEditTimestamp = userContribs[9].timestamp;
// Create a Date object from the timestamp of the 10th edit.
const tenthEditDate = new Date(tenthEditTimestamp);
// Calculate the target date: 30 days after the 10th edit.
// This is the date when the 10th edit "falls off" the 30-day window.
const targetDateForBreach0 = new Date(tenthEditDate); // Clone to avoid modifying tenthEditDate
targetDateForBreach0.setDate(targetDateForBreach0.getDate() + 30);
// Get the current date and time.
const now = new Date();
// --- Calculate time_left_before_breach_0 (the primary countdown) ---
const diffMsForBreach0 = targetDateForBreach0.getTime() - now.getTime();
// Convert milliseconds to days and round to tenths for display.
// This represents how many days are left until the 10th edit falls off.
const time_left_before_breach_0 = Math.floor(diffMsForBreach0 / (1000 * 60 * 60 * 24) * 10) / 10;
let countdownText = '';
if (time_left_before_breach_0 <= 0) {
countdownText = 'Edit today!';
} else {
// Use 'day' or 'days' appropriately based on the value.
countdownText = `${time_left_before_breach_0} day${time_left_before_breach_0 === 1 ? '' : 's'} left`;
}
// --- Calculate required_rate ---
let required_rate = 0; // Initialize required_rate to find the maximum.
// Iterate for 'n' from 1 to 9, as per the definition.
// 'n' represents hypothetical new edits made immediately.
for (let n = 1; n <= 9; n++) {
// The 'relevant' edit is the (10-n)-th most recent edit currently.
// For example, if n=1, we consider the 9th most recent edit (index 8).
// If n=9, we consider the 1st most recent edit (index 0).
const relevantEditIndex = 9 - n;
const relevantEditTimestamp = userContribs[relevantEditIndex].timestamp;
const relevantEditDate = new Date(relevantEditTimestamp);
// Calculate the date when this specific 'relevant' edit would fall off the 30-day window.
const fallOffDateForN = new Date(relevantEditDate); // Clone to avoid mutation
fallOffDateForN.setDate(fallOffDateForN.getDate() + 30);
// Calculate the time remaining until this edit falls off (in milliseconds).
const timeUntilFallOffMs = fallOffDateForN.getTime() - now.getTime();
// Convert to days.
let timeUntilFallOffDays = timeUntilFallOffMs / (1000 * 60 * 60 * 24);
let currentRate;
if (timeUntilFallOffDays <= 0) {
// If the edit has already fallen off or is about to, an "infinite" rate is required
// to maintain the threshold based on 'n' new edits.
currentRate = Infinity;
} else {
// Calculate rates_n = n / time_left_before_breach_n.
// This indicates the rate of 'n' new edits required over the remaining time.
currentRate = n / timeUntilFallOffDays;
}
// Update the overall required_rate if the current 'rates_n' is higher.
if (currentRate > required_rate) {
required_rate = currentRate;
}
}
// Format the required_rate for display.
let requiredRateText = '';
if (required_rate === Infinity) {
requiredRateText = '∞ edits/day (breached)';
} else if (required_rate < 0.01) { // If the rate is extremely small, implies large surplus or no immediate need.
requiredRateText = 'No immediate edits required';
} else {
// Display rate rounded to two decimal places.
requiredRateText = `${required_rate.toFixed(2)} edits/day`;
}
// Find the 'My contributions' list item element.
const contribsListItem = document.getElementById('pt-mycontris');
if (contribsListItem) {
// Append the countdown text as a new div.
const countdownEl = document.createElement('div');
countdownEl.textContent = countdownText;
// countdownEl.style.fontSize = '0.8em'; // Optional: make text slightly smaller
contribsListItem.append(countdownEl);
// Append the required rate text as another new div.
const rateEl = document.createElement('div');
rateEl.textContent = `Req. ${requiredRateText}`;
// rateEl.style.fontSize = '0.8em';
contribsListItem.append(rateEl);
}
} else {
console.log('Could not retrieve 10th most recent edit, or user has less than 10 edits. Calculations cannot be performed.');
}
}).fail(function(jqXHR, textStatus, errorThrown) {
// Log any errors that occur during the API request.
console.error('MediaWiki API request failed:', textStatus, errorThrown);
});
});
});