Light12306/Web12306/js/ui/chat/roomsession.js

524 lines
20 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

define(function (require, exports, module) {
var EventObject = require("../../platform/EventObject.js");
var ep = require("../../platform/extensionPort.js");
var port = ep.port;
var mp = require("../widget_message_popup.js");
var sessMgr = require("../../account/sessionMgr.js");
var param = require("../../data.js");
var page = $("#chat_container");
var user = sessMgr.current;
var utility = require("../../utility.js");
var coder = require("../../platform/messageCoder.js");
var cmds = require("./actionCommand.js");
var securityCheck = require("../../platform/securityCheck.js");
var emojiRoot = "/images/emoji/";
var media = require("../../platform/media.js");
var lastPopupTip = parseInt(sessionStorage["lastRoomMstAt"] || "0", 10);
var checkPrivilege = function () {
securityCheck.isAdmin = user && (user.username === 'imfish' || user.username === 'iccfish');
};
sessMgr.on("sessionChanged", function () {
if (!sessMgr.current) {
session.exitRoom();
} else {
user = sessMgr.current;
checkPrivilege();
}
});
checkPrivilege();
var RoomSession = function () {
EventObject.apply(this);
var that = this;
var room;
var chatListContainer = page.find("article.chat-items");
var chatListContainerDom = chatListContainer[0];
var roomStateTemplate = $("#chat_connect_server").doT();
var roomSystemNoticeTemplate = $("#chat_sys_alert").doT();
var roomSysMessage = $("#chat_sys_message").doT();
var chatMsgItem = $("#chat_msg_item").doT();
//init pic send.
var fileReader = new FileReader();
fileReader.onload = function (fe) {
that.sendMsg({
color: user.options.chatColor,
text: "[贴图]",
target: []
}, [
{
type: "image",
data: fe.target.result
}]);
};
this.sendPic = function (file) {
if (!/^image\//i.test(file.type) || file.size > 100 * 1024) {
mp.showMessagePopup("error", "只能发送小于100K的图片哦");
return;
}
fileReader.readAsDataURL(file);
};
this.clearConnectingState = function () {
chatListContainer.find(".chat-state").remove();
};
this.enterRoom = function (targetRoom) {
if (targetRoom === room || (targetRoom && room && targetRoom.id === room.id))
return;
room = targetRoom;
//UI
$("#chat_frame>section").removeClass("chat-page-current");
page.addClass("chat-page-current");
page.find(">header>span:eq(0)").html(room.name);
chatListContainer.empty();
that.refreshOnlineCount();
page.find("button.button-primary").prop("disabled", true);
that.fireEvent("enterRoom");
if (!room.url) {
that.appendMessageItem(roomStateTemplate({ state: "connecting", stateIcon: "fa-spin fa-spinner", msg: "正在获得房间地址..." }));
$.post(param.chatServerGetAddressApi, { roomId: room.id }, "json").done(function (result) {
if (!result.url) {
that.clearConnectingState();
that.appendMessageItem(roomStateTemplate({ state: "disconnect", stateIcon: "fa-times", msg: "无法进入房间,请重试。", exinfo: "<a href='javascript:;' class='chat-frame-reconnect'>重新连接</a>" }));
that.exitRoom();
mp.showMessagePopup("error", "无法进入房间,请稍后重试。");
} else {
room.url = result.url;
room.heartbeat = result.heartbeat;
that.clearConnectingState();
port.postMessage("enterChatRoom", room);
}
}).fail(function () {
that.clearConnectingState();
that.appendMessageItem(roomStateTemplate({ state: "disconnect", stateIcon: "fa-times", msg: "无法进入房间,请重试。", exinfo: "<a href='javascript:;' class='chat-frame-reconnect'>重新连接</a>" }));
that.exitRoom();
mp.showMessagePopup("error", "无法进入房间,请稍后重试。");
});
} else {
if (!room.orgUrl) {
room.orgUrl = room.url;
room.url = room.orgUrl.replace(/#uid#/, user.username + "/" + user.dispname);
}
port.postMessage("enterChatRoom", room);
}
ep.track(param.trackTypes.JOIN_CHAT);
};
this.refreshOnlineCount = function () {
page.find(">header>span:eq(1)").html("当前在线 " + room.onlinecount + " 人");
page.find(".chat-online-count").html(room.onlinecount);
};
this.exitRoom = function () {
room = null;
port.postMessage("disconnectChatRoom");
that.fireEvent("exitRoom");
ep.track(param.trackTypes.EXIT_CHAT);
};
this.appendMessageItem = function (html) {
chatListContainer.append(html);
if (sessMgr.current.options.autoScroll !== 0)
chatListContainerDom.scrollTop = chatListContainerDom.scrollHeight;
};
this.clearDisplay = function () {
chatListContainer.empty();
};
this.sendMsg = function (msg, media) {
var errormsg = securityCheck.checkIllegalWords(msg.text);
if (errormsg) {
alert(errormsg);
return;
}
var data = {
content: msg.text,
color: /([a-f\d]{6})/i.exec(msg.color || "") && RegExp.$1 || "",
images: [],
fromUser: {
realname: user.dispname,
username: user.username
},
toUsers: msg.target || [],
time: new Date(),
action: "sendMsg",
systemMessage: false,
userMsgType: cmds.USER_SENDMSG,
success: true
};
if (securityCheck.checkIllegalUserName(data.toUsers.realname)) {
mp.showMessagePopup("error", "发言失败!");
return;
}
if (media && media.length) {
var tip = new mp.MessagePopup("loading", "正在上传图片,请稍等...");
tip.show();
//带有图片
$.post("http://12306.liebao.cn/index.php?r=UpdateImage/GetImageUrl", { data: media[0].data })
.done(function (json) {
tip.close();
if (json.resCode === 0) {
setTimeout(function () {
data.images.push(json.data.img_url);
port.postMessage("chatRoomSendMsg", coder.encode(data));
}, 1000);
}
}).fail(function () {
tip.setState("error", "图片上传失败:服务器开小差了....");
tip.delayClose();
});
} else {
port.postMessage("chatRoomSendMsg", coder.encode(data));
}
};
this.reconnect = function () {
if (!room)
return;
port.postMessage("enterChatRoom", room);
};
this.processSysMessage = function (msg) {
if (msg.sysMsgType === cmds.SYS_USERENTER) {
//用户进入
var info = msg.content.split('\t');
room.onlinecount = parseInt(info[0]);
that.refreshOnlineCount();
if (info[1] === user.username) {
//自己进入
that.appendMessageItem(roomSysMessage({ stateIcon: "fa-info-circle", state: "system", msg: "您已进入房间,当前房间在线 " + room.onlinecount + " 人。" }));
} else {
if (sessMgr.current.options.showRoomEnter)
that.appendMessageItem(roomSysMessage({ stateIcon: "fa-info-circle", state: "system", msg: '<a href="javascript:;" class="chat-item-at" data-un="' + utility.htmlEncode(info[1]) + '">' + utility.htmlEncode(info[2]) + '</a> 已进入房间,当前房间在线 ' + room.onlinecount + " 人。" }));
}
} else if (msg.sysMsgType === cmds.SYS_USEREXIT) {
//用户退出
var info = msg.content.split('\t');
room.onlinecount = parseInt(info[0]);
that.refreshOnlineCount();
if (info[1] === user.username) {
//自己进入
that.appendMessageItem(roomSysMessage({ stateIcon: "fa-info-circle", state: "system", msg: "您已离开房间,当前房间在线 " + room.onlinecount + " 人。" }));
} else {
if (sessMgr.current.options.showRoomEnter)
that.appendMessageItem(roomSysMessage({ stateIcon: "fa-info-circle", state: "system", msg: '<a href="javascript:;" class="chat-item-at" data-un="' + utility.htmlEncode(info[1]) + '">' + utility.htmlEncode(info[2]) + '</a> 已离开房间,当前房间在线 ' + room.onlinecount + " 人。" }));
}
} else if (msg.sysMsgType === cmds.SYS_SENDFAILED) {
} else if (msg.sysMsgType === cmds.SYS_OPERATIONBLOCKED) {
mp.showMessagePopup("error", msg.content);
} else if (msg.sysMsgType === cmds.SYS_UPDATEONLINECOUNT) {
that.appendMessageItem(roomSysMessage({ stateIcon: "fa-info-circle", state: "system", msg: "您已离开房间,当前房间在线 " + room.onlinecount + " 人。" }));
} else if (msg.sysMsgType === cmds.SYS_REPORTABUSERESULT) {
that.appendMessageItem(roomSysMessage({ stateIcon: "fa-info-circle", state: "system", msg: msg.content }));
}
};
this.processUserMessage = function (msg) {
//安全检测
if (securityCheck.checkIllegalUserName(msg.fromUser.username) || securityCheck.checkIllegalWords(msg.content))
return;
msg.self = msg.fromUser.username === sessMgr.current.username;
if (msg.color)
msg.color = "#" + msg.color;
//咩哈哈哈哈
if (msg.fromUser.username === "iccfish" || msg.fromUser.username === "imfish") {
msg.fromUser.realname = "木魚";
msg.fromUser.exStyle = "font-weight:bold;";
}
if (msg.fromUser.username === "*") {
msg.fromUser.realname = "<系统管理员>";
msg.fromUser.exStyle = "font-weight:bold;";
msg.sys = true;
}
msg.tome = false;
if (msg.toUsers && msg.toUsers.length) {
var selfTarget = _.findWhere(msg.toUsers, { username: sessMgr.current.username });
if (selfTarget) {
msg.tome = true;
selfTarget.username = null;
selfTarget.realname = "我";
}
}
if (msg.tome && lastPopupTip < msg.id && sessMgr.current.options.popupAt) {
sessionStorage["lastRoomMstAt"] = msg.id;
media.notify("聊天室@提醒", msg.fromUser.realname + " 对你说:" + msg.content);
}
//replace icon
msg.content = msg.content || "";
msg.content = utility.htmlEncode(msg.content).replace(/https?:\/\/[a-z\d\.-_\/%+\[\]\(\)\&\$!@]+/gi,"<a href='$&' target='_blank'>$&</a>");
msg.content = msg.content.replace(/:([a-z\d-+_]+):/gi, function ($0, $1) {
return "<img src='" + emojiRoot + "/" + $1 + ".png' />";
});
that.appendMessageItem(chatMsgItem(msg));
};
Object.defineProperty(this, "room", {
get: function () {
return room;
}
});
port.on("chatRoomConnecting", function () {
that.appendMessageItem(roomStateTemplate({ state: "connecting", stateIcon: "fa-spin fa-spinner", msg: "正在连接服务器中..." }));
that.fireEvent("chatRoomConnecting");
});
port.on("chatRoomConnected", function () {
page.find("button.button-primary").prop("disabled", false);
that.clearConnectingState();
that.appendMessageItem(roomSystemNoticeTemplate(room));
that.fireEvent("chatRoomConnected");
});
port.on("chatRoomReceiveMsg", function (e, evd) {
that.fireEvent("chatRoomReceiveMsg");
var data = coder.decode(evd.buffer);
if (!data)
return;
//check
if (data.images) {
if (_.some(data.images, function (m) {
return !/^http:\/\/www\.liebao\.cn\/.*/.test(m);
}))
return;
}
if (data.time) {
data.timeStr = utility.formatDate(data.time, "hh:mm:ss");
}
if (data.systemMessage)
that.processSysMessage(data);
else that.processUserMessage(data);
});
port.on("chatRoomDisconnected", function () {
that.clearConnectingState();
that.appendMessageItem(roomStateTemplate({ state: "disconnect", stateIcon: "fa-times", msg: "服务器已断开连接。", exinfo: "<a href='javascript:;' class='chat-frame-reconnect'>重新连接</a>" }));
that.fireEvent("chatRoomDisconnected");
page.find("button.button-primary").prop("disabled", true);
});
port.on("chatUpdateOnline", function (e, d) {
if (!room)
return;
room.onlinecount = d.count;
//更新显示
that.refreshOnlineCount();
//更新显示
$("#chat_server_select li[data-id='" + room.id + "'] span").html("(" + d.count + "人)");
});
port.on("sendMessageFailed", function (e, data) {
that.appendMessageItem(roomStateTemplate({ state: "error", stateIcon: "fa-times", msg: "消息发送失败:" + data, exinfo: "" }));
});
return this;
};
RoomSession.prototype = Object.create(EventObject);
RoomSession.constructor = RoomSession;
var session = new RoomSession();
(function chatEditor() {
var editor = page.find("section.chat-editor");
var sendBtn = editor.find(">footer>button.button-primary");
var editorArea = editor.find(".chat-editor-container");
var emojiIcons = "-p1|-1|angry|anguished|astonished|baby_chick|bear|beetle|bird|blush|cat|chicken|cold_sweat|confounded|confused|congratulations|construction_worker|cry|crying_cat_face|disappointed|disappointed_relieved|dizzy_face|dog|dog2|expressionless|fearful|flushed|frowning|grimacing|grin|grinning|hatched_chick|heart_eyes|heart_eyes_cat|hushed|innocent|joy|joy_cat|kissing|kissing_cat|kissing_closed_eyes|kissing_heart|kissing_smiling_eyes|laughing|mask|mouse|neutral_face|no_good|no_mouth|open_mouth|point_down|point_left|point_right|point_up|point_up_2|pouting_cat|rage|relaxed|relieved|satisfied|scream|scream_cat|sleeping|sleepy|smile|smiley|smiley_cat|smile_cat|smirk|smirk_cat|sob|stuck_out_tongue|stuck_out_tongue_closed_eyes|stuck_out_tongue_winking_eye|sunglasses|sweat|sweat_smile|tired_face|triumph|tropical_fish|unamused|warning|wave|weary|wink|worried|yellow_heart|yum".split('|');
//var specChars = "(^.^)\n(;_;)\n(¬_¬)\n(u_u)\n♪(´ε`)\n♪(´▽`)\n*_*\n⊙⊙!\n(ーー;)\n(-_-)zz\n↖(^ω^)↗\n囧rz\n^_^\n`(*∩_∩*)\n ̄□ ̄\nO(∩_∩)O\n*^_^* \n^_^#\n(☆_☆)/~~\n→_→ \n( o )~zZ\n(^ω^) \n(ˇ^ˇ)\no(>_<)o ~~\n>_<#\n⊙▂⊙\n╰_╯\n`(*><*)\n(⊙o⊙)\no(╯□╰)o\n::>_<:: \n=_=\nT_T\no(>_<)o ~~\n(#)凸\n:-x\n{{{(>_< )}}} \n(╯-╰)/ \nY(^o^)Y~\nY(^o^)Y~\n($ _ $)\no(︶︿︶)o\n⊙△⊙\n~~~^o^~~~\n╮(╯_╰)╭\n^_^#\n`(*∩_∩*)\n(⊙_⊙;)\n>_<||| \n@_@\n(⊙⊙?)\n^_~ \n(ˉ(∞)ˉ) \n^(oo)^ \n(◦ \"̮ ◦)\nヽミ ´∀`ミノ< \nヽ゚Д゚丿\nヽ(●´ε`●) \nヽ(≧Д≦)\nヽ(^0^)\nヾ(@^▽^@) \nヽ(*´∀`)\nヾ ^_^♪\n━(゚∀゚)━!\n(^▽^)コ祝贺你\nლ(╹ε╹ლ) \nლ(╹◡╹ლ)\nლ(^o^ლ) \nΣ(゚д゚lll)\nΣ(゚д゚;)\nΣ(TωT)努力--\nσ(´┰`=)\nε=┌(;・∀・)┘\nε=(・д・`*)ハァ…\nY(・∀・)Y 蟹\nY(>_<、)Y\nw(^_ン\n=0=\nT(;_;)T\np(^^)q\no(TヘTo)\noo\nm(-_-m) \nm(__)m\n♪(´ε` )\n☆彡\n☆ミ\n☆⌒(>。≪)\n☆⌒(*-゜)v\n≡(  ´Д`)/≡=\n∑(O_O)\n∑(・∀・) コ坏了 !!\n<(ToT)>\n{[(-_-)(-_-)]}zzz\n(・o・)/!\n(◎o◎)\n(^o^)/了解!\n(つд⊂)伤心\n゚Θ゚ \n(T▽T)\n(T_T)/~~\n(o・・o)/~\n(๑╹ڡ╹)╭ ♡\n(・。・)\n(・(仝)・)\n(・(ェ)・)\n¬з¬\n(=゚Д゚=)\n(=-ω-)zzZZ乙乙\n(--〆)\n( ̄Д ̄)ノ\n(-_-メ) \n(^^♪\n(^。^)y\n-.。o○\n(^ _ ^)/~~\n(-。-)y-゜゜゜\n(*゚Д゚)つミ匚___\n(*°∀°)=3\n(ー_ー)!!\n ^ω^\n( ^∀^)".split('\n');
var faceSelector = editor.find(">header>.chat-btn-emoji");
var filereader = new FileReader();
filereader.onload = function (fe) {
editor.find(".chat-editor-container").append("<img src='" + fe.target.result + "' />");
};
var loadImgIcons = function () {
var emojiHtml = [];
emojiIcons.forEach(function (code) {
emojiHtml.push("<li><img src='" + emojiRoot + "/" + code + ".png' data-emoji='" + code + "' /></li>");
});
editor.find(">header>.popup-smail").html(emojiHtml.join(""));
loadImgIcons = function () { };
};
var initEditor = function () {
if (!sessMgr.current)
return;
var color = sessMgr.current.options.chatColor || "#000000";
editor.find(">header .chat-editor-color").val(color);
editor.find(".chat-editor-container").css("color", color);
};
faceSelector.click(function () {
editor.find(">header>.popup-smail").toggleClass("popup-smail-on");
loadImgIcons();
});
$(document).on("click", ".popup-smail>li", function () {
var img = this.childNodes[0];
pasteHtml("&nbsp;<img data-emoji='" + img.dataset.emoji + "' src='" + img.src + "' />&nbsp;");
editor.find(">header>.popup-smail-on").removeClass("popup-smail-on");
});
//specChars.forEach(function (f) {
// var x = new Option(f, f);
// faceDom.options[faceDom.options.length] = x;
//});
//faceSelector.change(function () {
// var v = faceSelector.val();
// if (v) {
// pasteHtml(v);
// }
// faceSelector[0].selectedIndex = 0;
//});
$(".chat-items").on("click", ".chat-item > section > img", function () {
$(this).colorbox({ html: this.outerHTML });
});
var delayEnableSend = function () {
sendBtn.prop("disabled", true);
setTimeout(function () {
sendBtn.prop("disabled", false);
}, param.chatSendMsgDelay);
};
var pasteHtml = function (html) {
editorArea.append(html);
var range = document.createRange();
range.selectNodeContents(editorArea[0]);
range.collapse(false);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
editorArea[0].focus();
};
initEditor();
editor.find(".chat-editor-container").keyup(function (e) {
if (e.keyCode === 13 && sendBtn.is(":enabled")) {
sendBtn.click();
}
})[0].addEventListener("paste", function (e) {
if (e.clipboardData) {
var items = e.clipboardData.items;
if (items) {
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") === 0) {
var blob = items[i].getAsFile();
filereader.readAsDataURL(blob);
}
}
}
}
});
sessMgr.on("sessionChanged", function () {
initEditor();
});
editor.find(">header .chat-btn-cls").click(function () {
session.clearDisplay();
});
editor.find(">header .chat-editor-color").change(function () {
user.options.chatColor = this.value;
editor.find(".chat-editor-container").css("color", this.value);
sessMgr.save();
});
editor.find("#chat_file").change(function () {
var file = this;
if (file.files.length > 0) {
session.sendPic(this.files[0]);
}
file.value = "";
});
editor.find(">footer>button.button-default").click(function () {
session.exitRoom();
});
editor.find(">footer>button.button-primary").click(function () {
var editorObj = editor.find(".chat-editor-container");
var target = [];
var addedUser = [];
editorObj.find("span.chat-editor-at").each(function () {
var username = this.dataset.un;
if (addedUser[username])
return;
addedUser[username] = true;
target.push({
realname: $.trim($(this).text()).substr(1),
username: username
});
}).remove();
//msg
editorObj.find("img[data-emoji]").each(function () {
$(this).replaceWith(":" + this.dataset.emoji + ":");
});
//emoji
var msg = {
color: user.options.chatColor,
text: $.trim(editorObj.text()).replace(/\u00a0/g, ""),
target: target
}
var media = editorObj.find("img").toBase64Data();
if (!msg.text && !media.length)
return;
msg.text = msg.text || "[贴图]";
editor.find(".chat-editor-container").empty();
session.sendMsg(msg, media);
delayEnableSend();
});
$(document).on("click", "a.chat-item-at", function () {
var un = this.dataset.un;
var name = this.innerHTML;
if (!un)
return;
var html = "<span class='chat-editor-at' contenteditable='false' data-un='" + un + "'>@" + name + "</span>&nbsp;";
pasteHtml(html);
});
$(document).on("click", "a.chat-reportabuse", function () {
var a = $(this);
var item = a.closest(".chat-item");
var chatid = parseInt(item[0].dataset.chatid);
var authorlink = item.find(".chat-item-at:eq(0)")[0];
var username = authorlink.dataset.un;
if (username === '*' || username === "imfish" || username === "iccfish") {
mp.showMessagePopup("error", "亲,不可以举报我们伟大的管理员哦 ♪(´ε`)");
return;
}
if (!confirm("确定要举报 " + (authorlink.innerText) + " 吗?"))
return;
var data = {
systemMessage: false,
userMsgType: cmds.USER_REPORTABUSE,
content: chatid + "",
time: new Date()
};
port.postMessage("chatRoomSendMsg", coder.encode(data));
});
$(document).on("click", "a.chat-frame-reconnect", function () {
$(".chat-item").remove();
session.reconnect();
});
})();
return {
session: session,
enterRoom: session.enterRoom
}
});