Jump to content

User:Mathnerd314159/displayLibrary.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/* 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);
        });
    });
});