diff --git a/lib/api.js b/lib/api.js index ca7e4677..de03ad85 100644 --- a/lib/api.js +++ b/lib/api.js @@ -448,7 +448,10 @@ module.exports = function (Server) { image: img, text: text }; - chan.broadcastUserUpdate(user); + chan.sendAll("setUserProfile", { + name: user.name, + profile: user.profile + }); } } } diff --git a/lib/channel.js b/lib/channel.js index 0c8ab362..a7789afc 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -1004,13 +1004,15 @@ Channel.prototype.sendUserlist = function(user) { users.push({ name: this.users[i].name, rank: this.users[i].rank, - leader: this.users[i] == this.leader, meta: this.users[i].meta, profile: this.users[i].profile }); } } user.socket.emit("userlist", users); + if (this.leader !== null) { + user.socket.emit("setLeader", this.leader.name); + } } // Send the last 15 messages for context @@ -1038,6 +1040,14 @@ Channel.prototype.sendAllWithRank = function(rank, msg, data) { } } +Channel.prototype.sendAllExcept = function(user, msg, data) { + for(var i = 0; i < this.users.length; i++) { + if (this.users[i] !== user) { + this.users[i].socket.emit(msg, data); + } + } +} + Channel.prototype.broadcastPlaylistMeta = function() { var total = 0; var iter = this.playlist.items.first; @@ -1095,16 +1105,24 @@ Channel.prototype.broadcastNewUser = function(user) { self.kick(user, "You're banned!"); return; } - if (self.mutedUsers.contains(user.name.toLowerCase())) { + if (self.mutedUsers.contains(user.name.toLowerCase()) || + self.mutedUsers.contains("[shadow]"+user.name.toLowerCase())) { user.meta.icon = "icon-volume-off"; } - self.sendAll("addUser", { + + var pkt = { name: user.name, rank: user.rank, - leader: self.leader == user, meta: user.meta, profile: user.profile - }); + }; + if (self.mutedUsers.contains("[shadow]"+user.name.toLowerCase())) { + self.sendAllExcept(user, "addUser", pkt); + pkt.meta.icon = false; + user.socket.emit("addUser", pkt); + } else { + self.sendAll("addUser", pkt); + } if(user.rank > 0) { self.saveInitialRank(user); @@ -1118,21 +1136,7 @@ Channel.prototype.broadcastNewUser = function(user) { msgclass: "server-whisper", time: Date.now() }; - self.users.forEach(function(u) { - if(u.rank >= 2) { - u.socket.emit("joinMessage", pkt); - } - }); - }); -} - -Channel.prototype.broadcastUserUpdate = function(user) { - this.sendAll("updateUser", { - name: user.name, - rank: user.rank, - leader: this.leader == user, - meta: user.meta, - profile: user.profile + self.sendAllWithRank(2, "joinMessage", pkt); }); } @@ -2323,7 +2327,10 @@ Channel.prototype.trySetRank = function(user, data) { self.sendAllWithRank(3, "setChannelRank", data); }); } - self.broadcastUserUpdate(receiver); + self.sendAll("setUserRank", { + name: receiver.name, + rank: receiver.rank + }); } else if(self.registered) { self.getRank(data.user, function (err, rrank) { if (self.dead) @@ -2354,15 +2361,20 @@ Channel.prototype.changeLeader = function(name) { if(old.rank == 1.5) { old.rank = old.oldrank; } - this.broadcastUserUpdate(old); + this.sendAll("setUserRank", { + name: name, + rank: old.rank + }); } if(name == "") { + this.sendAll("setLeader", ""); this.logger.log("*** Resuming autolead"); this.playlist.lead(true); return; } for(var i = 0; i < this.users.length; i++) { if(this.users[i].name == name) { + this.sendAll("setLeader", name); this.logger.log("*** Assigned leader: " + name); this.playlist.lead(false); this.leader = this.users[i]; @@ -2370,7 +2382,10 @@ Channel.prototype.changeLeader = function(name) { this.users[i].oldrank = this.users[i].rank; this.users[i].rank = 1.5; } - this.broadcastUserUpdate(this.leader); + this.sendAll("setUserRank", { + name: name, + rank: this.users[i].rank + }); } } } diff --git a/lib/chatcommand.js b/lib/chatcommand.js index b4c7c1f2..d133d094 100644 --- a/lib/chatcommand.js +++ b/lib/chatcommand.js @@ -119,8 +119,21 @@ function handleShadowMute(chan, user, args) { }); return; } + /* Reset a previous regular mute */ + if (chan.mutedUsers.contains(person.name.toLowerCase())) { + chan.mutedUsers.remove(person.name.toLowerCase()); + chan.sendAll("setUserIcon", { + name: person.name, + icon: false + }); + } chan.mutedUsers.add("[shadow]" + person.name.toLowerCase()); chan.logger.log("*** " + user.name + " shadow muted " + args[0]); + person.meta.icon = "icon-volume-off"; + chan.sendAllExcept(person, "setUserIcon", { + name: person.name, + icon: "icon-volume-off" + }); var pkt = { username: "[server]", msg: user.name + " shadow muted " + args[0], @@ -156,7 +169,10 @@ function handleMute(chan, user, args) { } person.meta.icon = "icon-volume-off"; chan.mutedUsers.add(person.name.toLowerCase()); - chan.broadcastUserUpdate(person); + chan.sendAll("setUserIcon", { + name: person.name, + icon: "icon-volume-off" + }); chan.logger.log("*** " + user.name + " muted " + args[0]); } } @@ -183,7 +199,10 @@ function handleUnmute(chan, user, args) { person.meta.icon = false; chan.mutedUsers.remove(person.name.toLowerCase()); chan.mutedUsers.remove("[shadow]" + person.name.toLowerCase()); - chan.broadcastUserUpdate(person); + chan.sendAll("setUserIcon", { + name: person.name, + icon: false + }); chan.logger.log("*** " + user.name + " unmuted " + args[0]); } } diff --git a/lib/user.js b/lib/user.js index 61192353..a6a3af32 100644 --- a/lib/user.js +++ b/lib/user.js @@ -589,8 +589,12 @@ User.prototype.initCallbacks = function () { self.rank = rank; self.socket.emit("rank", rank); - if (self.inChannel()) - self.channel.broadcastUserUpdate(self); + if (self.inChannel()) { + self.channel.sendAll("setUserRank", { + name: self.name, + rank: rank + }); + } }); }; diff --git a/www/assets/js/callbacks.js b/www/assets/js/callbacks.js index b7304f3c..c1c5d7b0 100644 --- a/www/assets/js/callbacks.js +++ b/www/assets/js/callbacks.js @@ -673,6 +673,11 @@ Callbacks = { .addClass("userlist_item"); var flair = $("").appendTo(div); var nametag = $("").text(data.name).appendTo(div); + div.data("name", data.name); + div.data("rank", data.rank); + div.data("leader", false); + div.data("profile", data.profile); + div.data("icon", data.meta.icon); formatUserlistItem(div, data); addUserDropdown(div, data); div.appendTo($("#userlist")); @@ -682,13 +687,54 @@ Callbacks = { setLeader: function (name) { $(".userlist_item").each(function () { $(this).find(".icon-star-empty").remove(); + if ($(this).data("leader")) { + $(this).data("leader", false); + addUserDropdown($(this)); + } }); if (name === "") return; var user = findUserlistItem(name); if (user) { - $("").addClass("icon-star-empty").prependTo(user.children()[0]); + user.data("leader", true); + formatUserlistItem(user); + addUserDropdown(user); } + if (name === CLIENT.name) { + CLIENT.leader = true; + // I'm a leader! Set up sync function + if(LEADTMR) + clearInterval(LEADTMR); + LEADTMR = setInterval(sendVideoUpdate, 5000); + } else { + CLIENT.leader = false; + if(LEADTMR) + clearInterval(LEADTMR); + LEADTMR = false; + } + }, + + setUserRank: function (data) { + var user = findUserlistItem(data.name); + if (user === null) { + return; + } + + user.data("rank", data.rank); + formatUserlistItem(user); + addUserDropdown(user); + if(USEROPTS.sort_rank) + sortUserlist(); + }, + + setUserIcon: function (data) { + var user = findUserlistItem(data.name); + if (user === null) { + return; + } + + user.data("icon", data.icon); + formatUserlistItem(user); }, updateUser: function(data) { @@ -712,6 +758,7 @@ Callbacks = { } var user = findUserlistItem(data.name); if(user !== null) { + user.data("rank", data.rank); formatUserlistItem(user, data); addUserDropdown(user, data); if(USEROPTS.sort_rank) diff --git a/www/assets/js/util.js b/www/assets/js/util.js index 1f1bacd5..f39c6b95 100644 --- a/www/assets/js/util.js +++ b/www/assets/js/util.js @@ -77,7 +77,14 @@ function findUserlistItem(name) { return null; } -function formatUserlistItem(div, data) { +function formatUserlistItem(div) { + var data = { + name: div.data("name") || "", + rank: div.data("rank"), + profile: div.data("profile") || { image: "", text: ""}, + leader: div.data("leader") || false, + icon: div.data("icon") || false + }; var name = $(div.children()[1]); name.removeClass(); name.css("font-style", ""); @@ -109,7 +116,6 @@ function formatUserlistItem(div, data) { name.mouseleave(function() { profile.remove(); }); - var flair = div.children()[0]; flair.innerHTML = ""; // denote current leader with a star @@ -120,8 +126,8 @@ function formatUserlistItem(div, data) { name.css("font-style", "italic"); $("").addClass("icon-time").appendTo(flair); } - if(data.meta && data.meta.icon) { - $("").addClass(data.meta.icon).prependTo(flair); + if (data.icon) { + $("").addClass(data.icon).prependTo(flair); } } @@ -138,11 +144,10 @@ function getNameColor(rank) { return ""; } -function addUserDropdown(entry, data) { - entry.data("dropdown-info", data); - var name = data.name, - rank = data.rank, - leader = data.leader; +function addUserDropdown(entry) { + var name = entry.data("name"), + rank = entry.data("rank"), + leader = entry.data("leader"); entry.find(".user-dropdown").remove(); var menu = $("
") .addClass("user-dropdown") @@ -285,7 +290,10 @@ function calcUserBreakdown() { }; var total = 0; $("#userlist .userlist_item").each(function (index, item) { - var data = $(item).data("dropdown-info"); + var data = { + rank: $(item).data("rank") + }; + if(data.rank >= 255) breakdown["Site Admins"]++; else if(data.rank >= 3) @@ -312,8 +320,8 @@ function sortUserlist() { var slice = Array.prototype.slice; var list = slice.call($("#userlist .userlist_item")); list.sort(function (a, b) { - var r1 = $(a).data("dropdown-info").rank; - var r2 = $(b).data("dropdown-info").rank; + var r1 = $(a).data("rank"); + var r2 = $(b).data("rank"); var afk1 = $(a).find(".icon-time").length > 0; var afk2 = $(b).find(".icon-time").length > 0; var name1 = a.children[1].innerHTML.toLowerCase(); @@ -1132,7 +1140,7 @@ function handlePermissionChange() { } var users = $("#userlist").children(); for(var i = 0; i < users.length; i++) { - addUserDropdown($(users[i]), $(users[i]).data("dropdown-info")); + addUserDropdown($(users[i])); } $("#chatline").attr("disabled", !hasPermission("chat"));