Tieba Chat

Tieba Chat | 这是一个实现在网页端使用贴吧客户端聊天功能的脚本。通过该脚本,您可以与使用贴吧客户端的好友聊天

目前為 2014-07-08 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Tieba Chat
  3. // @version 1.3
  4. // @description Tieba Chat | 这是一个实现在网页端使用贴吧客户端聊天功能的脚本。通过该脚本,您可以与使用贴吧客户端的好友聊天
  5. // @match http://tieba.baidu.com/*
  6. // @include http://tieba.baidu.com/*
  7. // @author 864907600cc
  8. // @icon http://1.gravatar.com/avatar/147834caf9ccb0a66b2505c753747867
  9. // @run-at document-end
  10. // @grant none
  11. // @noframes
  12. // @namespace http://ext.ccloli.com
  13. // ==/UserScript==
  14.  
  15. // 本脚本基于 GPLv3 协议开源 http://www.gnu.org/licenses/gpl.html‎
  16. // (c) 86497600cc. Some Rights Reserved.
  17.  
  18.  
  19. var hex_md5 = (function(g,k){function l(a){return n(m(o(a)))};function m(a){return h(j(p(a),a.length*8))};function n(e){try{}catch(a){g=0};var b=g?'0123456789ABCDEF':'0123456789abcdef';var c='';var d;for(var a=0;a<e.length;a++)d=e.charCodeAt(a),c+=b.charAt(d>>>4&15)+b.charAt(d&15);return c};function o(d){var b='';var c=-1;var a,e;while(++c<d.length)a=d.charCodeAt(c),e=c+1<d.length?d.charCodeAt(c+1):0,55296<=a&&a<=56319&&56320<=e&&e<=57343&&(a=65536+((a&1023)<<10)+(e&1023),c++),a<=127?b+=String.fromCharCode(a):a<=2047?b+=String.fromCharCode(192|a>>>6&31,128|a&63):a<=65535?b+=String.fromCharCode(224|a>>>12&15,128|a>>>6&63,128|a&63):a<=2097151&&(b+=String.fromCharCode(240|a>>>18&7,128|a>>>12&63,128|a>>>6&63,128|a&63));return b};function p(c){var b=Array(c.length>>2);for(var a=0;a<b.length;a++)b[a]=0;for(var a=0;a<c.length*8;a+=8)b[a>>5]|=(c.charCodeAt(a/8)&255)<<a%32;return b};function h(c){var b='';for(var a=0;a<c.length*32;a+=8)b+=String.fromCharCode(c[a>>5]>>>a%32&255);return b};function j(j,l){j[l>>5]|=128<<l%32,j[(l+64>>>9<<4)+14]=l;var g=1732584193;var h=-271733879;var i=-1732584194;var f=271733878;for(var k=0;k<j.length;k+=16){var n=g;var o=h;var p=i;var m=f;g=a(g,h,i,f,j[k+0],7,-680876936),f=a(f,g,h,i,j[k+1],12,-389564586),i=a(i,f,g,h,j[k+2],17,606105819),h=a(h,i,f,g,j[k+3],22,-1044525330),g=a(g,h,i,f,j[k+4],7,-176418897),f=a(f,g,h,i,j[k+5],12,1200080426),i=a(i,f,g,h,j[k+6],17,-1473231341),h=a(h,i,f,g,j[k+7],22,-45705983),g=a(g,h,i,f,j[k+8],7,1770035416),f=a(f,g,h,i,j[k+9],12,-1958414417),i=a(i,f,g,h,j[k+10],17,-42063),h=a(h,i,f,g,j[k+11],22,-1990404162),g=a(g,h,i,f,j[k+12],7,1804603682),f=a(f,g,h,i,j[k+13],12,-40341101),i=a(i,f,g,h,j[k+14],17,-1502002290),h=a(h,i,f,g,j[k+15],22,1236535329),g=b(g,h,i,f,j[k+1],5,-165796510),f=b(f,g,h,i,j[k+6],9,-1069501632),i=b(i,f,g,h,j[k+11],14,643717713),h=b(h,i,f,g,j[k+0],20,-373897302),g=b(g,h,i,f,j[k+5],5,-701558691),f=b(f,g,h,i,j[k+10],9,38016083),i=b(i,f,g,h,j[k+15],14,-660478335),h=b(h,i,f,g,j[k+4],20,-405537848),g=b(g,h,i,f,j[k+9],5,568446438),f=b(f,g,h,i,j[k+14],9,-1019803690),i=b(i,f,g,h,j[k+3],14,-187363961),h=b(h,i,f,g,j[k+8],20,1163531501),g=b(g,h,i,f,j[k+13],5,-1444681467),f=b(f,g,h,i,j[k+2],9,-51403784),i=b(i,f,g,h,j[k+7],14,1735328473),h=b(h,i,f,g,j[k+12],20,-1926607734),g=c(g,h,i,f,j[k+5],4,-378558),f=c(f,g,h,i,j[k+8],11,-2022574463),i=c(i,f,g,h,j[k+11],16,1839030562),h=c(h,i,f,g,j[k+14],23,-35309556),g=c(g,h,i,f,j[k+1],4,-1530992060),f=c(f,g,h,i,j[k+4],11,1272893353),i=c(i,f,g,h,j[k+7],16,-155497632),h=c(h,i,f,g,j[k+10],23,-1094730640),g=c(g,h,i,f,j[k+13],4,681279174),f=c(f,g,h,i,j[k+0],11,-358537222),i=c(i,f,g,h,j[k+3],16,-722521979),h=c(h,i,f,g,j[k+6],23,76029189),g=c(g,h,i,f,j[k+9],4,-640364487),f=c(f,g,h,i,j[k+12],11,-421815835),i=c(i,f,g,h,j[k+15],16,530742520),h=c(h,i,f,g,j[k+2],23,-995338651),g=d(g,h,i,f,j[k+0],6,-198630844),f=d(f,g,h,i,j[k+7],10,1126891415),i=d(i,f,g,h,j[k+14],15,-1416354905),h=d(h,i,f,g,j[k+5],21,-57434055),g=d(g,h,i,f,j[k+12],6,1700485571),f=d(f,g,h,i,j[k+3],10,-1894986606),i=d(i,f,g,h,j[k+10],15,-1051523),h=d(h,i,f,g,j[k+1],21,-2054922799),g=d(g,h,i,f,j[k+8],6,1873313359),f=d(f,g,h,i,j[k+15],10,-30611744),i=d(i,f,g,h,j[k+6],15,-1560198380),h=d(h,i,f,g,j[k+13],21,1309151649),g=d(g,h,i,f,j[k+4],6,-145523070),f=d(f,g,h,i,j[k+11],10,-1120210379),i=d(i,f,g,h,j[k+2],15,718787259),h=d(h,i,f,g,j[k+9],21,-343485551),g=e(g,n),h=e(h,o),i=e(i,p),f=e(f,m)};return Array(g,h,i,f)};function f(a,b,c,d,f,g){return e(i(e(e(b,a),e(d,g)),f),c)};function a(b,a,c,d,e,g,h){return f(a&c|~a&d,b,a,e,g,h)};function b(c,a,d,b,e,g,h){return f(a&b|d&~b,c,a,e,g,h)};function c(b,a,c,d,e,g,h){return f(a^c^d,b,a,e,g,h)};function d(b,a,c,d,e,g,h){return f(c^(a|~d),b,a,e,g,h)};function e(b,c){var a=(b&65535)+(c&65535);var d=(b>>16)+(c>>16)+(a>>16);return d<<16|a&65535};function i(a,b){return a<<b|a>>>32-b};return g=0,k='',l}());
  20.  
  21. var user_id=window.PageData.user.id||window.PageData.user.user_id;//,
  22. //chatting_list_data='';
  23.  
  24. var _client_id='wappc_1398857293796_956',
  25. _client_type='2',
  26. _client_version='4.2.7',
  27. _phone_imei='092887406663530',
  28. net_type='3',
  29. sign_key='tiebaclient!!!';
  30.  
  31. /*if(document.cookie.match(/BDUSS=(.{192,}?);?/))var BDUSS=document.cookie.match(/BDUSS=(.{192,}?);?/)[1];
  32. else if(GM_getValue('BDUSS',0)!=0)var BDUSS=GM_getValue('BDUSS');
  33. else{
  34. var BDUSS=prompt('无法获取 BDUSS,请尝试在移动版贴吧注销并登录。\n\n1. 将浏览器 UA 设置为移动设备的 UA(例如 Chrome 可在开发者工具中点击右上角的“Show drawer.”,并在下方的 Emulation 里设置 UserAgent;Firefox 可安装 User Agent Overrider 等扩展);\n2. 访问 http://tieba.baidu.com/mo 进行登录操作;\n3. 登录后禁用 UA 设置,回到贴吧页检查是否可用。\n\n如果希望手动配置 BDUSS,请将 BDUSS 贴在下方并按确定键。');
  35. if(BDUSS!=null&&BDUSS!=''&&BDUSS.match(/.{192,}?/)){
  36. //document.cookie='BDUSS='+BDUSS.match(/.{192,}?/)+'; expires='+(new Date(new Date().getTime()+60*60*24*365*10*1000)).toGMTString()+'; path=/';
  37. GM_setValue('BDUSS',BDUSS);
  38. var BDUSS=BDUSS;
  39. window.location.href=window.location.href;
  40. }
  41. throw 'Tieba Chat can\'t get BDUSS!!!';
  42. }*/
  43.  
  44. var tb_chat_data=JSON.parse(window.localStorage.getItem('tb_chat_data')/*||window.localStorage.getItem('tb_chat_data')*/)||{};
  45. var message_update_timestamp=window.localStorage.getItem('tb_chat_message_update_timestamp')||new Date().getTime();
  46. var message_update_count=window.localStorage.getItem('tb_chat_message_update_count')||0;
  47. var user_portrait='';
  48. var com_portrait='';
  49. var chatting_list_page=1;
  50. var this_last_msg=0;
  51. var this_early_msg=0;
  52. var this_username=null;
  53. var this_userid=0;
  54. var this_msg_update=null;
  55.  
  56. if(tb_chat_data.first_install==null){
  57. window.$.dialog.alert('<div style="font-size:14px"><p>欢迎使用 Tieba Chat ~~~ ヽ(//∇//)ノ♡</p><p>这是一个实现在网页端使用贴吧客户端的聊天功能的脚本。通过该脚本,您可以方便地与使用贴吧客户端的好友聊天。</p><p>使用说明:<br>1. 将鼠标划至网页右下角的“贴吧聊天”即可打开聊天界面;<br>2. 点击聊天列表中的用户或贴子楼层右下角“聊天”可以发起聊天,点击“点击加载下/上一页”可以进行翻页操作;<br>3. 在聊天界面下方文本框中输入聊天文字,点击右侧“发送”即可发送消息;<br>4. 在聊天界面点击信息列表最上方的“点击查看更多”即可查看之前的消息(如果存在的话);<br>5. 鼠标移出聊天界面后 0.5 秒可收起聊天界面。</p><p style="color:red">警告:<br>* 该脚本目前仍处于测试阶段,可能存在一些未知错误,请谨慎使用<br><del>* 该脚本需要获取 BDUSS,但并不会将其共享,如果您不信任,请卸载此脚本</del> 已确认不需要 BDUSS<br>* 该脚本目前只能发送和接收文字信息,对于图片、表情、语音等多媒体信息暂不支持(主要是 mini 客户端 api 没有提供)<br>* 本脚本目前只是为实现该功能而编写,暂未考虑效率问题,这可能导致浏览器运行缓慢<br>* 本脚本无缓存功能,所有操作均需要重新访问 api,这可能带来较多的带宽消耗<br>* 此脚本的设计可能比较简陋,暂时还没有设置界面……毕竟只是为了测试而已 OTL</p><p>如有疑问请在 firefox 吧相关贴子讨论……</p></div>',{title:"Tieba Chat 欢迎界面",width:800})
  58. tb_chat_data.first_install=1;
  59. window.localStorage.setItem('tb_chat_data',JSON.stringify(tb_chat_data));
  60. }
  61.  
  62. function get_string(c){
  63. //str='BDUSS='+BDUSS+'&_client_id=wappc_1398857293796_956&_client_type=2&_client_version=4.2.7&_phone_imei=092887406663530&from=tieba&net_type=3';
  64. var str='';
  65. var str2='';
  66. for(var i in c){
  67. str+=i+'='+c[i];
  68. str2+=i+'='+encodeURIComponent(c[i])+'&';
  69. }
  70. var sign=hex_md5(str+sign_key);
  71. str2+='sign='+sign;
  72. return str2;
  73. }
  74.  
  75. function get_message_update(){
  76. var xhr = new XMLHttpRequest();
  77. xhr.onreadystatechange=function(){
  78. if(xhr.readyState==4&&xhr.status==200){
  79. var t=JSON.parse(xhr.responseText);
  80. if(t.error_code=='0'){
  81. if(t.error&&t.error.errno!='0'){
  82. //get_error_command(t.error.errno,t.error.usermsg)
  83. //console.error('Tieba Chat Error '+t.error_code+': '+t.error_msg);
  84. var s=show_error(t.error.errno,t.error.errmsg);
  85. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  86. s.onclick=function(){get_message_update();s.parentElement.removeChild(s);clearTimeout(t);};
  87. throw 'Tieba Chat Error '+t.error.errno+': '+t.error.errmsg;
  88. }
  89. /*if(t.message.pletter!='0'){
  90. panel_top.style.color='orange';
  91. //get_chatting_list();
  92. }*/
  93. message_update_timestamp=new Date().getTime();
  94. message_update_count=t.message.pletter;
  95. //if(message_update_count!=window.localStorage.getItem('tb_chat_message_update_count')){
  96. if(message_update_count!='0'){
  97. document.title='【'+message_update_count+' 条新聊天】'+original_title;
  98. panel_top.style.color='orange';
  99. }
  100. else{
  101. document.title=original_title;
  102. panel_top.style.color='#000';
  103. }
  104. //}
  105. window.localStorage.setItem('tb_chat_message_update_timestamp',message_update_timestamp);
  106. window.localStorage.setItem('tb_chat_message_update_count',t.message.pletter);
  107. }
  108. else{
  109. var s=show_error(t.error_code,t.error_msg);
  110. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  111. s.onclick=function(){get_message_update();s.parentElement.removeChild(s);clearTimeout(t);};
  112. throw 'Tieba Chat Error '+t.error_code+': '+t.error_msg;
  113. }
  114. }
  115. }
  116. xhr.open('POST','//tieba.baidu.com/c/s/msg?'+get_string());
  117. xhr.send();
  118. }
  119.  
  120. function get_chatting_list(pn){
  121. var xhr=new XMLHttpRequest();
  122. xhr.onreadystatechange=function(){
  123. if(xhr.readyState==4&&xhr.status==200){
  124. var t=JSON.parse(xhr.responseText);
  125. if(t.error_code=='0'){
  126. if(t.error&&t.error.errno!='0'){
  127. //get_error_command(t.error.errno,t.error.usermsg)
  128. //console.error('Tieba Chat Error '+t.error_code+': '+t.error_msg);
  129. var s=show_error(t.error.errno,t.error.errmsg);
  130. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  131. s.onclick=function(){get_chatting_list(pn);s.parentElement.removeChild(s);clearTimeout(t);};
  132. throw 'Tieba Chat Error '+t.error.errno+': '+t.error.errmsg;
  133. }
  134. panel_head.textContent='贴吧聊天';
  135. panel_main.innerHTML='';
  136. var panel_list=document.createElement('div');
  137. panel_list.className='tb_chat_panel_list';
  138. panel_main.appendChild(panel_list);
  139. chatting_list_page=pn;
  140. if(pn>1){
  141. var msg_more=document.createElement('div');
  142. msg_more.textContent='点击加载上一页';
  143. msg_more.style.cssText='width:200px;margin:20px auto;text-align:center;font-size:13px;background:#0CF;padding:5px;-webkit-user-select:none;-moz-user-select:none;cursor:pointer;color:#FFF';
  144. panel_list.appendChild(msg_more);
  145. msg_more.onclick=function(){get_chatting_list(pn-1);msg_more.textContent='正在载入......';};
  146. }
  147. //chatting_list_data='';
  148. for(var c in t.record){
  149. var p=document.createElement('div');
  150. p.className='tb_chat_row';
  151. p.setAttribute('user_id',t.record[c].user_id);
  152. p.setAttribute('user_name',t.record[c].user_name)
  153. p.innerHTML='<div class="tb_chat_pleft"><img class="tb_chat_avatar" src="http://tb.himg.baidu.com/sys/portrait/item/'+t.record[c].portrait+'" alt></div><div class="tb_chat_pright"><div class="tb_chat_username">'+t.record[c].user_name+'</div><div class="tb_chat_lasttext">'+(t.record[c].abstract.length>0?t.record[c].abstract[t.record[c].abstract.length-1].text:'')+'</div></div><div style="clear:both"></div>';
  154. if(t.record[c].unread_count!='0'){
  155. p.style.color='orange';
  156. p.onclick=function(){panel_top.style.color='#000';this_userid=this.getAttribute('user_id');this_username=this.getAttribute('user_name');get_latest_msg(this.getAttribute('user_id'));}
  157. }
  158. else p.onclick=function(){this_userid=this.getAttribute('user_id');this_username=this.getAttribute('user_name');get_latest_msg(this.getAttribute('user_id'));};
  159. panel_list.appendChild(p);
  160. //chatting_list_data+='<div class="tb_chat_row"'+(t.record[c].unread_count!='0'?' style="background:rgba(255,0,0,.1)"':'')+' user_id="'+t.record[c].user_id+'"><div class="tb_chat_pleft"><img class="tb_chat_avatat" src="http://tb.himg.baidu.com/sys/portrait/item/'+t.record[c].portrait+'" alt></div><div class="tb_chat_pright"><div class="tb_chat_username">'+t.record[c].user_name+'</div><div class="tb_chat_lasttext">'+(t.record[c].abstract.length>0?t.record[c].abstract[t.record[c].abstract.length-1].text:'')+'</div></div></div>';
  161. }
  162. if(t.has_more==1){
  163. var msg_more=document.createElement('div');
  164. msg_more.textContent='点击加载下一页';
  165. msg_more.style.cssText='width:200px;margin:20px auto;text-align:center;font-size:13px;background:#0CF;padding:5px;-webkit-user-select:none;-moz-user-select:none;cursor:pointer;color:#FFF';
  166. panel_list.appendChild(msg_more);
  167. msg_more.onclick=function(){get_chatting_list(pn+1);msg_more.textContent='正在载入......';};
  168. }
  169. //if(has_more=='1')chatting_list_data+='<div class="tb_chat_next">点击加载下一页</div>';
  170. //panel.innerHTML=chatting_list_data;
  171. /*var row_node=document.querySelectorAll('.tb_chat_row');
  172. for(var c in row_node){
  173. row_node[c].onclick=function(){get_latest_msg(row_node[c].getAttribute('user_id'));}
  174. }*/
  175. if(panel_top_back.hasAttribute('show'))panel_top_back.removeAttribute('show');
  176. if(panel_top_action.hasAttribute('show')){
  177. panel_top_action.removeAttribute('show');
  178. panel_top_action.textContent='+';
  179. panel_top_action.onclick=function(){
  180. var username=prompt('请输入用户名以发起聊天');
  181. if(username!=null&&username!='')get_userid(username);
  182. }
  183. }
  184. this_last_msg=0;
  185. this_early_msg=0;
  186. this_username=null;
  187. this_userid=0;
  188. }
  189. else{
  190. var s=show_error(t.error_code,t.error_msg);
  191. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  192. s.onclick=function(){get_chatting_list(pn);s.parentElement.removeChild(s);clearTimeout(t);};
  193.  
  194. throw 'Tieba Chat Error '+t.error_code+': '+t.error_msg;
  195. }
  196. }
  197. }
  198. xhr.open('POST','//tieba.baidu.com/c/s/comlist?'+get_string({
  199. //BDUSS:BDUSS,
  200. _client_id:_client_id,
  201. _client_type:_client_type,
  202. _client_version:_client_version,
  203. _phone_imei:_phone_imei,
  204. net_type:net_type,
  205. pn:pn
  206. }));
  207. xhr.send();
  208. }
  209.  
  210. function get_latest_msg(id){
  211. var xhr=new XMLHttpRequest();
  212. xhr.onreadystatechange=function(){
  213. if(xhr.readyState==4&&xhr.status==200){
  214. var t=JSON.parse(xhr.responseText);
  215. if(t.error_code=='0'){
  216. if(t.error&&t.error.errno!='0'){
  217. //get_error_command(t.error.errno,t.error.usermsg)
  218. //console.error('Tieba Chat Error '+t.error_code+': '+t.error_msg);
  219. var s=show_error(t.error.errno,t.error.errmsg);
  220. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  221. s.onclick=function(){get_latest_msg(id);s.parentElement.removeChild(s);clearTimeout(t);};
  222. throw 'Tieba Chat Error '+t.error.errno+': '+t.error.errmsg;
  223. }
  224. //panel_main.innerHTML=xhr.responseText;
  225. /*if(this_username==null)*/
  226. if(id!=this_userid||document.getElementsByClassName('tb_chat_panel_list')[0])panel_main.innerHTML='';
  227. panel_head.textContent=this_username;
  228. if(document.getElementsByClassName('tb_chat_panel_msg')[0])var panel_msg=document.getElementsByClassName('tb_chat_panel_msg')[0];
  229. else{
  230. var panel_msg=document.createElement('div');
  231. panel_msg.className='tb_chat_panel_msg';
  232. panel_main.appendChild(panel_msg);
  233. }
  234. com_portrait=t.com_portrait;
  235. user_portrait=t.user_portrait;
  236. if(t.has_more==1){
  237. var msg_more=document.createElement('div');
  238. msg_more.textContent='点击加载更多';
  239. msg_more.style.cssText='width:200px;margin:20px auto;text-align:center;font-size:13px;background:#0CF;padding:5px;-webkit-user-select:none;-moz-user-select:none;cursor:pointer;color:#FFF';
  240. panel_msg.appendChild(msg_more);
  241. msg_more.onclick=function(){get_early_msg(id,panel_msg,msg_more);};
  242. }
  243. for(var c in t.message){
  244. var p=document.createElement('div');
  245. p.className='tb_chat_message';
  246. if(t.message[c].from=='0'){
  247. p.className+=' com';
  248. p.innerHTML='<div class="tb_chat_pleft"><img class="tb_chat_avatar" src="http://tb.himg.baidu.com/sys/portrait/item/'+com_portrait+'" alt></div><div class="tb_chat_pright"><div class="tb_chat_message_inner">'+(t.message[c].content[0].text||'未知数据')+'</div></div><div style="clear:both"></div>';
  249. }
  250. else{
  251. p.className+=' user';
  252. p.innerHTML='<div class="tb_chat_pleft"><img class="tb_chat_avatar" src="http://tb.himg.baidu.com/sys/portrait/item/'+user_portrait+'" alt></div><div class="tb_chat_pright"><div class="tb_chat_message_inner">'+(t.message[c].content[0].text||'未知数据')+'</div></div><div style="clear:both"></div>';
  253. }
  254. p.setAttribute('msg_id',t.message[c].msg_id);
  255. p.title='Post @ '+new Date(t.message[c].time*1000);
  256. //p.onclick=function(){get_latest_msg(this.getAttribute('user_id'));}
  257. panel_msg.appendChild(p);
  258. if(t.message[c].msg_id<this_early_msg||this_early_msg==0)this_early_msg=t.message[c].msg_id;
  259. if(t.message[c].msg_id>this_last_msg||this_last_msg==0)this_last_msg=t.message[c].msg_id;
  260. //chatting_list_data+='<div class="tb_chat_row"'+(t.record[c].unread_count!='0'?' style="background:rgba(255,0,0,.1)"':'')+' user_id="'+t.record[c].user_id+'"><div class="tb_chat_pleft"><img class="tb_chat_avatat" src="http://tb.himg.baidu.com/sys/portrait/item/'+t.record[c].portrait+'" alt></div><div class="tb_chat_pright"><div class="tb_chat_username">'+t.record[c].user_name+'</div><div class="tb_chat_lasttext">'+(t.record[c].abstract.length>0?t.record[c].abstract[t.record[c].abstract.length-1].text:'')+'</div></div></div>';
  261. }
  262. //document.querySelector('.tb_chat_panel_msg .tb_chat_message:nth-last-child(1)').scrollIntoView();
  263. panel_msg.scrollTop=panel_msg.scrollHeight;
  264. panel_top_back.setAttribute('show','1');
  265. panel_top_action.setAttribute('show','1');
  266. //tb_chat_data.com[t.record[c].user_id].last_msg=this_last_msg;
  267. //window.localStorage.setItem('tb_chat_data',JSON.stringify(tb_chat_data));
  268. if(!document.getElementsByClassName('tb_chat_msg_panel')[0]){
  269. var msg_panel=document.createElement('div');
  270. var msg_textarea=document.createElement('textarea');
  271. var msg_send=document.createElement('div');
  272. msg_panel.style.cssText='width:100%;height:50px;position:absolute;bottom:0;left:0';
  273. msg_panel.className='tb_chat_msg_panel';
  274. panel_main.appendChild(msg_panel);
  275. msg_textarea.style.cssText='width:320px;height:36px;font-size:12px;margin:7px;position:absolute;left:0;top:0;resize:none';
  276. msg_textarea.className='tb_chat_msg_textarea';
  277. msg_panel.appendChild(msg_textarea);
  278. msg_send.style.cssText='width:50px;height:25px;font-size:14px;line-height:25px;text-align:center;position:absolute;margin:15px 7px;right:0;top:0;background:#0CF;cursor:pointer;color:#FFF';
  279. msg_send.textContent='发送';
  280. msg_panel.appendChild(msg_send);
  281. msg_send.onclick=function(){add_message(id,this_last_msg,msg_textarea.value);};
  282. window.onfocus=function(){if(this_msg_update==null)this_msg_update=setInterval(function(){if(document.getElementsByClassName('tb_chat_msg_panel')[0]&&panel.hasAttribute('show'))get_latest_msg(id)},10000);};
  283. window.onblur=function(){if(this_msg_update!=null){clearInterval(this_msg_update);this_msg_update=null;}};
  284. panel_top_action.textContent='≡';
  285. panel_top_action.onclick=function(){
  286. switch(prompt('请键入以下数字并点击“确定”以完成对应操作:\n1. 清空当前用户全部聊天记录\n2. 从聊天列表内删除当前用户\n\n(比较简陋真是抱歉了 _(:з」∠)_ )')){
  287. case '1':
  288. delete_msg(id);
  289. break;
  290. case '2':
  291. delete_user(id);
  292. break;
  293. }
  294. }
  295. }
  296. get_message_update();
  297. }
  298. else{
  299. var s=show_error(t.error_code,t.error_msg);
  300. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  301. s.onclick=function(){get_latest_msg(id);s.parentElement.removeChild(s);clearTimeout(t);};
  302. throw 'Tieba Chat Error '+t.error_code+': '+t.error_msg;
  303. }
  304. }
  305. };
  306. xhr.open('POST','//tieba.baidu.com/c/s/recentmsg?'+get_string({
  307. //BDUSS:BDUSS,
  308. _client_id:_client_id,
  309. _client_type:_client_type,
  310. _client_version:_client_version,
  311. _phone_imei:_phone_imei,
  312. com_id:id,
  313. msg_id:this_last_msg,
  314. net_type:net_type,
  315. user_id:user_id
  316. }
  317. /*'msg_id=0&user_id='+user_id+'&com_id='+id*/));
  318. xhr.send();
  319. }
  320.  
  321. function get_early_msg(id,panel_msg,msg_more){
  322. msg_more.textContent='正在载入......';
  323. var scroll_top=panel_msg.scrollHeight-panel_msg.scrollTop;
  324. var xhr=new XMLHttpRequest();
  325. xhr.onreadystatechange=function(){
  326. if(xhr.readyState==4&&xhr.status==200){
  327. var t=JSON.parse(xhr.responseText);
  328. if(t.error_code=='0'){
  329. if(t.error&&t.error.errno!='0'){
  330. var s=show_error(t.error.errno,t.error.errmsg);
  331. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  332. s.onclick=function(){get_early_msg(id,panel_msg,msg_more);s.parentElement.removeChild(s);clearTimeout(t);};
  333. throw 'Tieba Chat Error '+t.error.errno+': '+t.error.errmsg;
  334. }
  335. var xxx=document.createElement('div');
  336. panel_msg.insertBefore(xxx,msg_more.nextElementSibling);
  337. for(var c in t.message){
  338. var p=document.createElement('div');
  339. p.className='tb_chat_message';
  340. if(t.message[c].from=='0'){
  341. p.className+=' com';
  342. p.innerHTML='<div class="tb_chat_pleft"><img class="tb_chat_avatar" src="http://tb.himg.baidu.com/sys/portrait/item/'+com_portrait+'" alt></div><div class="tb_chat_pright"><div class="tb_chat_message_inner">'+(t.message[c].content[0].text||'未知数据')+'</div></div><div style="clear:both"></div>';
  343. }
  344. else{
  345. p.className+=' user';
  346. p.innerHTML='<div class="tb_chat_pleft"><img class="tb_chat_avatar" src="http://tb.himg.baidu.com/sys/portrait/item/'+user_portrait+'" alt></div><div class="tb_chat_pright"><div class="tb_chat_message_inner">'+(t.message[c].content[0].text||'未知数据')+'</div></div><div style="clear:both"></div>';
  347. }
  348. p.setAttribute('msg_id',t.message[c].msg_id);
  349. p.title='Post @ '+new Date(t.message[c].time*1000);
  350. //p.onclick=function(){get_latest_msg(this.getAttribute('user_id'));}
  351. //panel_msg.appendChild(p);
  352. if(t.message[c].msg_id<this_early_msg||this_early_msg==0)this_early_msg=t.message[c].msg_id;
  353. if(t.message[c].msg_id>this_last_msg||this_last_msg==0)this_last_msg=t.message[c].msg_id;
  354. //panel_msg.insertBefore(p,msg_more.nextElement);
  355. xxx.appendChild(p);
  356. }
  357. if(t.has_more==1)msg_more.textContent='点击加载更多';
  358. else msg_more.parentElement.removeChild(msg_more);
  359. panel_msg.scrollTop=panel_msg.scrollHeight-scroll_top;
  360. }
  361. else{
  362. var s=show_error(t.error_code,t.error_msg);
  363. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  364. s.onclick=function(){get_early_msg(id,panel_msg,msg_more);s.parentElement.removeChild(s);clearTimeout(t);};
  365. throw 'Tieba Chat Error '+t.error_code+': '+t.error_msg;
  366. }
  367. }
  368. }
  369. xhr.open('POST','//tieba.baidu.com/c/s/historymsg?'+get_string({
  370. //BDUSS:BDUSS,
  371. _client_id:_client_id,
  372. _client_type:_client_type,
  373. _client_version:_client_version,
  374. _phone_imei:_phone_imei,
  375. com_id:id,
  376. msg_id:this_early_msg,
  377. net_type:net_type,
  378. user_id:user_id
  379. }
  380. /*'msg_id=0&user_id='+user_id+'&com_id='+id*/));
  381. xhr.send();
  382. }
  383.  
  384. function add_message(id,last_msg_id,content){
  385. var xhr=new XMLHttpRequest();
  386. xhr.onreadystatechange=function(){
  387. if(xhr.readyState==4&&xhr.status==200){
  388. var t=JSON.parse(xhr.responseText);
  389. if(t.error_code=='0'){
  390. if(t.error&&t.error.errno!='0'){
  391. //get_error_command(t.error.errno,t.error.usermsg)
  392. //console.error('Tieba Chat Error '+t.error_code+': '+t.error_msg);
  393. var s=show_error(t.error.errno,t.error.errmsg);
  394. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  395. s.onclick=function(){add_message(id,last_msg_id,content);s.parentElement.removeChild(s);clearTimeout(t);};
  396. throw 'Tieba Chat Error '+t.error.errno+': '+t.error.errmsg;
  397. }
  398. var this_last_msg;
  399. var panel_msg=document.getElementsByClassName('tb_chat_panel_msg')[0];
  400. //var panel_msg=document.createElement('div');
  401. //panel_msg.className='tb_chat_panel_msg';
  402. //panel_main.appendChild(panel_msg);
  403. for(var c in t.recent.message){
  404. var p=document.createElement('div');
  405. p.className='tb_chat_message';
  406. if(t.recent.message[c].from=='0'){
  407. p.className+=' com';
  408. p.innerHTML='<div class="tb_chat_pleft"><img class="tb_chat_avatar" src="http://tb.himg.baidu.com/sys/portrait/item/'+com_portrait+'" alt></div><div class="tb_chat_pright"><div class="tb_chat_message_inner">'+(t.recent.message[c].content[0].text||'未知数据')+'</div></div><div style="clear:both"></div>';
  409. }
  410. else{
  411. p.className+=' user';
  412. p.innerHTML='<div class="tb_chat_pleft"><img class="tb_chat_avatar" src="http://tb.himg.baidu.com/sys/portrait/item/'+user_portrait+'" alt></div><div class="tb_chat_pright"><div class="tb_chat_message_inner">'+(t.recent.message[c].content[0].text||'未知数据')+'</div></div><div style="clear:both"></div>';
  413. }
  414. p.setAttribute('msg_id',t.recent.message[c].msg_id);
  415. p.title='Post @ '+new Date(t.recent.message[c].time*1000);
  416. panel_msg.appendChild(p);
  417. //panel_top_back.setAttribute('show','1');
  418. if(t.recent.message[c].msg_id<this_early_msg||this_early_msg==0)this_early_msg=t.recent.message[c].msg_id;
  419. if(t.recent.message[c].msg_id>this_last_msg||this_last_msg==0)this_last_msg=t.recent.message[c].msg_id;
  420. }
  421. var p=document.createElement('div');
  422. p.className='tb_chat_message';
  423. p.className+=' user';
  424. p.innerHTML='<div class="tb_chat_pleft"><img class="tb_chat_avatar" src="http://tb.himg.baidu.com/sys/portrait/item/'+user_portrait+'" alt></div><div class="tb_chat_pright"><div class="tb_chat_message_inner">'+(t.message.content[0].text||'未知数据')+'</div></div><div style="clear:both"></div>';
  425. p.setAttribute('msg_id',t.message.msg_id);
  426. panel_msg.appendChild(p);
  427. if(t.message.msg_id<this_early_msg||this_early_msg==0)this_early_msg=t.message.msg_id;
  428. if(t.message.msg_id>this_last_msg||this_last_msg==0)this_last_msg=t.message.msg_id;
  429. //document.querySelector('.tb_chat_panel_msg .tb_chat_message:nth-last-child(1)').scrollIntoView();
  430. panel_msg.scrollTop=panel_msg.scrollHeight;
  431. document.getElementsByClassName('tb_chat_msg_textarea')[0].value='';
  432. }
  433. else{
  434. var s=show_error(t.error_code,t.error_msg);
  435. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  436. s.onclick=function(){add_message(id,last_msg_id,content);s.parentElement.removeChild(s);clearTimeout(t);};
  437. throw 'Tieba Chat Error '+t.error_code+': '+t.error_msg;
  438. }
  439. }
  440. }
  441. xhr.open('POST','//tieba.baidu.com/c/s/addmsg?'+get_string({
  442. //BDUSS:BDUSS,
  443. _client_id:_client_id,
  444. _client_type:_client_type,
  445. _client_version:_client_version,
  446. _phone_imei:_phone_imei,
  447. com_id:id,
  448. content:content,
  449. last_msg_id:last_msg_id,
  450. net_type:net_type,
  451. user_id:user_id
  452. }));
  453. xhr.send();
  454. }
  455.  
  456. function show_error(c,t){
  457. var panel_error=document.createElement('div');
  458. panel_error.className='tb_chat_error';
  459. panel.appendChild(panel_error);
  460. panel_error.innerHTML='Tieba Chat Error!!!<br>Error Code: '+c+'<br>Error Message:'+t+'<br>Click this panel to retry....';
  461. return panel_error;
  462. }
  463.  
  464. function add_enterance(){
  465. var s=document.getElementsByClassName('j_jb_ele');
  466. for(var i=0;i<s.length;i++){
  467. if(s[i].hasAttribute('tb_chat_added')==false){
  468. var k=document.createTextNode(' ');
  469. s[i].appendChild(k);
  470. var j=document.createElement('a');
  471. j.style.cssText='color:#999;cursor:pointer';
  472. j.textContent='聊天';
  473. s[i].appendChild(j);
  474. j.onclick=function(){
  475. var ud=JSON.parse(this.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.getAttribute('data-field')).author;
  476. this_userid=ud.user_id;
  477. this_username=ud.user_name;
  478. panel.setAttribute('show','1');
  479. get_latest_msg(ud.user_id);
  480. }
  481. var k=document.createTextNode(' |');
  482. s[i].appendChild(k);
  483. s[i].setAttribute('tb_chat_added','true');
  484. }
  485. }
  486. }
  487.  
  488. function get_userid(username){
  489. var xhr=new XMLHttpRequest();
  490. xhr.onreadystatechange=function(){
  491. if(xhr.readyState==4&&xhr.status==200){
  492. var t=JSON.parse(xhr.responseText);
  493. if(t.no==0){
  494. this_username=username;
  495. get_latest_msg(t.data.id);
  496. }
  497. else{
  498. var s=show_error(t.no,t.error);
  499. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  500. s.onclick=function(){get_userid(username);s.parentElement.removeChild(s);clearTimeout(t);};
  501. throw 'Tieba Chat Error '+t.no+': '+t.error;
  502. }
  503. }
  504. };
  505. xhr.open('POST','//tieba.baidu.com/home/get/panel?ie=utf-8&un='+encodeURIComponent(username));
  506. xhr.send();
  507. }
  508.  
  509. function delete_msg(id){
  510. var xhr=new XMLHttpRequest();
  511. xhr.onreadystatechange=function(){
  512. if(xhr.readyState==4&&xhr.status==200){
  513. var t=JSON.parse(xhr.responseText);
  514. if(t.error.errno=="0"&&t.error_code=="0"){
  515. alert('清除成功!');
  516. document.getElementsByClassName('tb_chat_panel_msg')[0].innerHTML='';
  517. }
  518. else{
  519. var s=show_error(t.error_code,t.error_msg);
  520. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  521. s.onclick=function(){delete_msg(id);s.parentElement.removeChild(s);clearTimeout(t);};
  522. throw 'Tieba Chat Error '+t.error_code+': '+t.error_msg;
  523. }
  524. }
  525. };
  526. xhr.open('POST','//tieba.baidu.com/c/s/clearmsg?'+get_string({
  527. _client_id:_client_id,
  528. _client_type:_client_type,
  529. _client_version:_client_version,
  530. _phone_imei:_phone_imei,
  531. com_id:id,
  532. net_type:net_type,
  533. user_id:user_id
  534. }));
  535. xhr.send();
  536. }
  537.  
  538. function delete_user(id){
  539. var xhr=new XMLHttpRequest();
  540. xhr.onreadystatechange=function(){
  541. if(xhr.readyState==4&&xhr.status==200){
  542. var t=JSON.parse(xhr.responseText);
  543. if(t.error.errno=="0"&&t.error_code=="0"){
  544. alert('删除成功!');
  545. get_chatting_list(chatting_list_page);
  546. if(this_msg_update!=null){
  547. clearInterval(this_msg_update);
  548. this_msg_update=null;
  549. }
  550. window.onfocus=null;
  551. window.onblur=null;
  552. }
  553. else{
  554. var s=show_error(t.error_code,t.error_msg);
  555. var t=setTimeout(function(){s.parentElement.removeChild(s);},5000);
  556. s.onclick=function(){delete_msg(id);s.parentElement.removeChild(s);clearTimeout(t);};
  557. throw 'Tieba Chat Error '+t.error_code+': '+t.error_msg;
  558. }
  559. }
  560. };
  561. xhr.open('POST','//tieba.baidu.com/c/s/delcom?'+get_string({
  562. _client_id:_client_id,
  563. _client_type:_client_type,
  564. _client_version:_client_version,
  565. _phone_imei:_phone_imei,
  566. com_id:id,
  567. net_type:net_type,
  568. tbs:PageData.tbs?PageData.tbs:get_tbs(),
  569. user_id:user_id
  570. }));
  571. xhr.send();
  572. }
  573.  
  574. function get_tbs(){
  575. var xhr=new XMLHttpRequest();
  576. xhr.onreadystatechange=function(){
  577. if(xhr.readyState==4&&xhr.status==200)return JSON.parse(xhr.responseText).tbs;
  578. }
  579. xhr.open('GET','http://tieba.baidu.com/dc/common/tbs');
  580. xhr.send();
  581. }
  582.  
  583. var message_update_timer=setInterval(function(){
  584. if((new Date().getTime()-(window.localStorage.getItem('tb_chat_message_update_timestamp')||message_update_timestamp))>10000){
  585. get_message_update();
  586. }
  587. else if(window.localStorage.getItem('tb_chat_message_update_count')!='0'){
  588. document.title='【'+window.localStorage.getItem('tb_chat_message_update_count')+' 条新聊天】'+original_title;
  589. panel_top.style.color='orange';
  590. }
  591. else{
  592. document.title=original_title;
  593. panel_top.style.color='#000';
  594. }
  595. /*if(message_update_count!=window.localStorage.getItem('tb_chat_message_update_count')&&){
  596. if(message_update_count!='0'){
  597. document.title='【'+message_update_count+' 条新聊天】'+original_title;
  598. panel_top.style.color='orange';
  599. }
  600. else{
  601. document.title=original_title;
  602. panel_top.style.color='#000';
  603. }
  604. }*/
  605. //if(PageData.product=='pb')add_enterance();
  606. },1000);
  607.  
  608. // ------------------------------------------------------------------------
  609.  
  610.  
  611. var panel=document.createElement('div');
  612. var panel_top=document.createElement('div');
  613. var panel_head=document.createElement('div');
  614. var panel_main=document.createElement('div');
  615. var panel_top_back=document.createElement('div');
  616. var panel_top_action=document.createElement('div');
  617. var panel_ifshow=null;
  618. var original_title=document.title;
  619. var ss=document.createElement('style');
  620. var stylesheet='.tb_chat_panel{width:400px;height:100%;position:fixed;top:calc(100% - 30px);right:0px;background:rgba(255,255,255,.75);z-index:200000;transition:all 0.5s ease-in;-webkit-user-select:none;-moz-user-select:none}.tb_chat_panel[show]{top:0px;transition:all 0.5s ease-out}.tb_chat_panel_top{font-size:14px;line-height:30px;text-align:center;width:100%;height:30px;-webkit-user-select:none;-moz-user-select:none}.tb_chat_panel_top_back{position:absolute;left:10px;top:0px;width:30px;height:30px;background:#0CF;visibility:hidden;color:#FFF;cursor:pointer;text-align:center}.tb_chat_panel_top_back[show]{visibility:visible}.tb_chat_panel_top_action{position:absolute;right:10px;top:0px;width:30px;height:30px;background:#0CF;visibility:hidden;color:#FFF;cursor:pointer;text-align:center}.tb_chat_panel_top_action[show],.tb_chat_panel[show] .tb_chat_panel_top_action{visibility:visible}.tb_chat_panel_main{height:calc(100% - 30px);overflow:auto}.tb_chat_row{/*width:400px;*/height:60px;padding:10px;cursor:pointer}.tb_chat_row:hover{background:rgba(0,0,0,.1)}.tb_chat_pleft{float:left}.tb_chat_row .tb_chat_avatar{width:60px;height:60px}.tb_chat_pright{float:left;max-width:300px}.tb_chat_row .tb_chat_username{font-size:14px;padding:6px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.tb_chat_row .tb_chat_lasttext{padding:6px;font-size:12px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.tb_chat_next{font-size:14px;text-align:center;width:100%;height:30px;line-height:30px}.tb_chat_message{font-size:12px;line-height:14px;min-height:28px;padding:5px}.tb_chat_message .tb_chat_avatar{width:28px;height:28px}.tb_chat_message.user .tb_chat_pleft,.tb_chat_message.user .tb_chat_pright{float:right;text-align:right}.tb_chat_message .tb_chat_message_inner{margin:0 10px;padding:6px;background:#FFF;border:1px solid #CCC;border-radius:3px;-moz-user-select:text;-webkit-user-select:text}.tb_chat_panel_msg{margin-bottom:50px;height:calc(100% - 50px);overflow:auto}.tb_chat_error{background:rgba(255,0,0,.25);font-size:12px;line-height:16px;position:fixed;width:350px;margin:0 25px;top:50px;right:0px;box-shadow:rgba(255,0,0,0.25) 0 0 5px;color:#F00}.tb_chat_message_inner::selection,.tb_chat_message_inner::-moz-selection{background:rgba(255,255,255,0.5)}';
  621. panel.className='tb_chat_panel';
  622. document.body.appendChild(panel);
  623. ss.textContent=stylesheet;
  624. panel.appendChild(ss);
  625. //panel_top.textContent='贴吧聊天';
  626. panel_top.className='tb_chat_panel_top';
  627. panel.appendChild(panel_top);
  628. panel_head.textContent='贴吧聊天';
  629. panel_top.appendChild(panel_head);
  630. panel_top_back.className='tb_chat_panel_top_back';
  631. panel_top_back.textContent='←';
  632. panel_top.appendChild(panel_top_back);
  633. panel_top_action.className='tb_chat_panel_top_action';
  634. panel_top_action.textContent='+';
  635. panel_top.appendChild(panel_top_action);
  636. panel_main.className='tb_chat_panel_main';
  637. panel.appendChild(panel_main);
  638.  
  639. panel_top_back.onclick=function(){
  640. get_chatting_list(chatting_list_page);
  641. if(this_msg_update!=null){
  642. clearInterval(this_msg_update);
  643. this_msg_update=null;
  644. }
  645. window.onfocus=null;
  646. window.onblur=null;
  647. };
  648. panel_top.onmouseover=function(){
  649. panel.setAttribute('show','1');
  650. if(this_userid==0)get_chatting_list(chatting_list_page);
  651. else get_latest_msg(this_userid);
  652. };
  653. panel.onmouseover=function(){if(panel_ifshow!=null)clearTimeout(panel_ifshow);};
  654. panel.onmouseout=function(){
  655. panel_ifshow=setTimeout(function(){
  656. if(panel.hasAttribute('show'))panel.removeAttribute('show');
  657. panel_ifshow=null;
  658. },500);
  659. };
  660. panel_top_action.onclick=function(){
  661. var username=prompt('请输入用户名以发起聊天');
  662. if(username!=null&&username!='')get_userid(username);
  663. }
  664. get_chatting_list(chatting_list_page);
  665. if(PageData.product=='pb')add_enterance();
  666. if(document.getElementsByClassName('tb_preload_notification')[0]){
  667. var tpn=document.getElementsByClassName('tb_preload_notification')[0];
  668. tpn.addEventListener('DOMSubtreeModified',function(){
  669. if(tpn.hasAttribute('show')==false)add_enterance();
  670. });
  671. }