index.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <template>
  2. <view class="page_container">
  3. <custom-nav-bar title="通话记录" />
  4. <u-tabs class="top_tab" :scrollable="false" :list="tabList" @click="clickTab"></u-tabs>
  5. <view class="pane_row" :style="{ transform: `translateX(${isAll ? '0' : '-100%'})` }">
  6. <view class="pane_content">
  7. <u-list :height="`${listHeight}px`" lowerThreshold="100" v-if="allList.length > 0" class="member_list">
  8. <u-list-item v-for="item in allList" :key="item.roomID">
  9. <view class="user_item" :style="{ color: item.duration > 0 ? '' : '#FF381F' }"
  10. @click="rtcInvitePrepare(item.isSelf ? item.inviteeUserIDList[0] : item.inviterUserID)">
  11. <my-avatar :src="item.faceURL" :desc="item.nickname" :isGroup="false" size="42" />
  12. <view class="details">
  13. <text style="font-size: 34rpx;">{{ item.nickname }}</text>
  14. <text
  15. :style="{ marginTop: '4rpx', color: item.duration > 0 ? '#8E9AB0' : '#FF381F', fontSize: '28rpx' }">{{
  16. item.mediaType === "video" ? '[视频通话]' :
  17. '[语音通话]' }}{{ latestMessageTime(item.time) }}</text>
  18. </view>
  19. <text class="type" v-if="item.duration === 0">{{ item.isSelf ? '呼出' : '呼入' }}</text>
  20. <text class="type" v-else>{{ toSecFormat(item.duration) }}</text>
  21. </view>
  22. </u-list-item>
  23. </u-list>
  24. <u-empty v-else mode="list" />
  25. </view>
  26. <view class="pane_content">
  27. <u-list :height="`${listHeight}px`" lowerThreshold="100" v-if="blockList.length > 0" class="member_list">
  28. <u-list-item v-for="item in blockList" :key="item.roomID">
  29. <view class="user_item" :style="{ color: item.duration > 0 ? '' : '#FF381F' }"
  30. @click="rtcInvitePrepare(item.isSelf ? item.inviteeUserIDList[0] : item.inviterUserID)">
  31. <my-avatar :src="item.faceURL" :desc="item.nickname" :isGroup="false" size="42" />
  32. <view class="details">
  33. <text style="font-size: 34rpx;">{{ item.nickname }}</text>
  34. <text
  35. :style="{ marginTop: '4rpx', color: item.duration > 0 ? '#8E9AB0' : '#FF381F', fontSize: '28rpx' }">{{
  36. item.mediaType === "video" ? '[视频通话]' :
  37. '[语音通话]' }}{{ latestMessageTime(item.time) }}</text>
  38. </view>
  39. <text class="type" v-if="item.duration === 0">{{ item.isSelf ? '呼出' : '呼入' }}</text>
  40. <text class="type" v-else>{{ toSecFormat(item.duration) }}</text>
  41. </view>
  42. </u-list-item>
  43. </u-list>
  44. <u-empty v-else mode="list" />
  45. </view>
  46. </view>
  47. </view>
  48. </template>
  49. <script>
  50. import { mapGetters } from "vuex";
  51. import {
  52. callingModule,
  53. secFormat
  54. } from "../../../util/imCommon";
  55. import {
  56. formatConversionTime,
  57. } from "../../../util/imCommon";
  58. import CustomNavBar from "../../../components/CustomNavBar/index.vue";
  59. import MyAvatar from "../../../components/MyAvatar/index.vue";
  60. export default {
  61. components: {
  62. CustomNavBar,
  63. MyAvatar,
  64. },
  65. computed: {
  66. ...mapGetters([
  67. "storeFriendList",
  68. ]),
  69. latestMessageTime() {
  70. return function (time) {
  71. return formatConversionTime(time)
  72. }
  73. },
  74. toSecFormat() {
  75. return function (time) {
  76. return secFormat(time)
  77. }
  78. },
  79. },
  80. data() {
  81. return {
  82. allList: [],
  83. blockList: [],
  84. isAll: true,
  85. tabList: [
  86. {
  87. name: "所有通话",
  88. },
  89. {
  90. name: "未接来电",
  91. },
  92. ],
  93. listHeight:
  94. uni.getWindowInfo().windowHeight -
  95. uni.getWindowInfo().statusBarHeight -
  96. 110,
  97. };
  98. },
  99. onShow() {
  100. this.getNativeCallList();
  101. },
  102. methods: {
  103. clickTab({ index }) {
  104. this.isAll = index === 0;
  105. },
  106. chooseCallMediaType() {
  107. return new Promise((resolve, reject) => {
  108. uni.showActionSheet({
  109. itemList: ["语音通话", "视频通话"],
  110. success: ({ tapIndex }) => {
  111. resolve(tapIndex ? "video" : "audio");
  112. },
  113. fail: () => reject(),
  114. });
  115. });
  116. },
  117. sendRtcInvite(mediaType, userID) {
  118. const isVideo = mediaType === "video";
  119. callingModule.startLiveChat(
  120. isVideo,
  121. [userID],
  122. "",
  123. this.$store.getters.storeCurrentUserID,
  124. );
  125. },
  126. rtcInvitePrepare(userID) {
  127. this.chooseCallMediaType()
  128. .then((callMediaType) => {
  129. this.sendRtcInvite(callMediaType, userID);
  130. });
  131. },
  132. getUserInfo(userID, storeFriendList) {
  133. const friend = storeFriendList.find((friend) => friend.userID === userID);
  134. return {
  135. nickname: friend.nickname,
  136. faceURL: friend.faceURL,
  137. }
  138. },
  139. mapNativeCalls(nativeCallList, storeFriendList) {
  140. return nativeCallList.map((item) => {
  141. const userInfo = item.isSelf
  142. ? this.getUserInfo(item.inviteeUserIDList[0], storeFriendList)
  143. : this.getUserInfo(item.inviterUserID, storeFriendList);
  144. return { ...item, ...userInfo };
  145. });
  146. },
  147. getNativeCallList() {
  148. const nativeCallList = uni.getStorageSync(`${this.$store.getters.storeCurrentUserID}_nativecall`) || [];
  149. this.allList = this.mapNativeCalls(nativeCallList, this.storeFriendList);
  150. this.blockList = this.mapNativeCalls(nativeCallList, this.storeFriendList).filter((item) => item.duration === 0);
  151. }
  152. },
  153. };
  154. </script>
  155. <style lang="scss">
  156. .page_container {
  157. background-color: #f8f8f8;
  158. overflow-x: hidden;
  159. .u-tabs {
  160. background-color: #fff;
  161. // margin-bottom: 12px;
  162. }
  163. .pane_row {
  164. display: flex;
  165. transition: all 0.3s ease 0s !important;
  166. .pane_content {
  167. @include colBox(false);
  168. height: 100%;
  169. flex: 0 0 100%;
  170. .user_item {
  171. @include vCenterBox();
  172. padding: 24rpx;
  173. color: $uni-text-color;
  174. .details {
  175. @include vCenterBox();
  176. display: flex;
  177. flex-direction: column;
  178. justify-content: space-between;
  179. align-items: flex-start;
  180. margin-left: 12rpx;
  181. width: 75%;
  182. }
  183. .type {
  184. font-size: 28rpx;
  185. margin-right: 12rpx;
  186. }
  187. }
  188. /deep/.user_item {
  189. background-color: #fff;
  190. }
  191. }
  192. }
  193. .u-empty {
  194. margin-top: 20vh !important;
  195. }
  196. }
  197. </style>