Jump to content

User:Enterprisey/simple-notifs.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Enterprisey (talk | contribs) at 20:54, 11 November 2019 (add ability to mark notifs as read). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
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.
// vim: ts=4 sw=4 et ai
$( function () {
    var api;

    // Copied from https://stackoverflow.com/a/3177838/1757964
    function timeSince(date) {
        var seconds = Math.floor((new Date() - date) / 1000);
        var interval = Math.floor(seconds / 31536000);
        if (interval > 1) {
            return interval + " years";
        }
        interval = Math.floor(seconds / 2592000);
        if (interval > 1) {
            return interval + " months";
        }
        interval = Math.floor(seconds / 86400);
        if (interval > 1) {
            return interval + " days";
        }
        interval = Math.floor(seconds / 3600);
        if (interval > 1) {
            return interval + " hours";
        }
        interval = Math.floor(seconds / 60);
        if (interval > 1) {
            return interval + " minutes";
        }
        return Math.floor(seconds) + " seconds";
    }

    function wikilink( title ) {
        return "<a href='" + mw.util.getUrl( title ) + "'>" + title + "</a>";
    }

    function notifToElement( notif ) {
        var timestamp = timeSince( new Date( notif.timestamp.utciso8601 ) ) + " ago";
        var userLink = "<a href='" + mw.util.getUrl( "User:" + notif.agent.name ) + "'>" + notif.agent.name + "</a>";
        var newNotifDiv = $( "<div class='notif'>" );
        if( !notif.read ) newNotifDiv.append( "*" );
        if( notif.type === "mention" && notif.category === "mention" ) {
            newNotifDiv
                .append( "Mentioned " + timestamp + " by " + userLink + " on " )
                .append( wikilink( notif.title.full ) )
                .append( " with " )
                .append( "<a href='" + mw.util.getUrl( "Special:Diff/" + notif.revid ) + "'>this edit</a>" );
        }
        else if( notif.type === "emailuser" && notif.category === "emailuser" ) {
            newNotifDiv
                .append( "Emailed " + timestamp + " by " + userLink )
        } else if( notif.type === "edit-thank" && notif.category === "edit-thank" ) {
            newNotifDiv
                .append( "Thanked " + timestamp + " by " + userLink + " for " )
                .append( "<a href='" + mw.util.getUrl( "Special:Diff/" + notif.revid ) + "'>this edit</a>" )
                .append( " to " )
                .append( wikilink( notif.title.full ) );
        } else if( notif.type === "edit-user-talk" && notif.category === "edit-user-talk" ) {
            newNotifDiv
                .append( "Your user talk page changed " + timestamp + " by " + userLink )
                .append( " with " )
                .append( "<a href='" + mw.util.getUrl( "Special:Diff/" + notif.revid ) + "'>this edit</a>" );
        } else if( notif.type === "mention-success" && notif.category === "mention-success" ) {
            newNotifDiv
                .append( "Successfully mentioned someone " + timestamp + " on " )
                .append( wikilink( notif.title.full ) )
                .append( " with " )
                .append( "<a href='" + mw.util.getUrl( "Special:Diff/" + notif.revid ) + "'>this edit</a>" )
        } else {
            newNotifDiv.text( JSON.stringify( notif ) );
        }
        if( !notif.read ) {
            newNotifDiv
                .append( " (" )
                .append( $( "<a>" )
                    .text( "done" )
                    .click( function () {
                        api.postWithToken( "csrf", {
                            action: "echomarkread",
                            list: notif.id
                        } ).then( function () {

                            // Remove asterisk
                            var prevContent = newNotifDiv.get( 0 ).childNodes[0].textContent;
                            if( prevContent.indexOf( "*" ) === 0 ) {
                                newNotifDiv.get( 0 ).childNodes[0].textContent = prevContent.substring( 1 );
                            }
                        } );
                    } )
                )
                .append( ")" )
        }

        return newNotifDiv;
    }

    function showPanel( notifsList ) {
        if( !document.getElementById( "simple-notifs-panel" ) ) {
            var ptOffset = $( "#pt-simple-notifs" ).offset();
            var panel = $( "<div>" )
                .attr( "id", "simple-notifs-panel" )
                .css( "top", ptOffset.top + 30 + "px" )
                .css( "left", ptOffset.left + "px" )
                .appendTo( "body" );
            notifsList.reverse();
            notifsList.map( notifToElement ).forEach( function ( e ) { panel.append( e ); } );
        } else {
            $( "#simple-notifs-panel" ).toggle();
        }
    }
    $.when(
        $.getJSON(
            mw.config.get( 'wgScriptPath' ) + '/api.php',
            {
                format: "json",
                action: "query",
                meta: "notifications",
                notunreadfirst: "true", // not is the notifications module, not the word "not"
                formatversion: 2,
            }
        ),
        $.ready,
        mw.loader.using( [ "mediawiki.api", "mediawiki.util" ] )
    ).then( function ( results ) {
        var data = results[0];
        if( !data || !data.query || !data.query.notifications ||
            !data.query.notifications.list ) {
            console.error( "simple-notifs died ", data );
        }

        api = new mw.Api( "User:Enterprisey/simple-notifs.js" );

        $( "<li>" )
            .insertAfter( "#pt-userpage" )
            .append( data.query.notifications.list.filter( function ( x ) { return !x.read; } ).length )
            .attr( "id", "pt-simple-notifs" )
            .on( "click", function () { showPanel( data.query.notifications.list ); } )

        mw.loader.addStyleTag( "ul li#pt-simple-notifs { cursor: pointer; background-color: gray; margin-top: .3em; padding: .3em; padding-top: .3em; background-color: #ccc }"+
            " #simple-notifs-panel { position: fixed; background-color: white; width: 30em; height: 50%; overflow-y: scroll; border: thin solid black; border-radius: 2px; padding: 0.5em; font-size: 0.875em; }"+
            "#simple-notifs-panel .notif { margin-bottom: 0.3em; }");
    } );
} );