Chat.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. MWF.xApplication.Execution.Chat = new Class({
  2. Extends: MWF.widget.Common,
  3. Implements: [Options, Events],
  4. options: {
  5. "style" : "default",
  6. "documentId" : ""
  7. },
  8. initialize: function (dialogContainer, editorContainer, app, actions, lp, options) {
  9. this.setOptions(options);
  10. this.dialogContainer = $(dialogContainer);
  11. this.editorContainer = $(editorContainer);
  12. this.app = app;
  13. this.actions = actions;
  14. this.lp = lp;
  15. this.userName = layout.desktop.session.user.name;
  16. this.path = "/x_component_Execution/$Chat/"+this.options.style+"/"
  17. this.actionSettingPath = MWF.defaultPath+"/widget/$SimpleEditor/"+this.options.style+"/ActionSetting.js";
  18. this.cssPath = this.path + "css.wcss"
  19. this._loadCss();
  20. },
  21. load: function () {
  22. this._loadEmotionSetting();
  23. if( this.dialogContainer ){
  24. this.dialogNode = new Element( "div.dialogNode", {
  25. "styles" : this.css.dialogNode
  26. }).inject(this.dialogContainer)
  27. //this.dialogContainer.setStyle("height","400px");
  28. var _self = this;
  29. MWF.require("MWF.widget.ScrollBar", function () {
  30. this.scrollObj = new MWF.widget.ScrollBar(this.dialogContainer, {
  31. "indent": false,
  32. "style": "default",
  33. "where": "before",
  34. "distance": 60,
  35. "friction": 4,
  36. "axis": {"x": false, "y": true},
  37. "onScroll": function (y) {
  38. //var scrollSize = _self.dialogContainer.getScrollSize();
  39. //var clientSize = _self.dialogContainer.getSize();
  40. //var scrollHeight = scrollSize.y - clientSize.y;
  41. //
  42. //if (y + 200 > scrollHeight && _self.loadDialog) {
  43. // if (! _self.isItemsLoaded) _self.loadDialog();
  44. //}
  45. if( y == 0 ){
  46. if (! _self.isItemsLoaded) _self.loadDialog();
  47. }
  48. }
  49. });
  50. //this.scrollObj.scrollVNode.setStyles({"margin-top":"300px"})
  51. }.bind(this), false);
  52. this.items = [];
  53. this.isItemsLoaded = false;
  54. this.isItemLoadding = false;
  55. this.loadDialog( function(){
  56. this.scrollToLater();
  57. }.bind(this) );
  58. }
  59. if(this.editorContainer){
  60. this.loadEditor( this.editorContainer, "" );
  61. }
  62. },
  63. scrollToLater : function(){
  64. setTimeout( function(){
  65. var clientSize = this.scrollObj.node.getSize();
  66. if( !this.scrollObj.scrollVNode )this.scrollObj.checkScroll();
  67. if( this.scrollObj.scrollVNode ){
  68. var scrollVNodeSize = this.scrollObj.scrollVNode.getSize();
  69. var maxY = (clientSize.y.toFloat())-(scrollVNodeSize.y.toFloat());
  70. this.scrollObj.scroll( maxY, null );
  71. }
  72. }.bind(this), 500 )
  73. },
  74. _loadEmotionSetting : function(){
  75. if( this.emotionSetting )return;
  76. var r = new Request({
  77. url: this.actionSettingPath,
  78. async: false,
  79. method: "get",
  80. onSuccess: function(responseText, responseXML){
  81. this.emotionSetting = MWF.widget.SimpleEditor.Actions.setting.emotion;
  82. }.bind(this),
  83. onFailure: function(xhr){
  84. alert(xhr.responseText);
  85. }
  86. });
  87. r.send();
  88. },
  89. loadDialog: function( callback ){
  90. if (!this.isItemsLoaded) {
  91. if (!this.isItemLoadding) {
  92. this.isItemLoadding = true;
  93. this.getCurrentPageData(function (json) { //alert(JSON.stringify(json))
  94. var length = json.count; //|| json.data.length;
  95. if (length <= this.items.length) {
  96. this.isItemsLoaded = true;
  97. }
  98. json.data.each(function (d) { //alert(JSON.stringify(d))
  99. this.loadDialogItem( d );
  100. }.bind(this))
  101. this.isItemLoadding = false;
  102. if( callback )callback();
  103. }.bind(this), 10 )
  104. }
  105. }
  106. //this.dialogContainer.scrollTo(0, 400 );
  107. //alert(this.dialogContainer.getScrollSize().y)
  108. },
  109. loadDialogItem: function( d , position){
  110. this.items.push(d.id)
  111. var isCurrentUser = ( d.senderName == this.userName );
  112. //var isCurrentUser = false
  113. var msg_li = new Element("div.msg_li", {"styles": this.css.msg_li}).inject(this.dialogNode, position || "top")
  114. var msg_item = new Element("div", {"styles": this.css.msg_item}).inject(msg_li)
  115. var msg_person = new Element("div", {
  116. "styles": this.css[isCurrentUser ? "msg_person_right" : "msg_person_left"]
  117. }).inject(msg_item)
  118. var msg_face = new Element("img", {
  119. "styles": this.css.msg_face
  120. }).inject(msg_person)
  121. this.setUserFace(d.senderName, msg_face);
  122. if (!isCurrentUser) {
  123. var msg_name = new Element("div", {
  124. "styles": this.css.msg_person_name,
  125. "text": d.senderName
  126. }).inject(msg_person)
  127. }
  128. var msg_arrow_left = new Element("div", {
  129. "styles": this.css[isCurrentUser ? "msg_arrow_right" : "msg_arrow_left"]
  130. }).inject(msg_item);
  131. var msg_content_body = new Element("div", {
  132. "styles": this.css[isCurrentUser ? "msg_content_body_right" : "msg_content_body_left"]
  133. }).inject(msg_item);
  134. //if (isCurrentUser) {
  135. // var msg_del = new Element("span", {
  136. // "styles": this.css.msg_del,
  137. // "title": "点击删除"
  138. // }).inject(msg_content_body);
  139. // msg_del.addEvent("click", function () {
  140. // if (confirm("删除后无法恢复,确定要删除该信息?")) {
  141. // this.deleteSingleMessage(docid, seq, jQuery(this).parents(".msg_li"));
  142. // }
  143. // }.bind(this))
  144. //}
  145. var msg_content_area = new Element("div", {
  146. "styles": this.css.msg_content_area
  147. }).inject(msg_content_body);
  148. var msg_content_text = new Element("p", {
  149. "styles": this.css.msg_content_text,
  150. "html": this.parseEmotion( d.content )
  151. }).inject(msg_content_area);
  152. var msg_content_time = new Element("p", {
  153. "styles": this.css.msg_content_time,
  154. "text": d.createTime
  155. }).inject(msg_content_area);
  156. },
  157. parseEmotion : function( content ){
  158. return content.replace(/\[emotion=(.*?)\]/g, function( a,b ){
  159. return "<img imagename='"+b+"' style='cursor:pointer;border:0;padding:2px;' " +" class='MWF_editor_emotion' src='"+ this.emotionSetting.imagesPath + b + this.emotionSetting.fileExt +"'>";
  160. }.bind(this));
  161. },
  162. //listMessageData: function( callback ){
  163. // var json = {
  164. // "type": "success",
  165. // "data": [
  166. // {
  167. // "id": "53a508ec-7862-4036-a273-c15830cd3f86",
  168. // "createTime": "2016-04-19 15:38:50",
  169. // "updateTime": "2016-04-19 15:38:50",
  170. // "sequence": "2016041915385053a508ec-7862-4036-a273-c15830cd3f46",
  171. // "content": "飞哥,找时间和孟总对一下设计,看看情况。飞哥,找时间和孟总对一下设计,看看情况飞哥,找时间和孟总对一下设计,看看情况飞哥,找时间和孟总对一下设计,看看情况",
  172. // "person": "李义"
  173. // },
  174. // {
  175. // "id": "53a508ec-7862-4036-a273-c15830cd3f87",
  176. // "createTime": "2016-04-19 15:38:50",
  177. // "updateTime": "2016-04-19 15:38:50",
  178. // "sequence": "2016041915385053a508ec-7862-4036-a273-c15830cd3f46",
  179. // "content": "下周我们就开始写代码.下周我们就开始写代码.下周我们就开始写代码.下周我们就开始写代码.下周我们就开始写代码下周我们就开始写代码.",
  180. // "person": "金飞"
  181. // }
  182. // ],
  183. // "date": "2016-05-27 14:20:07",
  184. // "spent": 2,
  185. // "size": 2,
  186. // "count": 0,
  187. // "position": 0,
  188. // "message": ""
  189. // }
  190. //
  191. //},
  192. getCurrentPageData:function(callback,count){
  193. if (!count)count = 5;
  194. var id = (this.items && this.items.length) ? this.items[this.items.length - 1] : "(0)";
  195. var filter = {"workId":this.options.workId} || {};
  196. this.actions.getChatListNext(id, count, filter, function (json) { //alert("action="+JSON.stringify(json))
  197. if (callback) callback(json);
  198. }.bind(this),null,false)
  199. },
  200. setUserFace: function(userName, faceNode ){
  201. this.getUserData( userName, function( userData ){
  202. var icon;
  203. if( userData.icon ){
  204. icon = "data:image/png;base64,"+userData.icon;
  205. }else{
  206. icon = this.path+ ( userData.genderType=="f" ? "female.png" : "man.png");
  207. }
  208. faceNode.set("src", icon );
  209. })
  210. },
  211. getUserData : function( userName, callback ){
  212. this.userData = this.userData || {};
  213. if( this.userData[userName] ){
  214. if(callback)callback(this.userData[userName])
  215. }else{
  216. this.actions.getPerson(function(json){
  217. this.userData[userName] = json.data;
  218. if(callback)callback(json.data)
  219. }.bind(this),null,userName,false)
  220. }
  221. },
  222. sendMessage : function(content, callback){
  223. var d = {
  224. "workId" : this.options.workId,
  225. "createTime": new Date().format("db"),
  226. "content": content,
  227. "targetIdentity": this.app.identity,
  228. "senderName" : this.userName
  229. }
  230. this.actions.submitChat(d, function(json){
  231. }.bind(this),
  232. function(xhr,text,error){
  233. var errorText = error;
  234. if (xhr) errorMessage = xhr.responseText;
  235. var e = JSON.parse(errorMessage);
  236. if(e.message){
  237. this.app.notice( e.message,"error");
  238. }else{
  239. this.app.notice( errorText,"error");
  240. }
  241. }.bind(this),false);
  242. this.loadDialogItem(d, "bottom");
  243. if(callback)callback();
  244. },
  245. loadEditor: function ( container, data ) {
  246. MWF.require("MWF.widget.SimpleEditor", function () {
  247. this.editor = new MWF.widget.SimpleEditor({
  248. "style": "chatReceive", //使用的样式文件夹
  249. "hasHeadNode" : false,
  250. "hasTitleNode": false, //是否有标题区
  251. "editorDisabled": false, //编辑区是否能进行编辑
  252. "hasToolbar": true, //是否生成操作条
  253. "toolbarDisable": false, //操作条是否失效
  254. "hasSubmit": true, //是否形成提交按钮
  255. "submitDisable": false, //提交按钮是否失效
  256. "hasCustomArea": true, //是否有提示区
  257. "paragraphise": false, //回车是否形成段落
  258. "minHeight": 100, //最小高度
  259. "maxHeight": 100, //编辑区的最大高度
  260. "overFlow": "visible", //可选项为 visible, auto 和 max ,visible 高度随内容变化, auto 内容高度超过minHeight时滚动条,max 内容高度超过maxHeight时滚动条(ie6 和 文档模式为杂项时,失效)
  261. "width": "100%", //编辑器的宽度
  262. "action": "Emotion", //操作条上面有哪些操作,如果是all,表示使用 toolbarItems.json 里配置的所有操作,否则传入操作的 action ,用 空格隔开,比如 "Image | Emotion"
  263. "limit": 255, //输入长度限制,0表示无限制
  264. "onQueryLoad": function () {
  265. return true;
  266. },
  267. "onPostLoad": function ( editor ) {
  268. editor.setCustomInfo("");
  269. },
  270. "onSubmitForm": function ( editor ) {
  271. var content = editor.getContent(true);
  272. if( content.trim() != "<br>" && content.trim()!=""){
  273. this.sendMessage( content, function(){
  274. editor.setContent("");
  275. this.scrollToLater();
  276. }.bind(this));
  277. }else{
  278. this.app.notice("不能发送空消息","error");
  279. }
  280. }.bind(this)
  281. }, container, data||"", null, null);
  282. this.editor.load();
  283. }.bind(this));
  284. }
  285. });