chat-panel.vue 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498
  1. <template>
  2. <view @tap="ontap">
  3. <scroll-view class="chat-detail" :style="{'height':chatheight+'px'}" id="chat" scroll-y="true"
  4. :scroll-into-view="scrollToView" @scroll="chatscroll">
  5. <!-- <view class="chat-detail" id="chat" auto-height="true" > -->
  6. <!-- 加载历史数据waitingUI -->
  7. <view class="nodata" v-if="showmore && system.chattime<3650"> 仅能查看最近{{system.chattime}}日的聊天记录</view>
  8. <view class="loading" v-if="showLoading">
  9. <view class="spinner">
  10. <view class="rect1"></view>
  11. <view class="rect2"></view>
  12. <view class="rect3"></view>
  13. <view class="rect4"></view>
  14. <view class="rect5"></view>
  15. </view>
  16. </view>
  17. <view v-for="(m,index) in messagelist_old" :key="'itemold_'+m.msg_id" :id="'item_'+m.msg_id"
  18. v-if="m.isloading!=3">
  19. <messageitem :item="m" :loading_id="loading_id" :userid="userid" :playVoiceId="playVoiceId"
  20. @redpack_open="redpack_open" @atusuer='atusuer' @clickAvatar='clickAvatar' @msgAction='msgAction'
  21. @play_vedio='play_vedio' @playVoice="playVoice"></messageitem>
  22. </view>
  23. <view v-for="(m,index) in messagelist" :key="'itemnew_'+m.msg_id" :id="'item_'+m.msg_id"
  24. v-if="m.isloading!=3">
  25. <view class="nodata" v-if="unreadid==m.msg_id">以下是未读消息</view>
  26. <messageitem :item="m" :ref="'messageitem_'+index" :loading_id="loading_id" :unreadid="unreadid"
  27. :userid="userid" :playVoiceId="playVoiceId" @redpack_open="redpack_open" @atusuer='atusuer'
  28. @clickAvatar='clickAvatar' @msgAction='msgAction' @play_vedio='play_vedio' @playVoice="playVoice">
  29. </messageitem>
  30. </view>
  31. <view v-if="sending">
  32. <messageitem id="self_send" :item="sendingdata" :userid="userid" :loading_id="loading_id"
  33. @clickAvatar='clickAvatar' @redpack_open="redpack_open" @msgAction='msgAction'
  34. @play_vedio='play_vedio' @playVoice="playVoice"></messageitem>
  35. </view>
  36. <view id="self_bottom1" class="self_bottom">
  37. </view>
  38. <view id="self_bottom2" class="self_bottom">
  39. </view>
  40. </scroll-view>
  41. <view class="unread" @tap="scrollto_unread" v-if="unreadnum>0">有<view class="num">{{unreadnum}}</view>条未读消息
  42. </view>
  43. <view :class="touch_class" :style="touch_style" v-if="touch_menu">
  44. <block v-for="(m1,index1) in touch_menulist" :key="'menu_'+index1">
  45. <view @tap="tap_menu(m1.type)">{{m1.text}}</view>
  46. </block>
  47. </view>
  48. <view class="vedioplay" v-if="videoshow" :style="{'display':videoshow?'inline-block':'none'}">
  49. <video id="video_play" :src="videosrc" loop="false" autoplay="true" @play="playVedio()" @ended="endVedio()"
  50. @pause="pauseVedio()" :poster="poster"></video>
  51. <view class="bottom">
  52. <uni-icons type='closeempty' class="icon1" @tap="endVedio()"></uni-icons>
  53. </view>
  54. </view>
  55. <redpick v-if="is_redpack_open" :item="redpack_info" @closePick="is_redpack_open=false;"
  56. @fresmsg="freshmsg_fromredopen"></redpick>
  57. <logoutwords v-if="showlogout" :item="logoutinfo" @sub="logout_sub" @cancle="showlogout=false;"></logoutwords>
  58. </view>
  59. </template>
  60. <script>
  61. import {
  62. mapState,
  63. mapGetters
  64. } from 'vuex';
  65. import action from '../library/action.js'
  66. import messageitem from './messageitem.vue'
  67. import http from "../library/http.js"
  68. import chat from "../library/chat.js"
  69. import uniIcons from './uni-icons/uni-icons.vue'
  70. import redpick from './get-redpick.vue'
  71. import Vue from 'vue';
  72. import logoutwords from './logout_words.vue'
  73. const innerAudioContext = uni.createInnerAudioContext();
  74. let loadStatus = false;
  75. let lastMid = '';
  76. var windowHeight = uni.getSystemInfoSync().windowHeight;
  77. var windowWidth = uni.getSystemInfoSync().windowWidth;
  78. var statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
  79. var chatheight = windowHeight - 60;
  80. var chattop = 0;
  81. // #ifndef APP-PLUS
  82. var chattop = statusBarHeight + 45;
  83. var windowWidth = uni.getSystemInfoSync().screenHeight;
  84. var chatheight = uni.getSystemInfoSync().windowHeight - chattop - 60;
  85. // #endif
  86. function timestampToTime(timestamp) {
  87. var date = new Date(timestamp * 1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
  88. var Y = date.getFullYear();
  89. var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1);
  90. var D = date.getDate();
  91. var h = date.getHours();
  92. var m = date.getMinutes();
  93. var s = date.getSeconds();
  94. if (D < 10) D = '0' + D;
  95. if (h < 10) h = '0' + h;
  96. if (m < 10) m = '0' + m;
  97. if (s < 10) s = '0' + s;
  98. return Y + '-' + M + '-' + D + ' ' + h + ':' + m + ':' + s;
  99. }
  100. export default {
  101. components: {
  102. uniIcons,
  103. messageitem,
  104. redpick,
  105. logoutwords
  106. },
  107. props: {
  108. storeKey: {
  109. require: true
  110. },
  111. boardheight: {
  112. type: Number,
  113. default: 0
  114. },
  115. manager: {
  116. type: [Number, String, Object, Boolean],
  117. default: 0
  118. },
  119. thistype: {
  120. default: '',
  121. },
  122. sending: {
  123. type: Boolean,
  124. default: false
  125. },
  126. sendingdata: {
  127. default: {}
  128. },
  129. no_add: {
  130. type: Boolean,
  131. default: false
  132. },
  133. atme: {
  134. default: 0
  135. },
  136. at_msg_id: {
  137. default: 0
  138. }
  139. },
  140. data() {
  141. return {
  142. chatheight: chatheight,
  143. chattop: chattop,
  144. panelheight: chatheight,
  145. paddingtop: 0,
  146. scrollToView: 'self_bottom2',
  147. scrollAnimation: true,
  148. showLoading: false,
  149. playVoiceId: '',
  150. isizes: {},
  151. pageHeight: 0,
  152. contentViewHeight: 0,
  153. footViewHeight: 90,
  154. mitemHeight: 0,
  155. scrollTop: 0,
  156. letterDetails: [],
  157. senderheight: 0,
  158. hide_list: '',
  159. loading_id: 0,
  160. playVedioId: '',
  161. videoshow: false,
  162. videosrc: "",
  163. video_playing: false,
  164. video_end: false,
  165. poster: null,
  166. isbottom: false,
  167. pagemaxtop: 0,
  168. isscroll: false,
  169. pagetop: 0,
  170. storeId: 0,
  171. isgroup: 1,
  172. page: 0,
  173. pagenum: 0,
  174. userid: parseInt(uni.getStorageSync('access_token')),
  175. isfrist: 0,
  176. oldheight: 0,
  177. lastmessage: [],
  178. oldlength: 0,
  179. showmore: false,
  180. touch_menu: false,
  181. touch_style: "",
  182. touch_class: 'touch_menu',
  183. touch_menulist: [],
  184. touch_time: 0,
  185. touch_timer: null,
  186. message: [],
  187. touch_item: null,
  188. isfristload: true,
  189. maxheight: 0,
  190. msg_id1: 0,
  191. messagelist: uni.getStorageSync(uni.getStorageSync('access_token') + "_chat_" + this.storeKey),
  192. messagelist_old: [],
  193. isupdate: false,
  194. lastscroll: 0,
  195. scrollpos: 'down',
  196. unreadid: 0,
  197. unreadnum: 0,
  198. redpack_info: {},
  199. is_redpack_open: false,
  200. showlogout: false,
  201. logoutinfo: {},
  202. keyboardheight: 0,
  203. system: uni.getStorageSync('system')
  204. };
  205. },
  206. mounted() {
  207. uni.setStorageSync('storeykey', 'chat');
  208. if (this.atme == 1 && this.at_msg_id > 0) {
  209. this.scrolltoAtme();
  210. } else {
  211. this.isfristload = false;
  212. }
  213. this.scrollToBottom(0);
  214. this.storeId = this.storeKey.substr(1, this.storeKey.length - 1);
  215. if (this.storeKey.indexOf('G') > -1) {
  216. this.isgroup = 1;
  217. //群组消息
  218. this.group_read(this.storeId);
  219. } else {
  220. this.isgroup = 0;
  221. this.user_read(this.storeId);
  222. //私人消息
  223. }
  224. // console.log(this.messagelist.length)
  225. // if(this.messagelist.length>30){
  226. // for(var i=0;i<this.messagelist.length-30;i++){
  227. // this.messagelist.splice(i,1);
  228. // }
  229. // uni.setStorageSync(uni.getStorageSync('access_token')+"_chat_"+this.storeKey,this.messagelist);
  230. // }
  231. var that = this;
  232. that.messageslist(0);
  233. var that = this;
  234. this.$socket.on('chat', (res) => {
  235. this.sendmsg(res);
  236. })
  237. // #ifdef APP-PLUS
  238. var that = this;
  239. setTimeout(function() {
  240. var wh = uni.getSystemInfoSync().screenHeight;
  241. var ch = wh - statusBarHeight - 105;
  242. if (ch < that.chatheight) that.chatheight = ch;
  243. else {
  244. var wh = uni.getSystemInfoSync().windowHeight;
  245. var ch = wh - 60;
  246. that.chatheight = ch;
  247. }
  248. }, 1000)
  249. uni.onKeyboardHeightChange(res => {
  250. if (res.height > 0) {
  251. that.scrollToBottom();
  252. }
  253. this.chatheight = this.panelheight - res.height;
  254. this.$forceUpdate();
  255. this.keyboardheight = res.height;
  256. // console.log(this.chatheight);
  257. // console.log(this.panelheight,this.maxheight)
  258. // if(this.panelheight<=this.maxheight && this.messagelist.length<=6){
  259. // // that.paddingtop=res.height;
  260. // // that.$forceUpdate();
  261. // }
  262. })
  263. // #endif
  264. // console.log(message)
  265. },
  266. destroyed() {
  267. this.$socket.off('chat');
  268. uni.setStorageSync('storeykey', "index");
  269. if (this.isgroup == 1) {
  270. this.group_read(this.storeId);
  271. } else {
  272. this.user_read(this.storeId);
  273. }
  274. },
  275. computed: {},
  276. methods: {
  277. redpack_open(m) {
  278. this.redpack_info = m;
  279. this.is_redpack_open = true;
  280. },
  281. scrolltoAtme() {
  282. if (this.atme == 1 && this.at_msg_id > 0 && this.isfristload == true) {
  283. this.scrollToView = 'item_' + this.at_msg_id;
  284. this.isfristload = false;
  285. }
  286. },
  287. sendmsg(res) {
  288. var res = chat.push(res, 'chat');
  289. if (res != false) {
  290. // console.log(res.msglist.length)
  291. this.$store.commit('chat/update_msglist', res.msglist);
  292. }
  293. this.freshmsg()
  294. },
  295. freshmsg() {
  296. this.messagelist = uni.getStorageSync(this.userid + "_chat_" + this.storeKey);
  297. },
  298. freshmsg_fromredopen(e) {
  299. //this.messagelist='';
  300. this.freshmsg();
  301. // var index=this.messagelist.findIndex(v => v.msg_id == e.msg_id);
  302. // console.log(index)
  303. // this.$set(this.messagelist,index,e)
  304. },
  305. isindexhtml(str) {
  306. var arr = ['<br', '&nbsp;', "<div", "<span"];
  307. str = str.toString();
  308. for (var i = 0; i < arr.length; i++) {
  309. //console.log(str,arr[i])
  310. if (str.indexOf(arr[i]) > -1) return true;
  311. }
  312. return false;
  313. },
  314. getautoheight() {
  315. // console.log(this.oldheight);
  316. this.showLoading = false;
  317. var that = this;
  318. setTimeout(function() {
  319. if (this.pagenum > 0)
  320. that.scrollToView = 'item_'.that.msg_id1;
  321. }, 200)
  322. },
  323. message_format(data) {
  324. var messagedata = [];
  325. if (data.length > 0) {
  326. for (var i = 0; i < data.length; i++) {
  327. var item = data[i];
  328. try {
  329. if (item.type == 'time') {
  330. var temp = {
  331. type: 'tips',
  332. message: {
  333. content: item.content,
  334. type: 'tips'
  335. },
  336. 'msg_id': item.id,
  337. isloading: 0
  338. };
  339. temp['sender_id'] = item.userid;
  340. temp['sender'] = item.sender;
  341. temp['timestamp'] = item.addtime;
  342. messagedata.push(temp);
  343. } else if (item.addtime != undefined && item.addtime > 0) {
  344. var temp = {};
  345. temp['_mid'] = 'm' + Math.random().toString(36).substring(2);
  346. temp['cache_key'] = this.storeKey;
  347. temp['group_id'] = item.groupid;
  348. if (this.isgroup == 1) temp['id'] = item.groupid;
  349. else temp['id'] = item.userid;
  350. temp['isloading'] = 0;
  351. temp['msg_id'] = item.id;
  352. temp['self'] = item.self;
  353. temp['sender_id'] = item.userid;
  354. temp['sender'] = item.sender;
  355. temp['timestamp'] = item.addtime;
  356. temp['unread'] = 0;
  357. temp['type'] = item.type;
  358. temp['message'] = {
  359. 'type': item.type,
  360. 'content': item.content1
  361. };
  362. messagedata.push(temp);
  363. }
  364. } catch (e) {
  365. //TODO handle the exception
  366. /// console.log(e)
  367. }
  368. }
  369. }
  370. return messagedata;
  371. },
  372. //获取云端消息记录
  373. messageslist(totime) {
  374. var lists = [];
  375. var time1 = (new Date()).getTime() / 1000 - 7 * 24 * 3600;
  376. if (totime < 1) {
  377. var isfrist = true;
  378. totime = parseInt((new Date()).getTime() / 1000);
  379. } else {
  380. var isfrist = false;
  381. if (this.showLoading == true) return false;
  382. }
  383. var storekey = this.storeKey
  384. var postdata = {
  385. id: parseInt(this.storeId),
  386. userid: parseInt(this.userid),
  387. isgroup: this.isgroup,
  388. totime: totime
  389. };
  390. var that = this;
  391. http.setWait(false).get('group.php?act=messages2', postdata).then(res => {
  392. if (res.code == 200) {
  393. // console.log(res);
  394. var data = res.data;
  395. var messagedata = this.message_format(data);
  396. if (isfrist == true) {
  397. if (messagedata.length < 1) {
  398. this.messagelist = [];
  399. this.showmore = true;
  400. }
  401. uni.setStorageSync(this.userid + "_chat_" + this.storeKey, messagedata);
  402. this.freshmsg();
  403. var that = this;
  404. setTimeout(function() {
  405. if (that.atme == 1 && that.at_msg_id > 0) {
  406. that.scrolltoAtme();
  407. } else
  408. that.scrollToBottom();
  409. that.isupdate = true;
  410. }, 300)
  411. } else {
  412. this.showLoading = false;
  413. if (messagedata.length > 0) {
  414. if (this.messagelist_old.length > 0) {
  415. var scrollToView = 'item_' + this.messagelist_old[0].msg_id;
  416. this.messagelist_old.unshift(...messagedata)
  417. } else {
  418. var scrollToView = 'item_' + this.messagelist[0].msg_id;
  419. this.messagelist_old = messagedata;
  420. }
  421. this.showmore = false;
  422. var that = this;
  423. setTimeout(function() {
  424. that.scrollToView = scrollToView
  425. }, 200)
  426. } else {
  427. this.showmore = true;
  428. }
  429. }
  430. }
  431. })
  432. },
  433. update_message(data) {
  434. var isin = 0;
  435. for (var i = this.messagelist.length - 1; i >= 0; i--) {
  436. var item = this.messagelist[i];
  437. if (parseInt(item.msg_id) == parseInt(data.msg.msg_id)) {
  438. return false;
  439. }
  440. }
  441. var messageold = uni.getStorageSync(this.userid + "_chatold_" + this.storeKey);
  442. for (var i = messageold.length - 1; i >= 0; i--) {
  443. var item = messageold[i];
  444. if (parseInt(item.msg_id) == parseInt(data.msg.msg_id)) {
  445. return false;
  446. }
  447. }
  448. var message = messageold.concat(this.messagelist);
  449. },
  450. //设置群未读消息
  451. group_read(group_id) {
  452. this.$store.commit('chat/clearunread', this.storeKey);
  453. },
  454. user_read(userid) {
  455. this.$store.commit('chat/clearunread', this.storeKey);
  456. },
  457. scrollto_unread() {
  458. this.scrollToView = "item_" + this.unreadid;
  459. this.unreadid = 0;
  460. this.unreadnum = 0;
  461. },
  462. chatscroll(e) {
  463. // if(this.keyboardheight>0) uni.hideKeyboard();
  464. this.touch_menu = false;
  465. var top = e.detail.scrollTop;
  466. this.maxheight = e.detail.scrollHeight;
  467. if (top > this.maxheight) this.maxheight = top;
  468. if (top + this.panelheight >= this.maxheight - 100 && top > 0) {
  469. this.isbottom = true;
  470. this.unreadid = 0;
  471. this.unreadnum = 0;
  472. } else this.isbottom = false;
  473. if (top > this.lastscroll) this.scrollpos = 'down';
  474. else this.scrollpos = 'up';
  475. // console.log(this.scrollpos,this.isbottom);
  476. this.lastscroll = top;
  477. if (top < 50 && this.isfristload == false && this.isupdate == true) {
  478. if (this.messagelist_old.length > 0) {
  479. var msg = this.messagelist_old[0];
  480. } else {
  481. var msg = this.messagelist[0];
  482. }
  483. if (msg.timestamp == undefined) var totime = msg.msg_id;
  484. else var totime = msg.timestamp;
  485. if (totime > 0) totime = totime - 1;
  486. this.messageslist(parseInt(totime));
  487. this.showLoading = true;
  488. }
  489. },
  490. setAutoHeight(e) {
  491. //console.log(e);
  492. this.touch_menu = false;
  493. },
  494. vedio_show(m) {
  495. if (m.isloading == 1) {
  496. return m.message.content.src;
  497. } else
  498. return this.image_cache(m.message.content.src)
  499. },
  500. poster_show(m) {
  501. if (m.isloading == 1) {
  502. return false;
  503. } else {
  504. var src = m.message.content.src;
  505. try {
  506. var arr = src.split('/');
  507. var filename = arr[arr.length - 1];
  508. var arr1 = filename.split('.');
  509. var newname = arr1[0] + "_video.jpg";
  510. var poster = src.replace(filename, newname);
  511. return poster;
  512. } catch (e) {
  513. //TODO handle the exception
  514. return "/static/img/vediobanner.jpg";
  515. }
  516. }
  517. },
  518. scrollToBottom: function() {
  519. var that = this;
  520. setTimeout(function() {
  521. if (that.scrollToView == "self_bottom1")
  522. that.scrollToView = "self_bottom2";
  523. else {
  524. that.scrollToView = "self_bottom1";
  525. }
  526. that.pagenum = 0;
  527. that.isbottom = true;
  528. that.unreadnum = 0;
  529. that.unreadid = 0;
  530. }, 200)
  531. },
  532. play_vedio(m) {
  533. this.videoshow = true;
  534. this.videosrc = this.vedio_show(m);
  535. this.poster = this.poster_show(m);
  536. this.video_playing = false;
  537. var that = this;
  538. setTimeout(function() {
  539. var videoContext = uni.createVideoContext('video_play');
  540. if (that.video_playing == false) {
  541. // videoContext.requestFullScreen(0);
  542. // setTimeout(function(){videoContext.play()},100);
  543. that.playVedioId = m._mid;
  544. videoContext.play();
  545. }
  546. }, 500)
  547. },
  548. //结束播放
  549. endVedio() {
  550. this.video_end = true;
  551. var videoContext = uni.createVideoContext('video_play');
  552. // videoContext.exitFullScreen();
  553. videoContext.pause();
  554. this.playVedioId = "";
  555. this.videosrc = "";
  556. this.pauseVedio();
  557. var that = this;
  558. that.video_end = false;
  559. },
  560. playVedio() {
  561. this.video_playing = true;
  562. this.video_end = false;
  563. this.videoshow = true;
  564. },
  565. pauseVedio() {
  566. this.video_playing = false;
  567. this.videoshow = false;
  568. },
  569. screenchange() {
  570. if (this.video_playing == true) {
  571. var videoContext = uni.createVideoContext('video_play');
  572. videoContext.exitFullScreen();
  573. videoContext.pause();
  574. this.playVedioId = "";
  575. this.videosrc = "";
  576. this.pauseVedio();
  577. } else {
  578. if (this.video_end == false) {
  579. var videoContext = uni.createVideoContext('video_play');
  580. videoContext.play();
  581. }
  582. }
  583. },
  584. playVoice(message) {
  585. var that = this;
  586. var id = message._mid;
  587. if (this.playVoiceId == id) {
  588. innerAudioContext.stop();
  589. innerAudioContext.src = '';
  590. that.playVoiceId = "";
  591. that.loading_id = 0;
  592. return false;
  593. }
  594. if (this.playVoiceId !== '') {
  595. innerAudioContext.stop();
  596. innerAudioContext.src = '';
  597. that.playVoiceId = "";
  598. that.loading_id = 0;
  599. }
  600. // if (this.playVoiceId == '') {
  601. this.loading_id = id;
  602. innerAudioContext.src = this.image_cache(message.message.content.url);
  603. innerAudioContext.volume = 1;
  604. innerAudioContext.autoplay = true;
  605. innerAudioContext.onCanplay(function() {
  606. innerAudioContext.play();
  607. that.playVoiceId = id;
  608. that.loading_id = 0;
  609. })
  610. innerAudioContext.onEnded(() => {
  611. innerAudioContext.stop();
  612. innerAudioContext.src = '';
  613. that.playVoiceId = "";
  614. that.loading_id = 0;
  615. });
  616. },
  617. atusuer(msg) {
  618. if (msg.sender.id != this.userid) {
  619. let result = {
  620. id: msg.id,
  621. nickname: msg.sender.nickname
  622. }
  623. this.$emit('close', result);
  624. }
  625. // console.log(msg) ;
  626. },
  627. clickAvatar(msg) {
  628. if (msg.id > 0) {
  629. var params = {
  630. id: msg.sender.id,
  631. 'group_id': msg.group_id,
  632. thistype: this.thistype
  633. };
  634. // console.log(JSON.stringify(msg));
  635. return this.$jump('friend.detail', params)
  636. //this.$emit('click-avatar', this.messages[index]);
  637. } else {
  638. return false;
  639. }
  640. },
  641. toText(msg) {
  642. var text = msg.replace(/&nbsp;/g, ' ');
  643. text = text.replace(/<br>/g, '\n');
  644. text = text.replace(/<\/?[^>]*>/g, '');
  645. return text;
  646. },
  647. copyText(msg) {
  648. var message = msg.message;
  649. if (message.content.type == 'remind')
  650. var content = message.content.content;
  651. else if (message.type == 'url')
  652. var content = message.content.content;
  653. else var content = message.content
  654. content = this.toText(content);
  655. uni.setClipboardData({
  656. data: content,
  657. success: function() {
  658. uni.showToast({
  659. title: '复制成功',
  660. icon: 'none'
  661. })
  662. }
  663. });
  664. },
  665. ontap() {
  666. if (new Date().getTime() - this.touch_time > 1500) this.touch_menu = false;;
  667. },
  668. delete_msg(msg) {
  669. var list = this.messagelist;
  670. var isin = 0;
  671. var list11 = [];
  672. list.forEach(item => {
  673. if (parseInt(item.msg_id) == parseInt(msg.msg_id)) {
  674. // item.isloading=3;
  675. isin = 1;
  676. } else {
  677. list11.push(item);
  678. }
  679. })
  680. var that = this;
  681. if (isin == 1) {
  682. that.messagelist = list11;
  683. uni.setStorageSync(this.userid + "_chat_" + this.storeKey, list11);
  684. } else {
  685. var list = this.messagelist_old;
  686. var list11 = [];
  687. list.forEach(item => {
  688. if (parseInt(item.msg_id) == parseInt(msg.msg_id)) {
  689. } else {
  690. list11.push(item);
  691. }
  692. })
  693. that.messagelist_old = list11;
  694. }
  695. var postdata = {
  696. id: msg.msg_id,
  697. userid: this.userid
  698. };
  699. http.setWait(false).get('group.php?act=clearchatlist', postdata).then(res => {
  700. })
  701. // this.freshmsg();
  702. },
  703. logout_sub(e) {
  704. uni.showToast({
  705. icon: 'none',
  706. title: '操作成功'
  707. })
  708. },
  709. tap_menu(type) {
  710. var msg = this.touch_item;
  711. uni.showToast({
  712. title: new Date().getTime() - this.touch_time
  713. })
  714. if (new Date().getTime() - this.touch_time > 1000) {
  715. this.touch_menu = false;
  716. var that = this;
  717. if(type == 'quote') {
  718. console.log('this.touch_item:',this.touch_item);
  719. this.$emit('chooseQuote',this.touch_item)
  720. }
  721. if (type == "delete") {
  722. // this.clearchatlist(msg);
  723. this.delete_msg(msg)
  724. }
  725. if (type == 'copy') {
  726. that.copyText(msg);
  727. }
  728. if (type == 'back') {
  729. let data = {
  730. userid: that.userid,
  731. msg_id: msg.msg_id,
  732. type: 'chat_back',
  733. store: that.storeKey
  734. }
  735. that.$socket.send(data);
  736. }
  737. if (type == 'at') {
  738. that.atusuer(msg);
  739. }
  740. if (type == 'view') {
  741. that.clickAvatar(msg);
  742. }
  743. if (type == 'manage0') {
  744. var data = {
  745. type: 'groupset1',
  746. mode: 'manage',
  747. settype: 0,
  748. group_id: msg.group_id,
  749. userid: msg.sender.id,
  750. from_uid: uni.getStorageSync('access_token')
  751. };
  752. that.$socket.send(data);
  753. }
  754. if (type == 'manage1') {
  755. var data = {
  756. type: 'groupset1',
  757. mode: 'manage',
  758. settype: 1,
  759. group_id: msg.group_id,
  760. userid: msg.sender.id,
  761. from_uid: uni.getStorageSync('access_token')
  762. };
  763. that.$socket.send(data);
  764. }
  765. if (type == 'deny0') {
  766. var data = {
  767. type: 'groupset1',
  768. mode: 'deny',
  769. settype: 0,
  770. group_id: msg.group_id,
  771. userid: msg.sender.id,
  772. from_uid: uni.getStorageSync('access_token')
  773. };
  774. that.$socket.send(data);
  775. }
  776. if (type == 'deny1') {
  777. var data = {
  778. type: 'groupset1',
  779. mode: 'deny',
  780. settype: 1,
  781. group_id: msg.group_id,
  782. userid: msg.sender.id,
  783. from_uid: uni.getStorageSync('access_token')
  784. };
  785. that.$socket.send(data);
  786. }
  787. if (type == 'deleteuser') {
  788. // var data={type:'deleteGroup',group_id:msg.group_id,userid:msg.id,fromid:uni.getStorageSync('access_token')};
  789. // that.$socket.send(data);
  790. this.showlogout = true;
  791. this.logoutinfo = {
  792. group_id: msg.group_id,
  793. userid: msg.sender.id,
  794. nickname: msg.sender.nickname
  795. };
  796. }
  797. if (type == 'manage0' || type == 'manage1' || type == 'deny0' || type == 'deny1' || type ==
  798. 'deleteuser') {
  799. uni.showToast({
  800. title: '操作成功',
  801. icon: 'none'
  802. })
  803. }
  804. }
  805. },
  806. msgAction(e, msg) {
  807. this.touch_item = msg;
  808. this.touch_time = new Date().getTime();
  809. var user_id = uni.getStorageSync('access_token');
  810. var that = this;
  811. var itemList = [{
  812. type: 'delete',
  813. text: '删除'
  814. }];
  815. if ((that.manager == 1 && msg.group_id > 0) || (user_id == msg.sender.id && new Date().getTime() /
  816. 1000 - (parseInt(msg.timestamp)) <= 120)) {
  817. itemList.push({
  818. type: 'back',
  819. text: '撤回消息'
  820. });
  821. }
  822. if (msg.message.type == 'text' || msg.message.type == 'url') {
  823. itemList = itemList.concat([{
  824. type: 'copy',
  825. text: '复制'
  826. }, {
  827. type: 'quote',
  828. text: '引用'
  829. }])
  830. // itemList.push({
  831. // type: 'copy',
  832. // text: '复制'
  833. // });
  834. }
  835. if(msg.message.type == 'emotion' || msg.message.type == 'image') {
  836. itemList.push({
  837. type: 'quote',
  838. text: '引用'
  839. });
  840. }
  841. if (that.manager == 1 && msg.group_id > 0 && user_id != msg.sender.id) {
  842. var users = uni.getStorageSync(msg.group_id + '_group_members');
  843. var thistype = 'user';
  844. var usertype = "user";
  845. var is_deny = 0;
  846. var isin = 0;
  847. for (var i = 0; i < users.length; i++) {
  848. if (users[i].id == user_id) thistype = users[i].type;
  849. if (users[i].id == msg.sender.id) {
  850. usertype = users[i].type;
  851. is_deny = users[i].is_deny;
  852. isin = 1;
  853. }
  854. }
  855. }
  856. if (thistype == 'owner') {
  857. if (usertype == 'manager') itemList.push({
  858. 'type': 'manage0',
  859. 'text': '取消管理'
  860. });
  861. else itemList.push({
  862. 'type': 'manage1',
  863. 'text': '设为管理'
  864. });
  865. if (is_deny == 1) itemList.push({
  866. 'type': 'deny0',
  867. 'text': '解除禁言'
  868. });
  869. else itemList.push({
  870. 'type': 'deny1',
  871. 'text': '禁言'
  872. });
  873. if (isin == 1) itemList.push({
  874. 'type': 'deleteuser',
  875. 'text': '踢人'
  876. });
  877. }
  878. if (thistype == 'manager' && usertype == 'user') {
  879. if (is_deny == 1) itemList.push({
  880. 'type': 'deny0',
  881. 'text': '解除禁言'
  882. });
  883. else itemList.push({
  884. 'type': 'deny1',
  885. 'text': '禁言'
  886. });
  887. if (isin == 1) itemList.push({
  888. 'type': 'deleteuser',
  889. 'text': '踢人'
  890. });
  891. }
  892. // itemList.push({type:'view',text:'查看名片'});
  893. this.touch_menulist = itemList;
  894. this.touch_menu = 0;
  895. var y = e.changedTouches[0].clientY + 50;
  896. var yy = "top";
  897. var xx = "left";
  898. var top = 0;
  899. var classname = "touch_menu";
  900. var len = itemList.length;
  901. if (y < 160) {
  902. yy = 'top'
  903. top = y - 10
  904. classname += ' top';
  905. } else {
  906. top = windowHeight - y + 85;
  907. yy = 'bottom';
  908. classname += ' bottom'
  909. }
  910. if (msg.sender.id == this.userid) {
  911. var xx = "right";
  912. //var x=windowWidth-x;
  913. classname += " right";
  914. } else classname += " left";
  915. this.touch_class = classname;
  916. this.touch_style = yy + ":" + top + "px";
  917. setTimeout(function() {
  918. that.touch_menu = true;
  919. }, 100)
  920. clearTimeout(this.touch_timer);
  921. this.touch_timer = setTimeout(function() {
  922. that.touch_menu = 0;
  923. }, 5000)
  924. },
  925. },
  926. watch: {
  927. messagelist(val) {
  928. if (val.length > 0) {
  929. var last = val[val.length - 1];
  930. if (last.msg_id != this.lastmessage.msg_id) {
  931. //this.pagenum=0;
  932. // console.log(last);
  933. if (last.self == 1 && this.sendingdata._mid == last._mid || last.message.type == 'tips') {
  934. this.$emit('setSending', false);
  935. this.scrollToBottom();
  936. } else {
  937. if (this.isbottom == true) {
  938. this.scrollToBottom();
  939. } else {
  940. if (last.self != 1) {
  941. this.unreadnum++;
  942. if (this.unreadid == 0) this.unreadid = last.msg_id;
  943. }
  944. }
  945. }
  946. }
  947. this.lastmessage = last;
  948. } else {
  949. this.showmore = true;
  950. }
  951. var that = this;
  952. this.$store.commit('chat/clearunread', this.storeKey);
  953. // //创建后调用回到底部方法
  954. },
  955. sending(val) {
  956. if (val != false) {
  957. this.scrollToBottom();
  958. }
  959. }
  960. }
  961. }
  962. </script>
  963. <style lang="scss" scoped>
  964. $redpackBgColor: #EF9638;
  965. $reverseTextBgColor: #3388ff;
  966. $voiceBgColor: #fafafa;
  967. $voiceColor: #000;
  968. $reverseVoiceBgColor: #3388ff;
  969. $reverseVoiceColor: #fff;
  970. .chat-detail {
  971. width: 100%;
  972. padding: 0px 0px;
  973. position: fixed;
  974. z-index: 1;
  975. left: 0px;
  976. bottom: 60px;
  977. width: 100%;
  978. }
  979. .unread {
  980. position: fixed;
  981. z-index: 999s;
  982. right: 5px;
  983. bottom: 75px;
  984. height: 25px;
  985. line-height: 25px;
  986. padding: 0px 10px;
  987. border-radius: 10px;
  988. background-color: #eee;
  989. color: #333;
  990. font-size: 14px;
  991. clear: both;
  992. }
  993. .unread .num {
  994. color: #FF0000;
  995. padding: 0px 2px;
  996. display: inline-block;
  997. font-weight: 600;
  998. }
  999. .self_bottom {
  1000. height: 10px;
  1001. display: block;
  1002. clear: both;
  1003. margin-top: 10px;
  1004. }
  1005. .nodata {
  1006. height: 30px;
  1007. line-height: 30px;
  1008. text-align: center;
  1009. font-size: 12px;
  1010. color: #ccc;
  1011. }
  1012. .vedioplay {
  1013. position: fixed;
  1014. z-index: 9999999999;
  1015. background-color: #000;
  1016. top: 0px;
  1017. width: 100%;
  1018. left: 0px;
  1019. height: 100vh;
  1020. line-height: calc(100vh - 45px);
  1021. vertical-align: middle;
  1022. display: table-cell;
  1023. }
  1024. .vedioplay video {
  1025. vertical-align: middle;
  1026. width: 100%;
  1027. display: inline-block;
  1028. }
  1029. .vedioplay .bottom {
  1030. position: absolute;
  1031. z-index: 999;
  1032. bottom: 10px;
  1033. left: 0px;
  1034. ;
  1035. width: 100%;
  1036. height: 50px;
  1037. line-height: 50px;
  1038. color: #fff;
  1039. text-align: center;
  1040. }
  1041. .vedioplay .bottom .icon1 {
  1042. font-size: 36px !important;
  1043. color: #eee !important;
  1044. }
  1045. .vedio {
  1046. display: inline-block;
  1047. float: left;
  1048. width: calc(100% - 200upx);
  1049. border-radius: 10upx;
  1050. padding-top: 0upx;
  1051. padding-bottom: 0upx;
  1052. overflow: hidden;
  1053. position: relative;
  1054. z-index: 0;
  1055. }
  1056. .vedio .timeshow {
  1057. position: absolute;
  1058. right: 12upx;
  1059. bottom: 16upx;
  1060. font-size: 24upx;
  1061. color: #FFFFFF;
  1062. z-index: 999999999;
  1063. }
  1064. .vedio .play_btn {
  1065. position: absolute;
  1066. height: 80upx;
  1067. width: 80upx;
  1068. left: calc(50% - 40upx);
  1069. top: calc(50% - 40upx);
  1070. z-index: 999999999;
  1071. }
  1072. .vedio_src {
  1073. max-width: 100%;
  1074. border-radius: 10upx;
  1075. max-height: 70vw;
  1076. z-index: 0 !important;
  1077. }
  1078. .touch_menu {
  1079. position: fixed;
  1080. z-index: 9999;
  1081. background-color: rgba(0, 0, 0, 0.8);
  1082. border: 1px #000 solid;
  1083. border-radius: 10px;
  1084. padding: 0px 10px;
  1085. line-height: 30px;
  1086. max-width: 100%;
  1087. font-size: 14px;
  1088. min-height: 40px;
  1089. }
  1090. .touch_menu view {
  1091. height: 45px;
  1092. line-height: 45px;
  1093. color: #fff;
  1094. display: inline-block;
  1095. padding: 0px 10px;
  1096. text-align: center;
  1097. border-right: 1px #999 solid;
  1098. }
  1099. .touch_menu view:last-child {
  1100. border-width: 0px;
  1101. ;
  1102. }
  1103. .touch_menu.right view {
  1104. padding: 0px 15px;
  1105. }
  1106. .touch_menu::before {
  1107. display: block;
  1108. content: " ";
  1109. position: absolute;
  1110. width: 0;
  1111. height: 0;
  1112. border-style: solid;
  1113. }
  1114. .touch_menu.top::before {
  1115. top: -12px;
  1116. border-width: 0px 12px 12px 12px;
  1117. border-color: #000 transparent;
  1118. }
  1119. .touch_menu.bottom::before {
  1120. bottom: -24px;
  1121. border-width: 12px;
  1122. border-color: #000 transparent transparent transparent;
  1123. }
  1124. .touch_menu.left {
  1125. text-align: left;
  1126. left: 3px;
  1127. }
  1128. .touch_menu.right {
  1129. text-align: right;
  1130. right: 20px;
  1131. }
  1132. .touch_menu.left::before {
  1133. left: 70px;
  1134. }
  1135. .touch_menu.right::before {
  1136. right: 50px;
  1137. }
  1138. .first {
  1139. width: 2px;
  1140. height: 2px;
  1141. background: #fff;
  1142. top: 22px;
  1143. left: 22px;
  1144. }
  1145. .second {
  1146. width: 12px;
  1147. height: 12px;
  1148. top: 17px;
  1149. left: 17px;
  1150. }
  1151. .third {
  1152. width: 20px;
  1153. height: 20px;
  1154. top: 12px;
  1155. left: 12px;
  1156. }
  1157. @keyframes fadeInOut {
  1158. 0% {
  1159. opacity: 0;
  1160. }
  1161. 100% {
  1162. opacity: 1;
  1163. }
  1164. }
  1165. /**/
  1166. .loading {
  1167. //loading动画
  1168. display: flex;
  1169. justify-content: center;
  1170. @keyframes stretchdelay {
  1171. 0%,
  1172. 40%,
  1173. 100% {
  1174. transform: scaleY(0.6);
  1175. }
  1176. 20% {
  1177. transform: scaleY(1.0);
  1178. }
  1179. }
  1180. .spinner {
  1181. margin: 20upx 0;
  1182. width: 60upx;
  1183. height: 25px;
  1184. display: flex;
  1185. align-items: center;
  1186. justify-content: space-between;
  1187. view {
  1188. background-color: #ff9800;
  1189. height: 25px;
  1190. width: 3px;
  1191. border-radius: 3px;
  1192. animation: stretchdelay 1.2s infinite ease-in-out;
  1193. }
  1194. .rect2 {
  1195. animation-delay: -1.1s;
  1196. }
  1197. .rect3 {
  1198. animation-delay: -1.0s;
  1199. }
  1200. .rect4 {
  1201. animation-delay: -0.9s;
  1202. }
  1203. .rect5 {
  1204. animation-delay: -0.8s;
  1205. }
  1206. }
  1207. }
  1208. image {
  1209. will-change: transform;
  1210. }
  1211. .loadingbox {
  1212. height: 80upx;
  1213. width: 70upx;
  1214. justify-content: center;
  1215. line-height: 80upx;
  1216. display: inline-block;
  1217. text-align: center;
  1218. vertical-align: top;
  1219. }
  1220. .loadingbox image {
  1221. height: 36upx;
  1222. width: 36upx;
  1223. vertical-align: middle;
  1224. }
  1225. </style>