chat.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <template>
  2. <view class="tab-page">
  3. <view v-if="loading" class="chat-loading">
  4. <loading :size="50" :mask="false">
  5. <view>消息接收中...</view>
  6. </loading>
  7. </view>
  8. <view class="chat-tip" v-if="!loading && chatStore.chats.length==0">
  9. 温馨提示:您现在还没有任何聊天消息,快跟您的好友发起聊天吧~
  10. </view>
  11. <scroll-view class="scroll-bar" v-else scroll-with-animation="true" scroll-y="true">
  12. <view v-for="(chatPos,i) in chatsPos" :key="i">
  13. <chat-item v-if="!chatStore.chats[chatPos.idx].delete" :chat="chatStore.chats[chatPos.idx]"
  14. :active="menu.chatIdx==chatPos.idx" :index="chatPos.idx"
  15. @longpress.native="onShowMenu($event,chatPos.idx)"></chat-item>
  16. </view>
  17. </scroll-view>
  18. <pop-menu v-show="menu.show" :menu-style="menu.style" :items="menu.items" @close="onCloseMenu()"
  19. @select="onSelectMenu"></pop-menu>
  20. </view>
  21. </template>
  22. <script>
  23. export default {
  24. data() {
  25. return {
  26. menu: {
  27. show: false,
  28. style: "",
  29. chatIdx: -1,
  30. items: [{
  31. key: 'DELETE',
  32. name: '删除该聊天',
  33. icon: 'trash'
  34. },
  35. {
  36. key: 'TOP',
  37. name: '置顶该聊天',
  38. icon: 'arrow-up'
  39. }
  40. ]
  41. }
  42. }
  43. },
  44. methods: {
  45. onSelectMenu(item) {
  46. switch (item.key) {
  47. case 'DELETE':
  48. this.removeChat(this.menu.chatIdx);
  49. break;
  50. case 'TOP':
  51. this.moveToTop(this.menu.chatIdx);
  52. break;
  53. default:
  54. break;
  55. }
  56. this.menu.show = false;
  57. },
  58. onShowMenu(e, chatIdx) {
  59. this.menu.chatIdx = chatIdx;
  60. uni.getSystemInfo({
  61. success: (res) => {
  62. let touches = e.touches[0];
  63. let style = "";
  64. /* 因 非H5端不兼容 style 属性绑定 Object ,所以拼接字符 */
  65. if (touches.clientY > (res.windowHeight / 2)) {
  66. style = `bottom:${res.windowHeight-touches.clientY}px;`;
  67. } else {
  68. style = `top:${touches.clientY}px;`;
  69. }
  70. if (touches.clientX > (res.windowWidth / 2)) {
  71. style += `right:${res.windowWidth-touches.clientX}px;`;
  72. } else {
  73. style += `left:${touches.clientX}px;`;
  74. }
  75. this.menu.style = style;
  76. this.menu.chatIdx = chatIdx;
  77. //
  78. this.$nextTick(() => {
  79. this.menu.show = true;
  80. });
  81. }
  82. })
  83. },
  84. onCloseMenu() {
  85. this.menu.chatIdx = -1;
  86. this.menu.show = false;
  87. },
  88. removeChat(chatIdx) {
  89. this.$store.commit("removeChat", chatIdx);
  90. },
  91. moveToTop(chatIdx) {
  92. this.$store.commit("moveTop", chatIdx);
  93. },
  94. refreshUnreadBadge() {
  95. if (this.unreadCount > 0) {
  96. uni.setTabBarBadge({
  97. index: 0,
  98. text: this.unreadCount + ""
  99. })
  100. } else {
  101. uni.removeTabBarBadge({
  102. index: 0,
  103. complete: () => {}
  104. })
  105. }
  106. }
  107. },
  108. computed: {
  109. chatsPos() {
  110. // 计算会话的顺序
  111. let chatsPos = [];
  112. let chats = this.chatStore.chats;
  113. chats.forEach((chat, idx) => {
  114. chatsPos.push({
  115. idx: idx,
  116. sendTime: chat.lastSendTime
  117. })
  118. })
  119. chatsPos.sort((chatPos1, chatPos2) => {
  120. return chatPos2.sendTime - chatPos1.sendTime;
  121. });
  122. return chatsPos;
  123. },
  124. chatStore() {
  125. return this.$store.state.chatStore;
  126. },
  127. unreadCount() {
  128. let count = 0;
  129. this.chatStore.chats.forEach(chat => {
  130. if (!chat.delete) {
  131. count += chat.unreadCount;
  132. }
  133. })
  134. return count;
  135. },
  136. loading() {
  137. return this.chatStore.loadingGroupMsg || this.chatStore.loadingPrivateMsg
  138. }
  139. },
  140. watch: {
  141. unreadCount(newCount, oldCount) {
  142. this.refreshUnreadBadge();
  143. }
  144. },
  145. onShow() {
  146. this.refreshUnreadBadge();
  147. }
  148. }
  149. </script>
  150. <style scoped lang="scss">
  151. .tab-page {
  152. position: relative;
  153. border: #dddddd solid 1px;
  154. display: flex;
  155. flex-direction: column;
  156. .chat-tip {
  157. position: absolute;
  158. top: 400rpx;
  159. padding: 50rpx;
  160. line-height: 50rpx;
  161. text-align: left;
  162. color: darkblue;
  163. font-size: 30rpx;
  164. }
  165. .chat-loading {
  166. display: block;
  167. width: 100%;
  168. height: 100rpx;
  169. background: white;
  170. position: relative;
  171. color: blue;
  172. .loading-box {
  173. position: relative;
  174. }
  175. }
  176. .scroll-bar {
  177. flex: 1;
  178. height: 100%;
  179. }
  180. }
  181. </style>