לדלג לתוכן

משתמש:שרדינגר/lastseen-code.js

מתוך ויקיפדיה, האנציקלופדיה החופשית

הערה: לאחר הפרסום, ייתכן שיהיה צורך לנקות את זיכרון המטמון (cache) של הדפדפן כדי להבחין בשינויים.

  • פיירפוקס / ספארי: להחזיק את המקש Shift בעת לחיצה על טעינה מחדש (Reload) או ללחוץ על צירוף המקשים Ctrl-F5 או Ctrl-R (במחשב מק: ⌘-R).
  • גוגל כרום: ללחוץ על צירוף המקשים Ctrl-Shift-R (במחשב מק: ⌘-Shift-R).
  • אדג': להחזיק את המקש Ctrl בעת לחיצה על רענן (Refresh) או ללחוץ על צירוף המקשים Ctrl-F5.
(function() {
    var username = mw.config.get('wgRelevantUserName'); // Retrieves the relevant username for user-related pages
    var wikiLanguage = mw.config.get('wgContentLanguage'); // Detects the current Wikipedia language

    // Run the script on user-related pages if a relevant username is found
    if (username) {
        var api = new mw.Api();

        // Get user info to determine gender
        api.get({
            action: 'query',
            list: 'users',
            ususers: username,
            usprop: 'gender'
        }).done(function(data) {
            var userInfo = data.query.users[0];
            var userGender = userInfo.gender;

            // Messages in multiple languages with gender adjustments
            var messages = {
                'he': {
                    male: "המשתמש " + username + " ביצע את <a href='https://" + wikiLanguage + ".wikipedia.org/wiki/Special:Contributions/" + encodeURIComponent(username) + "'>העריכה</a> האחרונה שלו לפני ",
                    female: "המשתמשת " + username + " ביצעה את <a href='https://" + wikiLanguage + ".wikipedia.org/wiki/Special:Contributions/" + encodeURIComponent(username) + "'>העריכה</a> האחרונה שלה לפני "
                },
                'en': {
                    male: "User " + username + " made his last <a href='https://" + wikiLanguage + ".wikipedia.org/wiki/Special:Contributions/" + encodeURIComponent(username) + "'>edit</a> ",
                    female: "User " + username + " made her last <a href='https://" + wikiLanguage + ".wikipedia.org/wiki/Special:Contributions/" + encodeURIComponent(username) + "'>edit</a> "
                },
                // Add other languages here...
            };

            var noEditMessages = {
                'he': {
                    male: "המשתמש " + username + " עדיין לא ביצע עריכה",
                    female: "המשתמשת " + username + " עדיין לא ביצעה עריכה"
                },
                'en': {
                    male: "User " + username + " has not edited yet",
                    female: "User " + username + " has not edited yet"
                },
                // Add other languages here...
            };

            var genderKey = userGender === 'female' ? 'female' : 'male'; // Determine the appropriate gender key
            var message = messages[wikiLanguage][genderKey] || messages['en'][genderKey]; // Selects the message based on the language and gender, defaults to English
            var noEditMessage = noEditMessages[wikiLanguage][genderKey] || noEditMessages['en'][genderKey]; // Selects the "no edit" message based on the language and gender

            // Tooltip containing explanations for each color
            var tooltipFullExplanation = {
                'he': "ירוק: המשתמש ערך לאחרונה לפני פחות מ־20 דקות\nכתום: המשתמש ערך לאחרונה לפני יותר מ־20 דקות, אך לפני פחות משלושה חודשים\nאדום: המשתמש ערך לאחרונה לפני יותר משלושה חודשים\nאפור: המשתמש מעולם לא ערך באתר, או שמועד העריכה האחרונה לא ידוע",
                'en': "Green: The user edited less than 20 minutes ago\nOrange: The user edited more than 20 minutes ago, but within the last three months\nRed: The user edited more than three months ago\nGray: The user has never edited, or the last edit date is unknown"
            };

            var tooltipMessage = tooltipFullExplanation[wikiLanguage] || tooltipFullExplanation['en']; // Selects the tooltip explanation based on the language

            // Converts time difference to total seconds for Lua processing
            function convertTimeDifferenceToSeconds(date) {
                var now = new Date();
                var diffInSeconds = Math.floor((now - date) / 1000);
                return diffInSeconds;
            }

            // Determines which units to display based on time difference
            function determineUnits(diffInSeconds) {
                var units = [];
                if (diffInSeconds > 2 * 24 * 60 * 60) {
                    units.push("years", "months", "days");
                } else if (diffInSeconds > 24 * 60 * 60) {
                    units.push("days", "hours");
                } else if (diffInSeconds > 2 * 60) {
                    units.push("days", "hours", "minutes");
                } else {
                    units.push("days", "hours", "minutes", "seconds");
                }
                return units.join(", ");
            }

            // Formats the relative time using the Lua module and replaces "וגם" with "ו"
            function formatRelativeTimeUsingLua(diffInSeconds, lastEditDate) {
                var units = determineUnits(diffInSeconds);
                var tooltipTime = lastEditDate.toLocaleDateString() + ' ' + lastEditDate.getHours() + ':' + lastEditDate.getMinutes().toString().padStart(2, '0'); // Removes seconds
                return api.post({
                    action: 'expandtemplates',
                    text: "{{#invoke:משך זמן|sumHMS|" + diffInSeconds + "|units=" + units + "}}"
                }).then(function(response) {
                    return {
                        relativeTime: response.expandtemplates['*'].replace(/וגם/g, 'ו').replace(/\s{2,}/g, ' ').trim(),
                        tooltipTime: tooltipTime
                    };
                });
            }

            // Determines the color of the icon based on the time difference
            function getRecencyIcon(timeDiff, hasEdits) {
                var iconColor;
                if (!hasEdits) {
                    iconColor = "gray"; // Never edited or unknown date
                } else if (timeDiff <= 20 * 60 * 1000) {
                    iconColor = "green"; // Less than 20 minutes
                } else if (timeDiff <= 90 * 24 * 60 * 60 * 1000) {
                    iconColor = "orange"; // Between 20 minutes and three months
                } else {
                    iconColor = "red"; // More than three months
                }
                return `<span style="color:${iconColor}; font-size: 30px; cursor: help; vertical-align: middle;" title="${tooltipMessage}">&#9679;</span>`; // Circular icon with tooltip
            }

            var apiUrl = "https://" + wikiLanguage + ".wikipedia.org/w/api.php?action=query&list=usercontribs&ucuser=" + encodeURIComponent(username) + "&uclimit=1&ucdir=older&format=json&origin=*";

            $.getJSON(apiUrl, function(data) {
                var displayTime, icon;
                if (data.query && data.query.usercontribs && data.query.usercontribs.length > 0) {
                    var lastEditTime = new Date(data.query.usercontribs[0].timestamp);
                    var now = new Date();
                    icon = getRecencyIcon(now - lastEditTime, true);
                    
                    var timeDifferenceInSeconds = convertTimeDifferenceToSeconds(lastEditTime);
                    
                    formatRelativeTimeUsingLua(timeDifferenceInSeconds, lastEditTime).then(function(result) {
                        displayTime = `${message}<span title="${result.tooltipTime}" style="border-bottom: 1px dashed; cursor: pointer;" onclick="toggleExactTime(this, '${result.tooltipTime}')">${result.relativeTime}</span>`;
                        
                        var infoBox = document.createElement('div');
                        infoBox.style.fontSize = "small"; // Smaller font size
                        infoBox.style.padding = "8px 12px"; // Padding inside the box
                        infoBox.style.marginBottom = "10px";
                        infoBox.style.backgroundColor = "#f5f5f5"; // Light background color
                        infoBox.style.borderLeft = "5px solid #ccc"; // Left border line
                        infoBox.style.borderRadius = "4px"; // Rounded corners
                        infoBox.style.boxShadow = "0 1px 3px rgba(0,0,0,0.1)"; // Light shadow
                        infoBox.style.display = "flex";
                        infoBox.style.alignItems = "center";
                        infoBox.style.maxWidth = "600px"; // Max width limitation

                        infoBox.innerHTML = `${icon} <span style="margin-left: 8px;">${displayTime}</span>`;

                        var firstHeading = document.getElementById('firstHeading');
                        if (firstHeading) {
                            firstHeading.parentNode.insertBefore(infoBox, firstHeading.nextSibling);
                        }
                    });
                } else {
                    displayTime = noEditMessage; // Displays the appropriate message if no edits
                    icon = getRecencyIcon(Infinity, false); // Gray icon if no edits have been made

                    var infoBox = document.createElement('div');
                    infoBox.style.fontSize = "small"; // Smaller font size
                    infoBox.style.padding = "8px 12px"; // Padding inside the box
                    infoBox.style.marginBottom = "10px";
                    infoBox.style.backgroundColor = "#f5f5f5"; // Light background color
                    infoBox.style.borderLeft = "5px solid #ccc"; // Left border line
                    infoBox.style.borderRadius = "4px"; // Rounded corners
                    infoBox.style.boxShadow = "0 1px 3px rgba(0,0,0,0.1)"; // Light shadow
                    infoBox.style.display = "flex";
                    infoBox.style.alignItems = "center";
                    infoBox.style.maxWidth = "600px"; // Max width limitation

                    infoBox.innerHTML = `${icon} <span style="margin-left: 8px;">${displayTime}</span>`;

                    var firstHeading = document.getElementById('firstHeading');
                    if (firstHeading) {
                        firstHeading.parentNode.insertBefore(infoBox, firstHeading.nextSibling);
                    }
                }
            });
        });
    }

    // Function to toggle the display of the exact time below the relative time
    window.toggleExactTime = function(element, exactTime) {
        var nextElement = element.nextElementSibling;
        if (nextElement && nextElement.classList.contains('exact-time')) {
            nextElement.remove();
        } else {
            var exactTimeElement = document.createElement('div');
            exactTimeElement.classList.add('exact-time');
            exactTimeElement.style.fontSize = 'small';
            exactTimeElement.style.color = '#555';
            exactTimeElement.textContent = exactTime;
            element.parentNode.insertBefore(exactTimeElement, element.nextSibling);
        }
    };
})();