MediaWiki:ExtendedPrivateMessaging/code.js

/* ExtendedPrivateMessaging (XPM) * * Adds additional functions to private messages. * Working group PMs and alerts when users block and unblock you. * * @author Dorumin */ (function reloadUntilMainRoom {   if ( wgCanonicalSpecialPageName != 'Chat' || window.ExtendedPrivateMessaging && window.ExtendedPrivateMessaging.init ) return; // Double runs   if (!window.mainRoom || !window.mainRoom.isInitialized) { // MAINROOM IS NOT DEFINED        setTimeout(reloadUntilMainRoom, 500);        return;    }

var i18n;

if (typeof dev == 'undefined' || typeof dev.i18n == 'undefined') { // Import i18n-js, if needed importArticle({           type: 'script',            article: 'u:dev:MediaWiki:I18n-js/code.js'        }); }

/********** BLOCK PM INLINE ALERTS**********/ // Query the API for the peeps that blocked your PMs function update_blocked_by { $.get('/index.php?action=ajax&rs=ChatAjax&method=getPrivateBlocks').then(function(d) {           var blockedBy = d.blockedByChatUsers.sort;            if (blockedBy.join('|') == xpm.blockedBy.join('|')) return;            var changed = blockedBy.concat(xpm.blockedBy).filter(function(name, i, ref) { return ref.indexOf(name) == ref.lastIndexOf(name); });           xpm.blockedBy = blockedBy;            mainRoom.model.blockedByUsers.models.forEach(function(model) { if (xpm.blockedBy.indexOf(model.attributes.name) == -1) { mainRoom.model.blockedByUsers.remove(model); }           });            if (!changed.length) return;            changed.map(function(user) { var r = [user, wgUserName].sort; r.isBlocked = blockedBy.indexOf(user) != -1; return r;           }).filter(function(users) { return xpm.privateChats[users.join('|')]; }).forEach(update_chat);       }); }   function update_chat(users) { var room = xpm.privateChats[users.join('|')]; if (!room || users.length > 2) return; var them = users[0] == wgUserName ? users[1] : users[0], they_blocked = xpm.blockedBy.indexOf(them) != -1; room.model.room.set({           blockedMessageInput: users.isBlocked        }); room.model.chats.add(new models.InlineAlert({ text: mw.message('chat-user-' + (users.isBlocked ? 'blocked' : 'allow'), they_blocked || !users.isBlocked ? them : wgUserName, they_blocked || !users.isBlocked ? wgUserName : them).escaped }));   }    function bind_events(room) { room.socket.on("updateUser", function(msg) {           var data = JSON.parse(msg.data).attrs,                type = data.statusMessage,                status = data.statusState,                user = data.name,                users = room.model.privateRoom.attributes.users.sort;            if ( user != wgUserName && type == 'hey-i-just-met-you-and-this-is-crazy-but-heres-my-number-so-block-me-maybe' ) {               users.isBlocked = status;                update_chat(users);            }        }); }   // Declare global variable for debugging var xpm = window.ExtendedPrivateMessaging = $.extend({       blockedBy: mainRoom.model.blockedByUsers.models.map(function(n) { return n.attributes.name; }).sort,       privateChats: {},        groupIcon: 'https://i.imgur.com/Ib3A8Nl.png',        init: true    }, window.ExtendedPrivateMessaging); // Extend the private chats object $.each(mainRoom.chats.privates, function(i, room) {       var u = room.model.privateRoom.attributes.users.sort;        if (u.indexOf(undefined) != -1) return; // Socket is stupid        xpm.privateChats[u.join('|')] = room;        bind_events(room);    }); // Bind to new private rooms mainRoom.model.privateUsers.bind('add', function(u) {       var room = mainRoom.chats.privates[u.attributes.roomId],        users = room.model.privateRoom.attributes.users.sort;        if (users.indexOf(undefined) != -1) return; // Socket is stupid        xpm.privateChats[users.join('|')] = room;        bind_events(room);    }); // Bind to you blocking others mainRoom.model.blockedUsers.bind('add', function(u) {       var users = [u.attributes.name, wgUserName].sort,        room = xpm.privateChats[users.join('|')];        if (!room) return;        room.socket.send(new models.SetStatusCommand({            statusMessage: 'hey-i-just-met-you-and-this-is-crazy-but-heres-my-number-so-block-me-maybe',            statusState: true        }).xport);    }); // Bind to unblocking people mainRoom.model.blockedUsers.bind('remove', function(u) {       var users = [u.attributes.name, wgUserName].sort,        room = xpm.privateChats[users.join('|')];        if (!room) return;        room.socket.send(new models.SetStatusCommand({            statusMessage: 'hey-i-just-met-you-and-this-is-crazy-but-heres-my-number-so-block-me-maybe',            statusState: false        }).xport);    }); // Periodically check for new users who blocked you setInterval(update_blocked_by, 2500);

/********** GROUP PMs **********/ function remove_selection { var sel = window.getSelection ? getSelection : document.selection;

if (sel) { if (sel.removeAllRanges) { sel.removeAllRanges; } else if (sel.empty) { sel.empty; }       }    }

function open_group_private_message { var users = $('#WikiChatList .selected') .map(function {               return this.getAttribute('data-user');            }) .toArray;

if (users.length) { mainRoom.openPrivateChat(users); }

close_group_selection; }

function close_group_selection { document.body.classList.remove('picking-group-pm');

var picker = document.getElementById('GroupPickerInfo'); if (!picker) { return; }

$('.User.selected').removeClass('selected').removeAttr('style');

picker.style.animationName = 'none'; picker.style.animationDirection = 'reverse'; picker.offsetHeight; /* trigger reflow */ picker.style.animationName = null;

setTimeout(function {           picker.parentElement.removeChild(picker);        }, 450); }

function open_group_selection { var doc = document, rail   = doc.getElementById('Rail'), picker = doc.createElement('div'), start  = doc.createElement('div'), cross  = doc.createElement('div');

picker.id = 'GroupPickerInfo'; start.className = 'start'; cross.className = 'cross'; start.textContent = i18n.msg('help').plain; cross.textContent = '✖';

start.onclick = open_group_private_message; cross.onclick = close_group_selection;

picker.appendChild(start); picker.appendChild(cross);

rail.appendChild(picker);

doc.body.classList.add('picking-group-pm');

mainRoom.viewUsers.hideMenu; }

function user_click_handler(e) { var picker = document.getElementById('GroupPickerInfo'), $this = $(this);

if (!picker) return; e.preventDefault; setTimeout(mainRoom.viewUsers.hideMenu, 0); $this.toggleClass('selected');

if ($this.hasClass('selected')) { $this.css('background-color', $this.css('background-color')); } else { $this.removeAttr('style'); }   }

function new_room_handler(user) { var id = user.attributes.roomId, room = mainRoom.chats.privates[id], members = room.model.privateRoom.attributes.users.filter(function(name) {           return name != wgUserName;        }); if (members.length == 1) return;

var $elem = $('#MsgCount_' + id).closest('.User'); $elem .attr('title', members.join(', ')) .addClass('group') .removeAttr('id') .find('img') .attr('src', xpm.groupIcon); $elem.find('.username').get(0).firstChild.textContent = members.join(', '); }

function room_change_handler(e) { if (e.target && e.target.hasClass('group')) { mainRoom.viewUsers.hideMenu; }       var header = document.querySelector('#ChatHeader .private'), id = e.target ? Number(e.target.find('.splotch').attr('id').slice(9)) : mainRoom.activeRoom, room = mainRoom.chats.privates[id]; if (!header || !room) return; var users = mainRoom.chats.privates[id].model.privateRoom.attributes.users.filter(function(name) {           return name != wgUserName;        }); header.textContent = mw.message('chat-private-headline', users.join(', ')).text; header.title = users.join(', '); }

// Wait for i18n to be available mw.hook('dev.i18n').add(function(lib) {       lib.loadMessages('ExtendedPrivateMessaging').done(function(lang) { i18n = lang; i18n.useUserLang; // Bind mainRoom events var ref = mainRoom.viewUsers._callbacks.showPrivateMessage.shift; mainRoom.viewUsers.bind('showPrivateMessage', function(e) {               if (e.event.shiftKey) {                    e.event.preventDefault;

remove_selection; open_group_selection;

$('#WikiChatList .User[data-user="' + e.name + '"]').click; } else { ref(e); }           });

// Group PM tooltip mainRoom.viewUsers.bind('mainListClick', function {               var li = document.querySelector('#UserStatsMenu .private');                if (li) {                    li.title = i18n.msg('tooltip').plain;                }            });

// Just one isn't enough, because Chat, that's why mainRoom.viewUsers.bind('privateListClick', room_change_handler); mainRoom.model.room.bind('change', $.debounce(0, room_change_handler)); mainRoom.model.privateUsers.bind('add', new_room_handler);

// Bind DOM events $('#WikiChatList').on('click', '.User', user_click_handler); });   });

// Override mainRoom functions for proper group messaging mainRoom.privateMessage = function(obj) { var connectedUser = !1; var userData; this.model.privateUsers.find(function(userEl) {           if (userEl.get('name') == obj.name) {                if (!userData) {                    connectedUser = !0;                    userData = userEl;                } else {                    var oldId = userData.get('roomId'),                    newId = Number(obj.target.find('.splotch').attr('id').slice(9));                    if (oldId != newId) {                        userData = userEl;                    }                }            }        }); if (connectedUser) { return this.showRoom(userData.get('roomId')); } else { this.openPrivateChat([obj.name]); return true; }   };

mainRoom.viewUsers._callbacks.mainListClick[0] = $.proxy(function(obj) {       var user = this.model.users.findByName(obj.name);        var userMain = this.model.users.findByName(wgUserName);        var userYouAreBlockedBy = this.model.blockedByUsers.findByName(obj.name);        var userPrivate = Object.keys(mainRoom.chats.privates).find(function(key) { var users = mainRoom.chats.privates[key].model.privateRoom.attributes.users; return users.length == 2 && users.indexOf(obj.name) != -1; });       var actions = {            regular: ['profile', 'contribs'],            admin: []        };        if (this.menuHavePrivatBlock(obj.name)) {            if (typeof (userPrivate) == 'undefined' && typeof (userYouAreBlockedBy) == 'undefined') {                actions.regular.push('private');            }        } else {            actions.regular.push('private-allow');        }        if (this.userMain.get('isModerator') === true && user.get('isModerator') === false) {            actions.admin.push('kick');            actions.admin.push('ban');        }        if (this.userMain.get('canPromoteModerator') === true && user.get('isStaff') === false && $.inArray('kick', actions.admin) == -1) {            actions.admin.push('kick');            actions.admin.push('ban');        }        this.viewUsers.showMenu(obj.target, actions);    }, mainRoom); });