chat.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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="(chat,index) in chatStore.chats" :key="index">
  13. <chat-item :chat="chat" :index="index" @longpress.native="onShowMenu($event,index)"></chat-item>
  14. </view>
  15. </scroll-view>
  16. <pop-menu v-show="menu.show" :menu-style="menu.style" :items="menu.items" @close="menu.show=false"
  17. @select="onSelectMenu"></pop-menu>
  18. </view>
  19. </template>
  20. <script>
  21. export default {
  22. data() {
  23. return {
  24. menu: {
  25. show: false,
  26. style: "",
  27. chatIdx: -1,
  28. items: [{
  29. key: 'DELETE',
  30. name: '删除',
  31. icon: 'trash'
  32. },
  33. {
  34. key: 'TOP',
  35. name: '置顶',
  36. icon: 'arrow-up'
  37. }
  38. ]
  39. }
  40. }
  41. },
  42. methods: {
  43. onSelectMenu(item) {
  44. switch (item.key) {
  45. case 'DELETE':
  46. this.removeChat(this.menu.chatIdx);
  47. break;
  48. case 'TOP':
  49. this.moveToTop(this.menu.chatIdx);
  50. break;
  51. default:
  52. break;
  53. }
  54. this.menu.show = false;
  55. },
  56. onShowMenu(e, chatIdx) {
  57. uni.getSystemInfo({
  58. success: (res) => {
  59. let touches = e.touches[0];
  60. let style = "";
  61. /* 因 非H5端不兼容 style 属性绑定 Object ,所以拼接字符 */
  62. if (touches.clientY > (res.windowHeight / 2)) {
  63. style = `bottom:${res.windowHeight-touches.clientY}px;`;
  64. } else {
  65. style = `top:${touches.clientY}px;`;
  66. }
  67. if (touches.clientX > (res.windowWidth / 2)) {
  68. style += `right:${res.windowWidth-touches.clientX}px;`;
  69. } else {
  70. style += `left:${touches.clientX}px;`;
  71. }
  72. this.menu.style = style;
  73. this.menu.chatIdx = chatIdx;
  74. //
  75. this.$nextTick(() => {
  76. this.menu.show = true;
  77. });
  78. }
  79. })
  80. },
  81. removeChat(chatIdx) {
  82. this.$store.commit("removeChat", chatIdx);
  83. },
  84. moveToTop(chatIdx) {
  85. this.$store.commit("moveTop", chatIdx);
  86. },
  87. refreshUnreadBadge() {
  88. if (this.unreadCount > 0) {
  89. uni.setTabBarBadge({
  90. index: 0,
  91. text: this.unreadCount + ""
  92. })
  93. } else {
  94. uni.removeTabBarBadge({
  95. index: 0,
  96. complete: () => {}
  97. })
  98. }
  99. }
  100. },
  101. computed: {
  102. chatStore() {
  103. return this.$store.state.chatStore;
  104. },
  105. unreadCount() {
  106. let count = 0;
  107. this.chatStore.chats.forEach(chat => {
  108. count += chat.unreadCount;
  109. })
  110. return count;
  111. },
  112. loading() {
  113. return this.chatStore.loadingGroupMsg || this.chatStore.loadingPrivateMsg
  114. }
  115. },
  116. watch: {
  117. unreadCount(newCount, oldCount) {
  118. this.refreshUnreadBadge();
  119. }
  120. },
  121. onShow() {
  122. this.refreshUnreadBadge();
  123. }
  124. }
  125. </script>
  126. <style scoped lang="scss">
  127. .chat-tip {
  128. position: absolute;
  129. top: 400rpx;
  130. padding: 50rpx;
  131. line-height: 50rpx;
  132. text-align: left;
  133. color: darkblue;
  134. font-size: 30rpx;
  135. }
  136. .chat-loading {
  137. display: block;
  138. height: 100rpx;
  139. background: white;
  140. position: relative;
  141. color: blue;
  142. }
  143. </style>