NormalOutMessageContentContainerView.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <template>
  2. <div>
  3. <div class="message-time-container" v-bind:class="{checked:sharedPickState.messages.indexOf(message) >= 0}">
  4. <p v-if="this.message._showTime" class="time">{{ message._timeStr }}</p>
  5. <div class="message-content-container"
  6. v-bind:class="{checked:sharedPickState.messages.indexOf(message) >= 0}">
  7. <checkbox id="checkbox" v-if="sharedConversationState.enableMessageMultiSelection" type="checkbox"
  8. class="checkbox"
  9. :checked="isMessageChecked"
  10. :value="message" placeholder="" v-model="sharedPickState.messages"/>
  11. <div class="message-avatar-content-container">
  12. <!-- 文件的进度条有点特殊,有进度的消息的进度条有点特殊 -->
  13. <!-- <button>progress...</button>-->
  14. <LoadingView v-if="message.status === 0 || isDownloading"/>
  15. <i v-if="message.status === 2" class="icon-ion-close-circled" style="color: red" @click="resend"/>
  16. <div class="flex-column flex-align-end">
  17. <MessageContentContainerView :message="message"
  18. class="message-content-container-view"
  19. @longpress.native="openMessageContextMenu($event, message)"/>
  20. <QuoteMessageView v-if="quotedMessage"
  21. style="padding: 5px 0; max-width: 80%"
  22. :message="message"
  23. :quoted-message="quotedMessage"
  24. :message-digest="this.message.messageContent.quoteInfo.messageDigest"
  25. :show-close-button="false"/>
  26. </div>
  27. <img
  28. class="avatar"
  29. @click="onClickUserPortrait(message.from)"
  30. draggable="false"
  31. :src="message._from.portrait" alt="">
  32. </div>
  33. </div>
  34. <p v-if="shouldShowMessageReceipt" class="receipt" @click="showMessageReceiptDetail">
  35. {{ messageReceipt }}</p>
  36. </div>
  37. </div>
  38. </template>
  39. <script>
  40. import UserCardView from "@/pages/user/UserCardView";
  41. import Message from "@/wfc/messages/message";
  42. import MessageContentContainerView from "@/pages/conversation/message/MessageContentContainerView";
  43. import store from "@/store";
  44. import LoadingView from "@/pages/common/LoadingView";
  45. import wfc from "@/wfc/client/wfc";
  46. import ConversationType from "@/wfc/model/conversationType";
  47. import {gte} from "@/wfc/util/longUtil";
  48. import MessageReceiptDetailView from "@/pages/conversation/message/MessageReceiptDetailView";
  49. import QuoteMessageView from "@/pages/conversation/message/QuoteMessageView";
  50. import Config from "@/config";
  51. export default {
  52. name: "NormalOutMessageContentView",
  53. props: {
  54. message: {
  55. type: Message,
  56. required: true,
  57. },
  58. },
  59. data() {
  60. return {
  61. sharedConversationState: store.state.conversation,
  62. sharedPickState: store.state.pick,
  63. highLight: false,
  64. quotedMessage: null,
  65. }
  66. },
  67. components: {
  68. QuoteMessageView,
  69. LoadingView,
  70. MessageContentContainerView,
  71. UserCardView,
  72. // TextMessageContentView,
  73. },
  74. mounted() {
  75. if (this.message.messageContent.quoteInfo) {
  76. let messageUid = this.message.messageContent.quoteInfo.messageUid;
  77. let msg = store.getMessageByUid(messageUid);
  78. if (!msg) {
  79. wfc.loadRemoteMessage(messageUid, (ms) => {
  80. msg = store._patchMessage(ms[0]);
  81. this.quotedMessage = msg;
  82. }, err => {
  83. console.log('load remote message error', messageUid, err)
  84. })
  85. } else {
  86. this.quotedMessage = msg;
  87. }
  88. }
  89. },
  90. methods: {
  91. onClickUserPortrait(userId) {
  92. store.setCurrentFriend(this.message._from);
  93. uni.navigateTo({
  94. url: '/pages/contact/UserDetailPage',
  95. success: () => {
  96. console.log('nav to UserDetailPage success');
  97. },
  98. fail: (err) => {
  99. console.log('nav to UserDetailPage err', err);
  100. }
  101. })
  102. },
  103. resend() {
  104. wfc.deleteMessage(this.message.messageId);
  105. wfc.sendMessage(this.message);
  106. },
  107. openMessageContextMenu(event, message) {
  108. this.$parent.$emit('openMessageContextMenu', event, message)
  109. this.highLight = true;
  110. },
  111. showMessageReceiptDetail() {
  112. let conversation = this.message.conversation;
  113. if (conversation.type === ConversationType.Single) {
  114. return;
  115. }
  116. let timestamp = this.message.timestamp;
  117. let deliveries = this.sharedConversationState.currentConversationDeliveries;
  118. let readEntries = this.sharedConversationState.currentConversationRead;
  119. if (conversation.type === ConversationType.Group) {
  120. let groupMembers = wfc.getGroupMemberIds(conversation.target, false);
  121. if (!groupMembers || groupMembers.length === 0) {
  122. // do nothing
  123. } else {
  124. let receivedUserIds = [];
  125. let readUserIds = [];
  126. let unReceiveUserIds = [];
  127. groupMembers.forEach(memberId => {
  128. let recvDt = deliveries ? deliveries.get(memberId) : 0;
  129. let readDt = readEntries ? readEntries.get(memberId) : 0;
  130. if (readDt && gte(readDt, timestamp)) {
  131. readUserIds.push(memberId);
  132. } else if (recvDt && gte(recvDt, timestamp)) {
  133. receivedUserIds.push(memberId)
  134. } else {
  135. unReceiveUserIds.push(memberId)
  136. }
  137. });
  138. let readUsers = store.getUserInfos(readUserIds, conversation.target)
  139. let receivedUsers = store.getUserInfos(receivedUserIds, conversation.target)
  140. let unreceiveUsers = store.getUserInfos(unReceiveUserIds, conversation.target)
  141. this.$modal.show(
  142. MessageReceiptDetailView,
  143. {
  144. readUsers: readUsers,
  145. receivedUsers: receivedUsers,
  146. unreceiveUsers: unreceiveUsers,
  147. }, {
  148. name: 'message-receipt-detail-modal',
  149. width: 480,
  150. height: 300,
  151. clickToClose: true,
  152. }, {})
  153. }
  154. }
  155. },
  156. },
  157. computed: {
  158. messageReceipt() {
  159. let conversation = this.message.conversation;
  160. let timestamp = this.message.timestamp;
  161. let receiptDesc = ''
  162. let deliveries = this.sharedConversationState.currentConversationDeliveries;
  163. let readEntries = this.sharedConversationState.currentConversationRead;
  164. if (conversation.type === ConversationType.Single) {
  165. let readDt = readEntries ? readEntries.get(conversation.target) : 0
  166. readDt = readDt ? readDt : 0;
  167. let recvDt = deliveries ? deliveries.get(conversation.target) : 0;
  168. recvDt = recvDt ? recvDt : 0;
  169. if (gte(readDt, timestamp)) {
  170. receiptDesc = "已读";
  171. } else if (gte(recvDt, timestamp)) {
  172. receiptDesc = "已送达";
  173. } else {
  174. receiptDesc = "未送达";
  175. }
  176. } else {
  177. let groupMembers = wfc.getGroupMemberIds(conversation.target, false);
  178. if (!groupMembers || groupMembers.length === 0) {
  179. receiptDesc = '';
  180. } else {
  181. let memberCount = groupMembers.length;
  182. let recvCount = 0;
  183. let readCount = 0;
  184. let receivedUserIds = [];
  185. let readUserIds = [];
  186. let unReceiveUserIds = [];
  187. groupMembers.forEach(memberId => {
  188. let recvDt = deliveries ? deliveries.get(memberId) : 0;
  189. let readDt = readEntries ? readEntries.get(memberId) : 0;
  190. if (readDt && gte(readDt, timestamp)) {
  191. readCount++;
  192. readUserIds.push(memberId);
  193. recvCount++;
  194. } else if (recvDt && gte(recvDt, timestamp)) {
  195. recvCount++;
  196. receivedUserIds.push(memberId)
  197. } else {
  198. unReceiveUserIds.push(memberId)
  199. }
  200. });
  201. receiptDesc = `已送达 ${recvCount}/${memberCount},已读 ${readCount}/${memberCount}`
  202. }
  203. }
  204. return receiptDesc;
  205. },
  206. isDownloading() {
  207. return store.isDownloadingMessage(this.message.messageId);
  208. },
  209. shouldShowMessageReceipt() {
  210. return this.sharedConversationState.isMessageReceiptEnable && ["FireRobot", Config.FILE_HELPER_ID].indexOf(this.message.conversation.target) < 0;
  211. },
  212. isMessageChecked() {
  213. return this.sharedPickState.messages.findIndex(m => m.messageId === this.message.messageId) >= 0;
  214. }
  215. },
  216. }
  217. </script>
  218. <style lang="css" scoped>
  219. .message-time-container {
  220. width: 100%;
  221. display: flex;
  222. flex-direction: column;
  223. align-items: flex-end;
  224. }
  225. .message-time-container.checked {
  226. background-color: #e7e7e7;
  227. }
  228. .message-time-container .time {
  229. width: 100%;
  230. margin-bottom: 20px;
  231. text-align: center;
  232. color: #b4b4b4;
  233. font-size: 10px;
  234. background-color: #f3f3f3;
  235. }
  236. .message-time-container .receipt {
  237. margin-right: 70px;
  238. font-size: 12px;
  239. margin-top: -10px;
  240. color: #b4b4b4;
  241. }
  242. .message-content-container {
  243. width: 100%;
  244. display: flex;
  245. padding: 10px 20px;
  246. justify-content: space-between;
  247. align-items: center;
  248. position: relative;
  249. }
  250. .message-avatar-content-container {
  251. display: flex;
  252. max-width: calc(100% - 60px);
  253. overflow: hidden;
  254. /*max-height: 800px;*/
  255. margin-left: auto;
  256. text-overflow: ellipsis;
  257. align-items: flex-start;
  258. }
  259. .message-avatar-content-container .avatar {
  260. width: 40px;
  261. height: 40px;
  262. border-radius: 3px;
  263. }
  264. .message-content-container-view.highlight {
  265. background-color: #dadada;
  266. opacity: 0.5;
  267. --out-arrow-color: #dadada !important;
  268. }
  269. </style>