Add private messaging
This commit is contained in:
parent
573e59680e
commit
b41529d4aa
|
|
@ -2865,6 +2865,57 @@ Channel.prototype.handleChat = function (user, data) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Channel.prototype.handlePm = function (user, data) {
|
||||||
|
if (typeof data.meta !== "object") {
|
||||||
|
data.meta = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user.name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof data.msg !== "string" || typeof data.to !== "string") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg = data.msg.substring(0, 240);
|
||||||
|
var to = null;
|
||||||
|
for (var i = 0; i < this.users.length; i++) {
|
||||||
|
if (this.users[i].name.toLowerCase() === data.to) {
|
||||||
|
to = this.users[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!to) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var meta = {};
|
||||||
|
if (user.rank >= 2) {
|
||||||
|
if ("modflair" in data.meta && data.meta.modflair === user.rank) {
|
||||||
|
meta.modflair = data.meta.modflair;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.indexOf(">") === 0) {
|
||||||
|
meta.addClass = "greentext";
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = XSS.sanitizeText(msg);
|
||||||
|
msg = this.filterMessage(msg);
|
||||||
|
var msgobj = {
|
||||||
|
username: user.name,
|
||||||
|
to: data.to,
|
||||||
|
msg: msg,
|
||||||
|
meta: meta,
|
||||||
|
time: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
to.socket.emit("pm", msgobj);
|
||||||
|
user.socket.emit("pm", msgobj);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters a chat message
|
* Filters a chat message
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,14 @@ User.prototype.initChannelCallbacks = function () {
|
||||||
|
|
||||||
self.channel.handleChat(self, data);
|
self.channel.handleChat(self, data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
wrapTypecheck("pm", function (data) {
|
||||||
|
if (typeof data.msg !== "string" || typeof data.to !== "string") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.channel.handlePm(self, data);
|
||||||
|
});
|
||||||
|
|
||||||
wrapTypecheck("newPoll", function (data) {
|
wrapTypecheck("newPoll", function (data) {
|
||||||
self.channel.handleOpenPoll(self, data);
|
self.channel.handleOpenPoll(self, data);
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,7 @@ html(lang="en")
|
||||||
mixin permeditor()
|
mixin permeditor()
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-default(type="button", data-dismiss="modal") Close
|
button.btn.btn-default(type="button", data-dismiss="modal") Close
|
||||||
|
#pmbar
|
||||||
include footer
|
include footer
|
||||||
mixin footer()
|
mixin footer()
|
||||||
script(src=sioSource)
|
script(src=sioSource)
|
||||||
|
|
|
||||||
|
|
@ -461,6 +461,25 @@ Callbacks = {
|
||||||
addChatMessage(data);
|
addChatMessage(data);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
pm: function (data) {
|
||||||
|
var name = data.username;
|
||||||
|
if (IGNORED.indexOf(name) !== -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.username === CLIENT.name) {
|
||||||
|
name = data.to;
|
||||||
|
}
|
||||||
|
var pm = initPm(name);
|
||||||
|
var msg = formatChatMessage(data, pm.data("last"));
|
||||||
|
var buffer = pm.find(".pm-buffer");
|
||||||
|
msg.appendTo(buffer);
|
||||||
|
buffer.scrollTop(buffer.prop("scrollHeight"));
|
||||||
|
if (pm.find(".panel-body").is(":hidden")) {
|
||||||
|
pm.removeClass("panel-default").addClass("panel-primary");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
joinMessage: function(data) {
|
joinMessage: function(data) {
|
||||||
if(USEROPTS.joinmessage)
|
if(USEROPTS.joinmessage)
|
||||||
addChatMessage(data);
|
addChatMessage(data);
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,9 @@ var CHATHIST = [];
|
||||||
var CHATHISTIDX = 0;
|
var CHATHISTIDX = 0;
|
||||||
var CHATTHROTTLE = false;
|
var CHATTHROTTLE = false;
|
||||||
var SCROLLCHAT = true;
|
var SCROLLCHAT = true;
|
||||||
var LASTCHATNAME = "";
|
var LASTCHAT = {
|
||||||
var LASTCHATTIME = 0;
|
name: ""
|
||||||
|
};
|
||||||
var FOCUSED = true;
|
var FOCUSED = true;
|
||||||
var PAGETITLE = "CyTube";
|
var PAGETITLE = "CyTube";
|
||||||
var TITLE_BLINK;
|
var TITLE_BLINK;
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,15 @@ function addUserDropdown(entry) {
|
||||||
ignore.text("Unignore User");
|
ignore.text("Unignore User");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* pm button */
|
||||||
|
var pm = $("<button/>").addClass("btn btn-xs btn-default")
|
||||||
|
.text("Private Message")
|
||||||
|
.appendTo(btngroup)
|
||||||
|
.click(function () {
|
||||||
|
initPm(name).find(".panel-heading").click();
|
||||||
|
menu.hide();
|
||||||
|
});
|
||||||
|
|
||||||
/* give/remove leader (moderator+ only) */
|
/* give/remove leader (moderator+ only) */
|
||||||
if (hasPermission("leaderctl")) {
|
if (hasPermission("leaderctl")) {
|
||||||
var ldr = $("<button/>").addClass("btn btn-xs btn-default")
|
var ldr = $("<button/>").addClass("btn btn-xs btn-default")
|
||||||
|
|
@ -1251,7 +1260,7 @@ function sendVideoUpdate() {
|
||||||
|
|
||||||
/* chat */
|
/* chat */
|
||||||
|
|
||||||
function formatChatMessage(data) {
|
function formatChatMessage(data, last) {
|
||||||
// Backwards compat
|
// Backwards compat
|
||||||
if (!data.meta || data.msgclass) {
|
if (!data.meta || data.msgclass) {
|
||||||
data.meta = {
|
data.meta = {
|
||||||
|
|
@ -1261,7 +1270,7 @@ function formatChatMessage(data) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Phase 1: Determine whether to show the username or not
|
// Phase 1: Determine whether to show the username or not
|
||||||
var skip = data.username === LASTCHATNAME;
|
var skip = data.username === last.name;
|
||||||
if(data.meta.addClass === "server-whisper")
|
if(data.meta.addClass === "server-whisper")
|
||||||
skip = true;
|
skip = true;
|
||||||
// Prevent impersonation by abuse of the bold filter
|
// Prevent impersonation by abuse of the bold filter
|
||||||
|
|
@ -1272,8 +1281,7 @@ function formatChatMessage(data) {
|
||||||
|
|
||||||
data.msg = execEmotes(data.msg);
|
data.msg = execEmotes(data.msg);
|
||||||
|
|
||||||
LASTCHATNAME = data.username;
|
last.name = data.username;
|
||||||
LASTCHATTIME = data.time;
|
|
||||||
var div = $("<div/>");
|
var div = $("<div/>");
|
||||||
/* drink is a special case because the entire container gets the class, not
|
/* drink is a special case because the entire container gets the class, not
|
||||||
just the message */
|
just the message */
|
||||||
|
|
@ -1332,7 +1340,7 @@ function addChatMessage(data) {
|
||||||
if(IGNORED.indexOf(data.username) !== -1) {
|
if(IGNORED.indexOf(data.username) !== -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var div = formatChatMessage(data);
|
var div = formatChatMessage(data, LASTCHAT);
|
||||||
// Incoming: a bunch of crap for the feature where if you hover over
|
// Incoming: a bunch of crap for the feature where if you hover over
|
||||||
// a message, it highlights messages from that user
|
// a message, it highlights messages from that user
|
||||||
div.data("sender", data.username);
|
div.data("sender", data.username);
|
||||||
|
|
@ -2265,3 +2273,72 @@ function execEmotes(msg) {
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initPm(user) {
|
||||||
|
if ($("#pm-" + user).length > 0) {
|
||||||
|
return $("#pm-" + user);
|
||||||
|
}
|
||||||
|
|
||||||
|
var pm = $("<div/>").addClass("panel panel-default pm-panel")
|
||||||
|
.appendTo($("#pmbar"))
|
||||||
|
.data("last", { name: "" })
|
||||||
|
.attr("id", "pm-" + user);
|
||||||
|
|
||||||
|
var title = $("<div/>").addClass("panel-heading").text(user).appendTo(pm);
|
||||||
|
var close = $("<button/>").addClass("close pull-right")
|
||||||
|
.html("×")
|
||||||
|
.appendTo(title).click(function () {
|
||||||
|
pm.remove();
|
||||||
|
$("#pm-placeholder-" + user).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
var body = $("<div/>").addClass("panel-body").appendTo(pm).hide();
|
||||||
|
var placeholder;
|
||||||
|
title.click(function () {
|
||||||
|
body.toggle();
|
||||||
|
pm.removeClass("panel-primary").addClass("panel-default");
|
||||||
|
if (!body.is(":hidden")) {
|
||||||
|
placeholder = $("<div/>").addClass("pm-panel-placeholder")
|
||||||
|
.attr("id", "pm-placeholder-" + user)
|
||||||
|
.insertAfter(pm);
|
||||||
|
var left = pm.position().left;
|
||||||
|
pm.css("position", "absolute")
|
||||||
|
.css("bottom", "0px")
|
||||||
|
.css("left", left);
|
||||||
|
} else {
|
||||||
|
pm.css("position", "");
|
||||||
|
$("#pm-placeholder-" + user).remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var buffer = $("<div/>").addClass("pm-buffer linewrap").appendTo(body);
|
||||||
|
$("<hr/>").appendTo(body);
|
||||||
|
var input = $("<input/>").addClass("form-control pm-input").attr("type", "text")
|
||||||
|
.appendTo(body);
|
||||||
|
|
||||||
|
input.keyup(function (ev) {
|
||||||
|
if (ev.keyCode === 13) {
|
||||||
|
var meta = {};
|
||||||
|
var msg = input.val();
|
||||||
|
if (msg.trim() === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (USEROPTS.modhat && CLIENT.rank >= Rank.Moderator) {
|
||||||
|
meta.modflair = CLIENT.rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CLIENT.rank >= 2 && msg.indexOf("/m ") === 0) {
|
||||||
|
meta.modflair = CLIENT.rank;
|
||||||
|
msg = msg.substring(3);
|
||||||
|
}
|
||||||
|
socket.emit("pm", {
|
||||||
|
to: user,
|
||||||
|
msg: msg,
|
||||||
|
meta: meta
|
||||||
|
});
|
||||||
|
input.val("");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return pm;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -500,3 +500,47 @@ li.ui-sortable-helper, li.ui-sortable-placeholder + li.queue_entry {
|
||||||
#cs-emotes td:nth-child(3) {
|
#cs-emotes td:nth-child(3) {
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pmbar {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pm-panel, .pm-panel-placeholder {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
float: left;
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pm-panel {
|
||||||
|
margin-bottom: 0!important;
|
||||||
|
border-radius: 0!important;
|
||||||
|
border-radius: 0!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pm-panel > .panel-heading {
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 0!important;
|
||||||
|
border-radius: 0!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pm-panel > .panel-body {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pm-panel > .panel-body > .pm-buffer {
|
||||||
|
height: 200px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pm-panel > .panel-body > hr {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pm-input {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
border-top-left-radius: 0!important;
|
||||||
|
border-top-right-radius: 0!important;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue