Jump to content

User:Mathnerd314159/displayLibrary.js

From Wikipedia, the free encyclopedia
This is the current revision of this page, as edited by Mathnerd314159 (talk | contribs) at 04:12, 24 June 2025 (add rate calculation). The present address (URL) is a permanent link to this version.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
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);
        });
    });
});