mirror of https://github.com/calzoneman/sync.git
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
|
||||
*/
|
||||
|
|
|
@ -257,6 +257,14 @@ User.prototype.initChannelCallbacks = function () {
|
|||
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) {
|
||||
self.channel.handleOpenPoll(self, data);
|
||||
});
|
||||
|
|
|
@ -202,6 +202,7 @@ html(lang="en")
|
|||
mixin permeditor()
|
||||
.modal-footer
|
||||
button.btn.btn-default(type="button", data-dismiss="modal") Close
|
||||
#pmbar
|
||||
include footer
|
||||
mixin footer()
|
||||
script(src=sioSource)
|
||||
|
|
|
@ -461,6 +461,25 @@ Callbacks = {
|
|||
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) {
|
||||
if(USEROPTS.joinmessage)
|
||||
addChatMessage(data);
|
||||
|
|
|
@ -56,8 +56,9 @@ var CHATHIST = [];
|
|||
var CHATHISTIDX = 0;
|
||||
var CHATTHROTTLE = false;
|
||||
var SCROLLCHAT = true;
|
||||
var LASTCHATNAME = "";
|
||||
var LASTCHATTIME = 0;
|
||||
var LASTCHAT = {
|
||||
name: ""
|
||||
};
|
||||
var FOCUSED = true;
|
||||
var PAGETITLE = "CyTube";
|
||||
var TITLE_BLINK;
|
||||
|
|
|
@ -199,6 +199,15 @@ function addUserDropdown(entry) {
|
|||
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) */
|
||||
if (hasPermission("leaderctl")) {
|
||||
var ldr = $("<button/>").addClass("btn btn-xs btn-default")
|
||||
|
@ -1251,7 +1260,7 @@ function sendVideoUpdate() {
|
|||
|
||||
/* chat */
|
||||
|
||||
function formatChatMessage(data) {
|
||||
function formatChatMessage(data, last) {
|
||||
// Backwards compat
|
||||
if (!data.meta || data.msgclass) {
|
||||
data.meta = {
|
||||
|
@ -1261,7 +1270,7 @@ function formatChatMessage(data) {
|
|||
};
|
||||
}
|
||||
// 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")
|
||||
skip = true;
|
||||
// Prevent impersonation by abuse of the bold filter
|
||||
|
@ -1272,8 +1281,7 @@ function formatChatMessage(data) {
|
|||
|
||||
data.msg = execEmotes(data.msg);
|
||||
|
||||
LASTCHATNAME = data.username;
|
||||
LASTCHATTIME = data.time;
|
||||
last.name = data.username;
|
||||
var div = $("<div/>");
|
||||
/* drink is a special case because the entire container gets the class, not
|
||||
just the message */
|
||||
|
@ -1332,7 +1340,7 @@ function addChatMessage(data) {
|
|||
if(IGNORED.indexOf(data.username) !== -1) {
|
||||
return;
|
||||
}
|
||||
var div = formatChatMessage(data);
|
||||
var div = formatChatMessage(data, LASTCHAT);
|
||||
// Incoming: a bunch of crap for the feature where if you hover over
|
||||
// a message, it highlights messages from that user
|
||||
div.data("sender", data.username);
|
||||
|
@ -2265,3 +2273,72 @@ function execEmotes(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) {
|
||||
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 New Issue