chat.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // pages/list/list.js
  2. import IMOperator from "./im-operator";
  3. import UI from "./ui";
  4. import MsgManager from "./msg-manager";
  5. import ImApi from './../../apis/im'
  6. import { API_BASE_URL } from './../../config/config'
  7. import UserApi from './../../apis/user'
  8. /**
  9. * 聊天页面
  10. */
  11. Page({
  12. /**
  13. * 页面的初始数据
  14. */
  15. data: {
  16. textMessage: '',
  17. chatItems: [],
  18. latestPlayVoicePath: '',
  19. chatStatue: 'open',
  20. extraArr: [{
  21. picName: 'choose_picture',
  22. description: '照片'
  23. }, {
  24. picName: 'take_photos',
  25. description: '拍摄'
  26. },],
  27. },
  28. /**
  29. * 生命周期函数--监听页面加载
  30. */
  31. onLoad(options) {
  32. // const friend = JSON.parse({});
  33. this.setData({
  34. pageHeight: wx.getSystemInfoSync().windowHeight,
  35. toId: options.toId
  36. });
  37. wx.setNavigationBarTitle({
  38. title: options.toName || '聊天页面'
  39. })
  40. this.getFriendDetail(options.toId).then(res => {
  41. this.imOperator = new IMOperator(this, res);
  42. this.getHistory(options.toId)
  43. this.UI = new UI(this);
  44. this.msgManager = new MsgManager(this);
  45. this.listener = (msg) => {
  46. if (msg.fromId === options.toId) {
  47. this.onlyGetHistory(options.toId)
  48. this.msgManager.showMsg({msg})
  49. }
  50. }
  51. this.imOperator.onSimulateReceiveMsg(this.listener);
  52. })
  53. },
  54. onHide () {
  55. },
  56. onReady() {
  57. this.chatInput = this.selectComponent('#chatInput');
  58. },
  59. onSendMessageEvent(e) {
  60. let content = e.detail.value;
  61. this.msgManager.sendMsg({type: 'TYPE_ONE', msgType: IMOperator.TextType, content, toId: this.data.toId, fromId: getApp().globalData.userinfo.viewerId});
  62. },
  63. onVoiceRecordEvent(e) {
  64. const {detail: {recordStatus, duration, tempFilePath, fileSize,}} = e;
  65. if (recordStatus === 2) {
  66. this.msgManager.sendMsg({
  67. msgType: IMOperator.VoiceType,
  68. content: tempFilePath,
  69. duration: Math.floor(duration / 1000),
  70. toId: this.data.toId
  71. });
  72. }
  73. this.msgManager.stopAllVoice();
  74. },
  75. /**
  76. * 点击extra中的item时触发
  77. * @param e
  78. */
  79. onExtraItemClickEvent(e) {
  80. let chooseIndex = parseInt(e.detail.index);
  81. if (chooseIndex === 2) {
  82. this.myFun();
  83. return;
  84. }
  85. wx.chooseImage({
  86. count: 1, // 默认9
  87. sizeType: ['compressed'],
  88. sourceType: chooseIndex === 0 ? ['album'] : ['camera'],
  89. success: (res) => {
  90. this.msgManager.sendMsg({msgType: IMOperator.ImageType, content: res.tempFilePaths[0], toId: this.data.toId})
  91. }
  92. });
  93. },
  94. /**
  95. * 点击extra按钮时触发
  96. * @param e
  97. */
  98. onExtraClickEvent(e) {
  99. console.log(e);
  100. },
  101. //模拟上传文件,注意这里的cbOk回调函数传入的参数应该是上传文件成功时返回的文件url,这里因为模拟,我直接用的savedFilePath
  102. simulateUploadFile({savedFilePath, duration, itemIndex}) {
  103. return new Promise((resolve, reject) => {
  104. wx.uploadFile({
  105. filePath: savedFilePath,
  106. name: 'file',
  107. url: `${API_BASE_URL}/im/upload`,
  108. header: {
  109. "Content-Type": "multipart/form-data"
  110. },
  111. success: (res) => {
  112. res = JSON.parse(res.data)
  113. resolve({url: `${API_BASE_URL}/im/download/${res.data}`});
  114. },
  115. fail: (err) => {
  116. console.log(err, 'err')
  117. }
  118. })
  119. });
  120. },
  121. /**
  122. * 自定义事件
  123. */
  124. myFun() {
  125. wx.showModal({
  126. title: '小贴士',
  127. content: '演示更新会话状态',
  128. confirmText: '确认',
  129. showCancel: true,
  130. success: (res) => {
  131. if (res.confirm) {
  132. this.msgManager.sendMsg({type: IMOperator.CustomType})
  133. }
  134. }
  135. })
  136. },
  137. resetInputStatus() {
  138. this.chatInput.closeExtraView();
  139. },
  140. onUnload() {
  141. this.msgManager.stopAllVoice();
  142. this.imOperator.removeSimulateReceiveMsg(this.listener)
  143. },
  144. async sendMsg({content, itemIndex}) {
  145. try {
  146. const {msg} = await this.imOperator.onSimulateSendMsg({content})
  147. this.UI.updateViewWhenSendSuccess(msg, itemIndex);
  148. return {msg};
  149. } catch (e) {
  150. console.error(e);
  151. this.UI.updateViewWhenSendFailed(itemIndex);
  152. }
  153. },
  154. /**
  155. * 重发消息
  156. * @param e
  157. */
  158. resendMsgEvent(e) {
  159. const itemIndex = parseInt(e.currentTarget.dataset.resendIndex);
  160. const item = this.data.chatItems[itemIndex];
  161. this.UI.updateDataWhenStartSending(item, false, false);
  162. this.msgManager.resend({...item, itemIndex});
  163. },
  164. getHistory (friend_id) {
  165. return ImApi.getMsgHistory(friend_id).then(res => {
  166. res.data.reverse().forEach(item => {
  167. if (item.content) {
  168. item.isMy = item.fromId === getApp().globalData.userinfo.viewerId;
  169. this.msgManager.showMsg({msg: this.imOperator.createNormalChatItem(item)})
  170. }
  171. })
  172. })
  173. },
  174. onlyGetHistory (friend_id) {
  175. return ImApi.getMsgHistory(friend_id)
  176. },
  177. getFriendDetail (friend_id) {
  178. return UserApi.getUserInfoById(friend_id).then(res => {
  179. return {
  180. friendHeadUrl: res.data.avatar,
  181. myHeadUrl: getApp().globalData.userinfo.avatar
  182. }
  183. })
  184. }
  185. });