chat.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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="nav-bar">
  9. <view class="nav-search">
  10. <uni-search-bar radius="100" v-model="searchText" cancelButton="none" placeholder="搜索"></uni-search-bar>
  11. </view>
  12. </view>
  13. <view class="chat-tip" v-if="!loading && chatStore.chats.length==0">
  14. 温馨提示:您现在还没有任何聊天消息,快跟您的好友发起聊天吧~
  15. </view>
  16. <scroll-view class="scroll-bar" v-else scroll-with-animation="true" scroll-y="true">
  17. <view v-for="(chat,index) in chatStore.chats" :key="index">
  18. <pop-menu v-if="isShowChat(chat)" :items="menu.items"
  19. @select="onSelectMenu($event,index)">
  20. <chat-item :chat="chat" :index="index"
  21. :active="menu.chatIdx==index"></chat-item>
  22. </pop-menu>
  23. </view>
  24. </scroll-view>
  25. </view>
  26. </template>
  27. <script>
  28. import useChatStore from '@/store/chatStore.js'
  29. export default {
  30. data() {
  31. return {
  32. chatStore: useChatStore(),
  33. searchText: "",
  34. menu: {
  35. show: false,
  36. style: "",
  37. chatIdx: -1,
  38. isTouchMove: false,
  39. items: [{
  40. key: 'DELETE',
  41. name: '删除该聊天',
  42. icon: 'trash',
  43. color: '#e64e4e'
  44. },
  45. {
  46. key: 'TOP',
  47. name: '置顶该聊天',
  48. icon: 'arrow-up'
  49. }
  50. ]
  51. }
  52. }
  53. },
  54. methods: {
  55. onSelectMenu(item,chatIdx) {
  56. switch (item.key) {
  57. case 'DELETE':
  58. this.removeChat(chatIdx);
  59. break;
  60. case 'TOP':
  61. this.moveToTop(chatIdx);
  62. break;
  63. default:
  64. break;
  65. }
  66. this.menu.show = false;
  67. },
  68. removeChat(chatIdx) {
  69. this.chatStore.removeChat(chatIdx);
  70. },
  71. moveToTop(chatIdx) {
  72. this.chatStore.moveTop(chatIdx);
  73. },
  74. isShowChat(chat){
  75. if(chat.delete){
  76. return false;
  77. }
  78. return !this.searchText || chat.showName.includes(this.searchText)
  79. },
  80. refreshUnreadBadge() {
  81. if (this.unreadCount > 0) {
  82. uni.setTabBarBadge({
  83. index: 0,
  84. text: this.unreadCount + ""
  85. })
  86. } else {
  87. uni.removeTabBarBadge({
  88. index: 0,
  89. complete: () => {}
  90. })
  91. }
  92. }
  93. },
  94. computed: {
  95. unreadCount() {
  96. let count = 0;
  97. this.chatStore.chats.forEach(chat => {
  98. if (!chat.delete) {
  99. count += chat.unreadCount;
  100. }
  101. })
  102. return count;
  103. },
  104. loading() {
  105. return this.chatStore.loadingGroupMsg || this.chatStore.loadingPrivateMsg
  106. }
  107. },
  108. watch: {
  109. unreadCount(newCount, oldCount) {
  110. this.refreshUnreadBadge();
  111. }
  112. },
  113. onShow() {
  114. this.refreshUnreadBadge();
  115. }
  116. }
  117. </script>
  118. <style scoped lang="scss">
  119. .tab-page {
  120. position: relative;
  121. border: #dddddd solid 1px;
  122. display: flex;
  123. flex-direction: column;
  124. .nav-bar {
  125. padding: 2rpx 20rpx;
  126. display: flex;
  127. align-items: center;
  128. background-color: white;
  129. border-bottom: 1px solid #ddd;
  130. height: 110rpx;
  131. .nav-search {
  132. flex: 1;
  133. height: 110rpx;
  134. }
  135. }
  136. .chat-tip {
  137. position: absolute;
  138. top: 400rpx;
  139. padding: 50rpx;
  140. line-height: 50rpx;
  141. text-align: left;
  142. color: darkblue;
  143. font-size: 30rpx;
  144. }
  145. .chat-loading {
  146. display: block;
  147. width: 100%;
  148. height: 120rpx;
  149. background: white;
  150. position: fixed;
  151. top: 0;
  152. z-index: 999;
  153. color: blue;
  154. .loading-box {
  155. position: relative;
  156. }
  157. }
  158. .scroll-bar {
  159. flex: 1;
  160. height: 100%;
  161. }
  162. }
  163. </style>