tuikit-atomicx-vue3 3.3.0-beta.3 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/dist/AttachmentPicker.module-BesmtGyl.js +11 -0
  2. package/dist/FilePicker.vue_vue_type_script_setup_true_lang-CdJ4DUzE.js +76 -0
  3. package/dist/ImagePicker.vue_vue_type_script_setup_true_lang-CbNUofpK.js +76 -0
  4. package/dist/{MessageInput.vue_vue_type_script_setup_true_lang-XRL7A5Gj.js → MessageInput.vue_vue_type_script_setup_true_lang-wUJPjWbx.js} +23 -18
  5. package/dist/VideoPicker.vue_vue_type_script_setup_true_lang-CmxjbNDJ.js +76 -0
  6. package/dist/chat/index.d.ts +3747 -2386
  7. package/dist/chat/index.js +12 -11
  8. package/dist/components/BarrageInput/BarrageInputH5.js +32 -8
  9. package/dist/components/BarrageInput/EmojiPicker/EmojiPicker.js +9 -5
  10. package/dist/components/BarrageInput/TextEditor/index.js +14 -6
  11. package/dist/components/BarrageList/Message/GroupTipMessage/GroupTipMessage.vue.d.ts +4 -4
  12. package/dist/components/BarrageList/Message/TextMessage/TextMessage.js +12 -4
  13. package/dist/components/BarrageList/i18n/en-US/index.d.ts +1 -0
  14. package/dist/components/BarrageList/i18n/en-US/index.js +2 -1
  15. package/dist/components/BarrageList/i18n/zh-CN/index.d.ts +1 -0
  16. package/dist/components/BarrageList/i18n/zh-CN/index.js +2 -1
  17. package/dist/components/ChatSetting/GroupChatSetting/GroupActions/GroupActions.js +5 -3
  18. package/dist/components/ChatSetting/GroupChatSetting/GroupChatSetting.js +3 -3
  19. package/dist/components/ChatSetting/GroupChatSetting/GroupInfo/GroupInfo.js +3 -3
  20. package/dist/components/ChatSetting/GroupChatSetting/GroupManagement/GroupManagement.js +3 -3
  21. package/dist/components/ChatSetting/GroupChatSetting/GroupMembers/GroupMembers.js +3 -3
  22. package/dist/components/ChatSetting/SettingItem/SettingItem.js +21 -21
  23. package/dist/components/ChatSetting/i18n/en-US.js +3 -3
  24. package/dist/components/ChatSetting/i18n/zh-CN.js +3 -3
  25. package/dist/components/ChatSetting/index.d.ts +1 -4
  26. package/dist/components/ChatSetting/index.js +3 -6
  27. package/dist/components/CoGuestPanel/CoGuestPanel.js +1 -1
  28. package/dist/components/ContactList/ContactInfo/ContactInfo.js +17 -17
  29. package/dist/components/ContactList/ContactInfo/ContactInfo.vue.d.ts +26 -2
  30. package/dist/components/ContactList/ContactInfo/GroupInfo/GroupInfo.js +2 -1
  31. package/dist/components/ContactList/ContactList.js +19 -10
  32. package/dist/components/ContactList/ContactList.vue.d.ts +109 -1
  33. package/dist/components/ContactList/index.d.ts +158 -26
  34. package/dist/components/ConversationList/ConversationActions/ConversationActions.js +8 -9
  35. package/dist/components/ConversationList/ConversationCreate/ConversationCreate.js +2 -1
  36. package/dist/components/ConversationList/ConversationCreate/ConversationCreateGroupDetail/ConversationCreateGroupDetail.js +8 -8
  37. package/dist/components/ConversationList/ConversationCreate/ConversationCreateUserSelectList/ConversationCreateUserSelectList.js +1 -2
  38. package/dist/components/ConversationList/ConversationCreate/ConversationGroupTypeInfo/ConversationGroupTypeInfo.js +8 -8
  39. package/dist/components/ConversationList/ConversationList.js +18 -44
  40. package/dist/components/ConversationList/ConversationList.vue.d.ts +197 -1535
  41. package/dist/components/ConversationList/ConversationListContent/ConversationListContent.js +8 -11
  42. package/dist/components/ConversationList/ConversationListContent/ConversationListContent.vue.d.ts +22 -340
  43. package/dist/components/ConversationList/ConversationPreview/ConversationPreview.vue.d.ts +80 -134
  44. package/dist/components/ConversationList/ConversationPreview/ConversationPreviewAbstract.js +14 -14
  45. package/dist/components/ConversationList/ConversationPreview/ConversationPreviewTimestamp.js +14 -14
  46. package/dist/components/ConversationList/ConversationPreview/ConversationPreviewTitle.js +19 -30
  47. package/dist/components/ConversationList/ConversationPreview/ConversationPreviewTitle.vue.d.ts +0 -2
  48. package/dist/components/ConversationList/ConversationPreview/ConversationPreviewUI.js +14 -15
  49. package/dist/components/ConversationList/ConversationPreview/ConversationPreviewUI.vue.d.ts +12 -24
  50. package/dist/components/ConversationList/ConversationPreview/ConversationPreviewUnread.js +14 -14
  51. package/dist/components/ConversationList/ConversationPreview/index.d.ts +1 -1
  52. package/dist/components/ConversationList/ConversationPreview/index.js +17 -21
  53. package/dist/components/ConversationList/ConversationSearch/ConversationSearch.js +1 -0
  54. package/dist/components/ConversationList/index.d.ts +468 -2400
  55. package/dist/components/ConversationList/index.js +1 -1
  56. package/dist/components/LiveCoreView/index.js +113 -58
  57. package/dist/components/LiveCoreView/index.vue.d.ts +9 -0
  58. package/dist/components/LiveList/LiveList.js +7 -5
  59. package/dist/components/LiveList/LiveListH5.js +77 -71
  60. package/dist/components/LiveList/i18n/en-US/index.d.ts +5 -0
  61. package/dist/components/LiveList/i18n/en-US/index.js +6 -1
  62. package/dist/components/LiveList/i18n/zh-CN/index.d.ts +5 -0
  63. package/dist/components/LiveList/i18n/zh-CN/index.js +6 -1
  64. package/dist/components/LiveList/pullToRefresh.js +204 -0
  65. package/dist/components/LiveList/pullToRefresh.vue.d.ts +86 -0
  66. package/dist/components/LiveScenePanel/CameraSettingDialog.js +6 -5
  67. package/dist/components/LiveScenePanel/index.js +3 -3
  68. package/dist/components/MessageInput/AttachmentPicker/AttachmentPicker.vue.d.ts +0 -4
  69. package/dist/components/MessageInput/AttachmentPicker/FilePicker.js +1 -1
  70. package/dist/components/MessageInput/AttachmentPicker/ImagePicker.js +1 -1
  71. package/dist/components/MessageInput/AttachmentPicker/VideoPicker.js +1 -1
  72. package/dist/components/MessageInput/AttachmentPicker/index.js +14 -19
  73. package/dist/components/MessageInput/EmojiPicker/EmojiPicker.js +3 -3
  74. package/dist/components/MessageInput/MessageInput.js +1 -1
  75. package/dist/components/MessageInput/MessageInput.vue.d.ts +6 -9
  76. package/dist/components/MessageInput/TextEditor/TextEditor.vue.d.ts +2 -2
  77. package/dist/components/MessageInput/TextEditor/index.js +18 -9
  78. package/dist/components/MessageInput/index.d.ts +5 -41
  79. package/dist/components/MessageInput/index.js +4 -4
  80. package/dist/components/MessageList/Message/CustomMessage/index.js +2 -2
  81. package/dist/components/MessageList/Message/FaceMessage/FaceMessage.js +7 -5
  82. package/dist/components/MessageList/Message/FaceMessage/FaceMessage.vue.d.ts +8 -8
  83. package/dist/components/MessageList/Message/LocationMessage/LocationMessage.js +2 -1
  84. package/dist/components/MessageList/Message/MergerMessage/MergerMessage.js +2 -1
  85. package/dist/components/MessageList/Message/MessageLayout/MessageActionDropdown/MessageActionDropdown.js +12 -4
  86. package/dist/components/MessageList/Message/MessageLayout/MessageActionDropdown/MessageActionDropdown.vue.d.ts +3 -3
  87. package/dist/components/MessageList/MessageForward/MessageForward.js +2 -3
  88. package/dist/components/MessageList/MessageList.js +14 -7
  89. package/dist/components/MessageList/MessageList.vue.d.ts +1 -1
  90. package/dist/components/MessageList/MessageTimeDivider/MessageTimeDivider.js +5 -5
  91. package/dist/components/MessageList/MessageTimeDivider/MessageTimeDivider.vue.d.ts +10 -10
  92. package/dist/components/MessageList/index.d.ts +143 -5
  93. package/dist/components/MessageList/index.js +5 -5
  94. package/dist/components/Search/Search.js +1 -3
  95. package/dist/components/Search/SearchResults/EmptyResult/EmptyResult.js +4 -6
  96. package/dist/components/Search/SearchResults/Loading/Loading.js +2 -4
  97. package/dist/components/Search/SearchResults/SearchResults.js +20 -22
  98. package/dist/components/Search/SearchResults/SearchResultsItem/Conversation/Conversation.js +6 -8
  99. package/dist/components/Search/SearchResults/SearchResultsItem/Group/Group.js +5 -7
  100. package/dist/components/Search/SearchResults/SearchResultsItem/Message/Message.js +19 -21
  101. package/dist/components/Search/SearchResults/SearchResultsItem/SearchResultsItem.js +1 -3
  102. package/dist/components/Search/SearchResults/SearchResultsItem/User/User.js +5 -7
  103. package/dist/components/StreamMixer/LocalMixer/index.js +11 -5
  104. package/dist/components/StreamView/manager/mediaManager.js +1 -1
  105. package/dist/components/UserPicker/UserPicker.js +2 -2
  106. package/dist/components/UserPicker/UserPicker.vue.d.ts +7 -8
  107. package/dist/components/UserPicker/components/ListMode/ListMode.js +14 -17
  108. package/dist/components/UserPicker/components/ListMode/ListMode.vue.d.ts +2 -2
  109. package/dist/components/UserPicker/components/SelectedPanel/SelectedPanel.vue.d.ts +2 -2
  110. package/dist/components/UserPicker/components/TreeMode/TreeMode.vue.d.ts +3 -3
  111. package/dist/components/UserPicker/components/TreeMode/TreeNode.vue.d.ts +4 -4
  112. package/dist/components/UserPicker/hooks/useSearchFilter.d.ts +3 -3
  113. package/dist/components/UserPicker/hooks/useSelection.d.ts +8 -8
  114. package/dist/components/UserPicker/hooks/useTreeState.d.ts +3 -3
  115. package/dist/components/UserPicker/index.d.ts +134 -3
  116. package/dist/components/UserPicker/index.js +3 -2
  117. package/dist/components/UserPicker/type.d.ts +18 -18
  118. package/dist/index.js +6 -3
  119. package/dist/rtc/index.d.ts +9 -0
  120. package/dist/states/GroupSettingState/GroupSettingState.js +3 -3
  121. package/dist/states/LiveSeatState/usePlayStream/MixStreamPlayer.js +3 -0
  122. package/dist/states/LoginState.js +1 -0
  123. package/dist/states/MessageInputState/MessageInputState.js +25 -5
  124. package/dist/styles/index.css +1275 -3559
  125. package/dist/types/contact.d.ts +13 -12
  126. package/dist/types/conversation.d.ts +12 -14
  127. package/dist/types/engine.d.ts +12 -0
  128. package/dist/types/engine.js +15 -0
  129. package/dist/types/index.js +2 -1
  130. package/dist/utils/json.js +0 -1
  131. package/package.json +7 -3
  132. package/src/chat/index.ts +12 -4
  133. package/src/components/BarrageInput/BarrageInputH5.vue +50 -4
  134. package/src/components/BarrageInput/EmojiPicker/EmojiPicker.module.scss +1 -0
  135. package/src/components/BarrageInput/EmojiPicker/EmojiPicker.vue +1 -1
  136. package/src/components/BarrageInput/TextEditor/Editor.scss +1 -1
  137. package/src/components/BarrageInput/TextEditor/TextEditor.module.scss +2 -0
  138. package/src/components/BarrageInput/TextEditor/TextEditor.vue +6 -0
  139. package/src/components/BarrageList/Message/GroupTipMessage/GroupTipMessage.vue +8 -8
  140. package/src/components/BarrageList/Message/TextMessage/TextMessage.vue +10 -0
  141. package/src/components/BarrageList/i18n/en-US/index.ts +1 -0
  142. package/src/components/BarrageList/i18n/zh-CN/index.ts +1 -0
  143. package/src/components/ChatSetting/GroupChatSetting/GroupActions/GroupActions.vue +5 -2
  144. package/src/components/ChatSetting/GroupChatSetting/GroupChatSetting.vue +5 -4
  145. package/src/components/ChatSetting/GroupChatSetting/GroupInfo/GroupInfo.vue +2 -2
  146. package/src/components/ChatSetting/GroupChatSetting/GroupManagement/GroupManagement.vue +3 -2
  147. package/src/components/ChatSetting/GroupChatSetting/GroupMembers/GroupMembers.vue +3 -3
  148. package/src/components/ChatSetting/SettingItem/SettingItem.vue +10 -7
  149. package/src/components/ChatSetting/i18n/en-US.ts +3 -3
  150. package/src/components/ChatSetting/i18n/zh-CN.ts +3 -3
  151. package/src/components/ChatSetting/index.ts +3 -3
  152. package/src/components/CoGuestPanel/CoGuestPanel.vue +9 -0
  153. package/src/components/ContactList/ContactInfo/BlacklistInfo/BlacklistInfo.scss +2 -0
  154. package/src/components/ContactList/ContactInfo/ContactInfo.vue +17 -9
  155. package/src/components/ContactList/ContactInfo/FriendApplicationInfo/FriendApplicationInfo.scss +2 -0
  156. package/src/components/ContactList/ContactInfo/FriendInfo/FriendInfo.scss +4 -3
  157. package/src/components/ContactList/ContactInfo/GroupApplicationInfo/GroupApplicationInfo.scss +2 -0
  158. package/src/components/ContactList/ContactInfo/GroupInfo/GroupInfo.scss +2 -0
  159. package/src/components/ContactList/ContactInfo/GroupInfo/GroupInfo.vue +1 -0
  160. package/src/components/ContactList/ContactInfo/SearchGroupInfo/SearchGroupInfo.scss +2 -2
  161. package/src/components/ContactList/ContactInfo/SearchUserInfo/SearchUserInfo.scss +3 -2
  162. package/src/components/ContactList/ContactList.scss +2 -1
  163. package/src/components/ContactList/ContactList.vue +18 -3
  164. package/src/components/ContactList/ContactListItem/BlacklistItem/BlacklistItem.scss +3 -3
  165. package/src/components/ContactList/ContactListItem/FriendApplicationItem/FriendApplicationItem.scss +5 -6
  166. package/src/components/ContactList/ContactListItem/FriendItem/FriendItem.scss +3 -3
  167. package/src/components/ContactList/ContactListItem/GroupApplicationItem/GroupApplicationItem.scss +5 -6
  168. package/src/components/ContactList/ContactListItem/GroupItem/GroupItem.scss +3 -3
  169. package/src/components/ConversationList/ConversationActions/ConversationActions.scss +2 -12
  170. package/src/components/ConversationList/ConversationActions/ConversationActions.vue +2 -2
  171. package/src/components/ConversationList/ConversationCreate/ConversationCreate.vue +1 -0
  172. package/src/components/ConversationList/ConversationCreate/ConversationCreateGroupDetail/ConversationCreateGroupDetail.scss +2 -1
  173. package/src/components/ConversationList/ConversationCreate/ConversationCreateUserSelectList/ConversationCreateUserSelectList.vue +2 -2
  174. package/src/components/ConversationList/ConversationCreate/ConversationGroupTypeInfo/ConversationGroupTypeInfo.scss +2 -1
  175. package/src/components/ConversationList/ConversationList.scss +0 -5
  176. package/src/components/ConversationList/ConversationList.vue +15 -41
  177. package/src/components/ConversationList/ConversationListContent/ConversationListContent.scss +1 -0
  178. package/src/components/ConversationList/ConversationListContent/ConversationListContent.vue +13 -18
  179. package/src/components/ConversationList/ConversationPreview/ConversationPreview.scss +11 -9
  180. package/src/components/ConversationList/ConversationPreview/ConversationPreview.vue +14 -16
  181. package/src/components/ConversationList/ConversationPreview/ConversationPreviewTitle.vue +2 -14
  182. package/src/components/ConversationList/ConversationPreview/index.ts +1 -1
  183. package/src/components/ConversationList/ConversationSearch/ConversationSearch.vue +1 -0
  184. package/src/components/LiveCoreView/index.vue +144 -78
  185. package/src/components/LiveList/LiveList.vue +3 -0
  186. package/src/components/LiveList/LiveListH5.vue +60 -85
  187. package/src/components/LiveList/i18n/en-US/index.ts +5 -0
  188. package/src/components/LiveList/i18n/zh-CN/index.ts +5 -0
  189. package/src/components/LiveList/pullToRefresh.vue +364 -0
  190. package/src/components/LiveScenePanel/CameraSettingDialog.vue +6 -5
  191. package/src/components/LiveScenePanel/index.vue +2 -2
  192. package/src/components/MessageInput/AttachmentPicker/AttachmentPicker.module.scss +4 -0
  193. package/src/components/MessageInput/AttachmentPicker/AttachmentPicker.vue +12 -17
  194. package/src/components/MessageInput/AttachmentPicker/FilePicker.vue +3 -2
  195. package/src/components/MessageInput/AttachmentPicker/ImagePicker.vue +3 -2
  196. package/src/components/MessageInput/AttachmentPicker/VideoPicker.vue +3 -2
  197. package/src/components/MessageInput/EmojiPicker/EmojiPicker.module.scss +1 -0
  198. package/src/components/MessageInput/MessageInput.vue +21 -15
  199. package/src/components/MessageInput/TextEditor/Editor.scss +1 -0
  200. package/src/components/MessageInput/TextEditor/TextEditor.vue +16 -6
  201. package/src/components/MessageInput/types.d.ts +3 -4
  202. package/src/components/MessageList/Message/CustomMessage/CustomMessage.vue +1 -1
  203. package/src/components/MessageList/Message/FaceMessage/FaceMessage.vue +10 -7
  204. package/src/components/MessageList/Message/LocationMessage/LocationMessage.vue +3 -1
  205. package/src/components/MessageList/Message/MergerMessage/MergerMessage.vue +1 -1
  206. package/src/components/MessageList/Message/MessageLayout/MessageActionDropdown/MessageActionDropdown.vue +2 -2
  207. package/src/components/MessageList/MessageForward/MessageForward.vue +3 -3
  208. package/src/components/MessageList/MessageList.vue +17 -5
  209. package/src/components/MessageList/MessageTimeDivider/MessageTimeDivider.vue +9 -9
  210. package/src/components/MessageList/index.ts +5 -4
  211. package/src/components/Search/Search.scss +0 -3
  212. package/src/components/Search/SearchResults/EmptyResult/EmptyResult.scss +0 -3
  213. package/src/components/Search/SearchResults/Loading/Loading.scss +0 -3
  214. package/src/components/Search/SearchResults/SearchResults.scss +7 -16
  215. package/src/components/Search/SearchResults/SearchResultsItem/Conversation/Conversation.scss +5 -11
  216. package/src/components/Search/SearchResults/SearchResultsItem/Group/Group.scss +5 -11
  217. package/src/components/Search/SearchResults/SearchResultsItem/Message/Message.scss +5 -11
  218. package/src/components/Search/SearchResults/SearchResultsItem/SearchResultsItem.scss +0 -3
  219. package/src/components/Search/SearchResults/SearchResultsItem/User/User.scss +5 -6
  220. package/src/components/StreamMixer/LocalMixer/index.vue +9 -4
  221. package/src/components/StreamView/manager/mediaManager.ts +1 -1
  222. package/src/components/UserPicker/UserPicker.vue +6 -9
  223. package/src/components/UserPicker/components/ListMode/ListMode.vue +3 -7
  224. package/src/components/UserPicker/components/SelectedPanel/SelectedPanel.vue +2 -2
  225. package/src/components/UserPicker/components/TreeMode/TreeMode.vue +3 -3
  226. package/src/components/UserPicker/components/TreeMode/TreeNode.vue +3 -3
  227. package/src/components/UserPicker/hooks/useSearchFilter.ts +15 -14
  228. package/src/components/UserPicker/hooks/useSelection.ts +32 -32
  229. package/src/components/UserPicker/hooks/useTreeState.ts +4 -4
  230. package/src/components/UserPicker/index.ts +16 -14
  231. package/src/components/UserPicker/type.ts +18 -18
  232. package/src/types/contact.ts +13 -12
  233. package/src/types/conversation.ts +12 -14
  234. package/src/types/engine.ts +15 -0
  235. package/src/utils/json.ts +0 -4
  236. package/dist/AttachmentPicker.module-0_DWsAtr.js +0 -11
  237. package/dist/FilePicker.vue_vue_type_script_setup_true_lang-CaSj3Gh_.js +0 -72
  238. package/dist/ImagePicker.vue_vue_type_script_setup_true_lang-CrzGMmrh.js +0 -72
  239. package/dist/VideoPicker.vue_vue_type_script_setup_true_lang-DTv6TJKr.js +0 -72
  240. package/dist/states/UIOpenControlState/UIOpenControlState.d.ts +0 -15
  241. package/dist/states/UIOpenControlState/UIOpenControlState.js +0 -28
  242. package/dist/states/UIOpenControlState/index.d.ts +0 -1
  243. package/dist/states/UIOpenControlState/index.js +0 -4
@@ -111,6 +111,8 @@ watch(
111
111
  async (user) => {
112
112
  if (user && user.userId) {
113
113
  isLoadingMore.value = true;
114
+ currentCursor.value = '';
115
+ liveList.value.length = 0;
114
116
  await fetchLiveList({});
115
117
  isLoadingMore.value = false;
116
118
  }
@@ -296,6 +298,7 @@ $text-color3: var(--text-color-tertiary);
296
298
 
297
299
  .right {
298
300
  display: flex;
301
+ align-items: center;
299
302
  float: right;
300
303
  margin-right: 10px;
301
304
  gap: 2px;
@@ -1,64 +1,52 @@
1
1
  <template>
2
- <div
3
- v-if="loginUserInfo"
4
- class="live-list-panel-h5"
5
- >
2
+ <div v-if="loginUserInfo" class="live-list-panel-h5">
6
3
  <div
7
- v-if="liveList.length > 0"
4
+ v-if="showLiveList.length > 0"
8
5
  ref="scrollContainerRef"
9
6
  class="live-list"
10
- @scroll="handleScroll"
11
- @wheel="handleWheel"
12
7
  >
13
- <div class="live-list-items">
14
- <div
15
- v-for="item in liveList"
16
- :key="item.liveId"
17
- class="live-item"
18
- @click="liveRoomClick(item)"
19
- >
20
- <div class="live-room-cover">
21
- <div class="header">
22
- <IconLiveCoverHeader :size="10" />
23
- <span class="viewer-count"> {{ item.currentViewerCount || 0 }} </span>
24
- <span> {{ t('people have watched the live') }} </span>
8
+ <PullToRefresh
9
+ :text="{
10
+ pull: t('Pull to refresh'),
11
+ release: t('Release to refresh'),
12
+ loading: t('Loading'),
13
+ success: t('Refresh success'),
14
+ error: t('Refresh failed'),
15
+ }"
16
+ @refresh="handleRefresh"
17
+ @load-more="fetchMoreLives"
18
+ >
19
+ <div class="live-list-items">
20
+ <div v-for="item in showLiveList" :key="item.liveId" class="live-item" @click="liveRoomClick(item)">
21
+ <div class="live-room-cover">
22
+ <div class="header">
23
+ <IconLiveCoverHeader :size="10" />
24
+ <span class="viewer-count"> {{ item.currentViewerCount || 0 }} </span>
25
+ <span> {{ t('people have watched the live') }} </span>
26
+ </div>
27
+ <img :src="item.coverUrl || DEFAULT_COVER" alt="" @error="handleCoverImageError" />
28
+ </div>
29
+ <span class="live-name">{{ item.liveName }} </span>
30
+ <div class="owner-info">
31
+ <Avatar
32
+ :src="item.liveOwner.avatarUrl"
33
+ :size="16"
34
+ :style="{ border: '1px solid var(--uikit-color-white-7)' }"
35
+ />
36
+ <span class="owner-name">{{ item.liveOwner.userName || item.liveOwner.userId }} </span>
25
37
  </div>
26
- <img
27
- :src="item.coverUrl || DEFAULT_COVER"
28
- alt=""
29
- @error="handleCoverImageError"
30
- >
31
- </div>
32
- <span class="live-name">{{ item.liveName }} </span>
33
- <div class="owner-info">
34
- <Avatar
35
- :src="item.liveOwner.avatarUrl"
36
- :size="16"
37
- :style="{ border: '1px solid var(--uikit-color-white-7)' }"
38
- />
39
- <span class="owner-name">{{ item.liveOwner.userName || item.liveOwner.userId }} </span>
40
38
  </div>
41
39
  </div>
42
- </div>
43
- <div
44
- v-if="!hasMoreLive"
45
- class="bottom-text-no-more"
46
- >
47
- <span>{{ t('No More') }}</span>
48
- </div>
40
+ <div v-if="!hasMoreLive" class="bottom-text-no-more">
41
+ <span>{{ t('No More') }}</span>
42
+ </div>
43
+ </PullToRefresh>
49
44
  </div>
50
- <div
51
- v-else-if="!isLoadingMore"
52
- class="no-live"
53
- >
45
+ <div v-else-if="!isLoadingMore" class="no-live">
54
46
  <IconNoLiveRoom :size="60" />
55
47
  <span>{{ t('No Live') }}</span>
56
48
  </div>
57
- <div
58
- v-if="liveList.length > 0 && (isShowMoreVisible || isLoadingMore)"
59
- class="bottom-text"
60
- >
61
- <span v-if="isShowMoreVisible">{{ t('Load More') }}</span>
49
+ <div v-if="liveList.length > 0 && isLoadingMore" class="bottom-text">
62
50
  <span v-if="isLoadingMore">{{ t('Loading...') }}</span>
63
51
  </div>
64
52
  </div>
@@ -71,10 +59,12 @@ import { useLiveState } from '../../states/LiveState';
71
59
  import { useLoginState } from '../../states/LoginState';
72
60
  import { Avatar } from '../Avatar';
73
61
  import type { LiveInfo } from '../../types';
62
+ import PullToRefresh from './pullToRefresh.vue';
74
63
 
75
64
  const { liveList, currentCursor, fetchLiveList } = useLiveState();
76
65
  const { loginUserInfo } = useLoginState();
77
66
  const { t } = useUIKit();
67
+ const showLiveList = ref<LiveInfo[]>([]);
78
68
 
79
69
  const DEFAULT_COVER = 'https://liteav-test-1252463788.cos.ap-guangzhou.myqcloud.com/voice_room/voice_room_cover1.png';
80
70
  const scrollContainerRef = ref<HTMLElement | null>(null);
@@ -85,24 +75,23 @@ const hasMoreLive = computed(() => currentCursor.value !== '');
85
75
  const liveItemWidth = ref('168px');
86
76
  const liveItemHeight = ref('262px');
87
77
 
88
- const shouldFetchMoreLiveList = computed(() => hasMoreLive.value && !isLoadingMore.value);
89
-
90
- const isShowMoreVisible = computed(() => shouldFetchMoreLiveList.value && !scrollContainerRef.value);
91
-
92
78
  const emit = defineEmits<{
93
79
  (e: 'live-room-click', liveInfo: LiveInfo): void;
94
80
  }>();
95
81
 
96
82
  watch(
97
83
  loginUserInfo,
98
- async (user) => {
84
+ async user => {
99
85
  if (user && user.userId) {
100
86
  isLoadingMore.value = true;
87
+ currentCursor.value = '';
88
+ liveList.value.length = 0;
101
89
  await fetchLiveList({});
90
+ showLiveList.value = liveList.value.slice();
102
91
  isLoadingMore.value = false;
103
92
  }
104
93
  },
105
- { immediate: true },
94
+ { immediate: true }
106
95
  );
107
96
 
108
97
  watch(scrollContainerRef, () => {
@@ -117,39 +106,23 @@ watch(scrollContainerRef, () => {
117
106
  }
118
107
  });
119
108
 
120
- function liveRoomClick(liveInfo: LiveInfo) {
121
- console.log('liveRoomClick,liveInfo:', liveInfo);
122
- emit('live-room-click', liveInfo);
123
- }
124
-
125
- function isScrollAtBottom(threshold = 50) {
126
- if (!scrollContainerRef.value) {
127
- return false;
128
- }
129
- return (
130
- scrollContainerRef.value.scrollTop + scrollContainerRef.value.clientHeight
131
- >= scrollContainerRef.value.scrollHeight - threshold
132
- );
133
- }
134
-
135
- function handleWheel(event: WheelEvent) {
136
- if (!scrollContainerRef.value) {
137
- return;
138
- }
139
-
140
- if (event.deltaY > 0 && isScrollAtBottom() && shouldFetchMoreLiveList.value) {
141
- fetchMoreLives();
109
+ async function handleRefresh(completeRefresh: (success?: boolean) => void) {
110
+ try {
111
+ isLoadingMore.value = true;
112
+ currentCursor.value = '';
113
+ liveList.value.length = 0;
114
+ await fetchLiveList({});
115
+ showLiveList.value = liveList.value.slice();
116
+ isLoadingMore.value = false;
117
+ completeRefresh(true);
118
+ } catch (error) {
119
+ completeRefresh(false);
142
120
  }
143
121
  }
144
122
 
145
- function handleScroll() {
146
- if (!scrollContainerRef.value) {
147
- return;
148
- }
149
-
150
- if (isScrollAtBottom() && shouldFetchMoreLiveList.value) {
151
- fetchMoreLives();
152
- }
123
+ function liveRoomClick(liveInfo: LiveInfo) {
124
+ console.log('liveRoomClick,liveInfo:', liveInfo);
125
+ emit('live-room-click', liveInfo);
153
126
  }
154
127
 
155
128
  async function fetchMoreLives() {
@@ -159,6 +132,7 @@ async function fetchMoreLives() {
159
132
  try {
160
133
  isLoadingMore.value = true;
161
134
  await fetchLiveList({ cursor: currentCursor.value });
135
+ showLiveList.value = liveList.value.slice();
162
136
  } finally {
163
137
  isLoadingMore.value = false;
164
138
  }
@@ -329,6 +303,7 @@ $text-color3: var(--text-color-tertiary);
329
303
  .bottom-text-no-more {
330
304
  flex: 1;
331
305
  min-height: 30px;
306
+ text-align: center;
332
307
  position: relative;
333
308
 
334
309
  span {
@@ -3,6 +3,11 @@ export const resource = {
3
3
  'people have watched the live': 'people have watched the live',
4
4
  'Load More': 'Load More',
5
5
  'Loading...': 'Loading...',
6
+ 'Loading': 'Loading',
6
7
  'No More': 'No More',
7
8
  'No Live': 'No Live',
9
+ 'Pull down to refresh': 'Pull down to refresh',
10
+ 'Release to refresh': 'Release to refresh',
11
+ 'Refresh success': 'Refresh success',
12
+ 'Refresh failed': 'Refresh failed',
8
13
  };
@@ -3,6 +3,11 @@ export const resource = {
3
3
  'people have watched the live': '人看过',
4
4
  'Load More': '加载更多',
5
5
  'Loading...': '加载中...',
6
+ 'Loading': '正在加载...',
6
7
  'No More': '没有更多',
7
8
  'No Live': '暂无直播间',
9
+ 'Pull to refresh': '下拉刷新',
10
+ 'Release to refresh': '松开刷新',
11
+ 'Refresh success': '刷新成功',
12
+ 'Refresh failed': '刷新失败',
8
13
  };
@@ -0,0 +1,364 @@
1
+ <template>
2
+ <div
3
+ class="pull-to-refresh"
4
+ @touchstart="onTouchStart"
5
+ @touchmove="onTouchMove"
6
+ @touchend="onTouchEnd"
7
+ @touchcancel="onTouchEnd"
8
+ >
9
+ <!-- Refresh indicator -->
10
+ <div
11
+ class="refresh-indicator"
12
+ :class="[refreshState, { visible: isIndicatorVisible }]"
13
+ :style="{ transform: `translateY(${translateY}px)` }"
14
+ >
15
+ <!-- refresh-arrow -->
16
+ <IconArrowUpNew
17
+ v-if="refreshState !== RefreshState.Loading && refreshState !== RefreshState.Success && refreshState !== RefreshState.Error"
18
+ class="refresh-arrow"
19
+ :class="{ releasing: refreshState === RefreshState.Releasing }"
20
+ :size="16"
21
+ />
22
+ <!-- refresh-loading -->
23
+ <div v-if="refreshState === RefreshState.Loading" class="refresh-loading"></div>
24
+ <!-- refresh-success -->
25
+ <IconCheck v-if="refreshState === RefreshState.Success" class="refresh-success" :size="16" />
26
+ <!-- refresh-error -->
27
+ <IconErrorToast v-if="refreshState === RefreshState.Error" class="refresh-error" :size="16" />
28
+ <!-- refresh-text -->
29
+ <span class="refresh-text">{{ statusText }}</span>
30
+ </div>
31
+
32
+ <!-- Content slot -->
33
+ <div ref="contentRef" class="refresh-content" :style="{ transform: `translateY(${contentTranslateY}px)` }"
34
+ @scroll="handleScroll"
35
+ @wheel="handleWheel">
36
+ <slot></slot>
37
+ </div>
38
+ </div>
39
+ </template>
40
+
41
+ <script lang="ts" setup>
42
+ import { ref, computed } from 'vue';
43
+ import { IconCheck, IconArrowUpNew, IconErrorToast } from '@tencentcloud/uikit-base-component-vue3';
44
+
45
+ interface Props {
46
+ threshold?: number;
47
+ resistance?: number;
48
+ disabled?: boolean;
49
+ resultDuration?: number;
50
+ text?: {
51
+ pull: string;
52
+ release: string;
53
+ loading: string;
54
+ success: string;
55
+ error: string;
56
+ };
57
+ }
58
+
59
+ /**
60
+ * Pull-to-refresh state enumeration
61
+ * Defines the various states that the component can be in during the entire pull-to-refresh flow
62
+ */
63
+ enum RefreshState {
64
+ /**
65
+ * Pulling state
66
+ * - User is dragging down but hasn't reached the refresh threshold yet
67
+ * - Shows down arrow icon, indicating user can continue pulling down
68
+ * - Content area follows finger movement, providing visual feedback
69
+ */
70
+ Pulling = 'pulling',
71
+
72
+ /**
73
+ * Releasing state
74
+ * - User has pulled down to or beyond the threshold (props.threshold)
75
+ * - Shows up arrow icon, indicating user can release to trigger refresh
76
+ * - Releasing at this point will immediately enter refresh state
77
+ */
78
+ Releasing = 'releasing',
79
+
80
+ /**
81
+ * Loading state
82
+ * - Component enters refresh state after user releases
83
+ * - Shows loading animation (spinning circle)
84
+ * - Content area stays at threshold height, displaying refresh indicator
85
+ * - Parent component starts executing actual refresh logic
86
+ */
87
+ Loading = 'loading',
88
+
89
+ /**
90
+ * Success state
91
+ * - Parent component refresh operation completed successfully
92
+ * - Shows green checkmark icon and success text
93
+ * - Content area stays at threshold height, displaying success indicator
94
+ * - Automatically resets after displaying for props.resultDuration time
95
+ */
96
+ Success = 'success',
97
+
98
+ /**
99
+ * Error state
100
+ * - Parent component refresh operation failed (e.g., network error, API exception)
101
+ * - Shows red error icon and failure text
102
+ * - Content area stays at threshold height, displaying error indicator
103
+ * - Automatically resets after displaying for props.resultDuration time
104
+ */
105
+ Error = 'error',
106
+ }
107
+
108
+ const refreshState = ref(RefreshState.Pulling);
109
+ const startY = ref(0);
110
+ const currentY = ref(0);
111
+ const isTouching = ref(false);
112
+ const contentRef = ref<HTMLElement | null>(null);
113
+ let timer: number | null = null;
114
+
115
+ const props = withDefaults(defineProps<Props>(), {
116
+ threshold: 60,
117
+ resistance: 2.5,
118
+ disabled: false,
119
+ resultDuration: 500,
120
+ text: () => ({
121
+ pull: 'Pull to refresh',
122
+ release: 'Release to refresh',
123
+ loading: 'Loading...',
124
+ success: 'Refresh success',
125
+ error: 'Refresh failed',
126
+ }),
127
+ });
128
+
129
+ const emit = defineEmits<{
130
+ refresh: [completeRefresh: (success?: boolean) => void];
131
+ loadMore: [];
132
+ }>();
133
+
134
+ defineExpose({
135
+ completeRefresh,
136
+ });
137
+
138
+ const pullDistance = computed(() => {
139
+ if (refreshState.value === RefreshState.Loading) {
140
+ return props.threshold;
141
+ }
142
+ if (!isTouching.value) return 0;
143
+ return Math.max(0, (currentY.value - startY.value) / props.resistance);
144
+ });
145
+
146
+ const contentTranslateY = computed(() => {
147
+ if (refreshState.value === RefreshState.Loading || refreshState.value === RefreshState.Success || refreshState.value === RefreshState.Error) {
148
+ return props.threshold;
149
+ }
150
+ return Math.min(pullDistance.value, props.threshold);
151
+ });
152
+
153
+ const translateY = computed(() => {
154
+ if (refreshState.value === RefreshState.Loading || refreshState.value === RefreshState.Success || refreshState.value === RefreshState.Error) {
155
+ return 0;
156
+ }
157
+ return Math.min(pullDistance.value, props.threshold) - props.threshold;
158
+ });
159
+
160
+ const isIndicatorVisible = computed(() => {
161
+ if (refreshState.value === RefreshState.Loading || refreshState.value === RefreshState.Success || refreshState.value === RefreshState.Error) {
162
+ return true;
163
+ }
164
+ return pullDistance.value > 10;
165
+ });
166
+
167
+ const statusText = computed(() => {
168
+ switch (refreshState.value) {
169
+ case RefreshState.Releasing:
170
+ return props.text.release;
171
+ case RefreshState.Loading:
172
+ return props.text.loading;
173
+ case RefreshState.Success:
174
+ return props.text.success;
175
+ case RefreshState.Error:
176
+ return props.text.error;
177
+ default:
178
+ return props.text.pull;
179
+ }
180
+ });
181
+
182
+ function isScrollAtBottom(threshold = 50) {
183
+ if (!contentRef.value) {
184
+ return false;
185
+ }
186
+
187
+ return (
188
+ contentRef.value.scrollTop + contentRef.value.clientHeight >=
189
+ contentRef.value.scrollHeight - threshold
190
+ );
191
+ }
192
+
193
+ function handleWheel(event: WheelEvent) {
194
+ if (!contentRef.value) {
195
+ return;
196
+ }
197
+
198
+ if (event.deltaY > 0 && isScrollAtBottom()) {
199
+ emit('loadMore');
200
+ }
201
+ }
202
+
203
+ function handleScroll() {
204
+ if (!contentRef.value) {
205
+ return;
206
+ }
207
+
208
+ if (isScrollAtBottom()) {
209
+ emit('loadMore');
210
+ }
211
+ }
212
+
213
+ function checkIsAtTop() {
214
+ if (!contentRef.value) return true;
215
+ return contentRef.value.scrollTop === 0;
216
+ }
217
+
218
+ function onTouchStart(event: TouchEvent) {
219
+ if (props.disabled || refreshState.value === RefreshState.Loading) return;
220
+ if (!checkIsAtTop()) return;
221
+
222
+ isTouching.value = true;
223
+ startY.value = event.touches[0].clientY;
224
+ currentY.value = startY.value;
225
+ refreshState.value = RefreshState.Pulling;
226
+ }
227
+
228
+ function onTouchMove(event: TouchEvent) {
229
+ if (!isTouching.value || props.disabled || refreshState.value === RefreshState.Loading) return;
230
+ currentY.value = event.touches[0].clientY;
231
+
232
+ if (pullDistance.value > 0 && checkIsAtTop()) {
233
+ event.preventDefault();
234
+ }
235
+
236
+ refreshState.value = pullDistance.value > props.threshold ? RefreshState.Releasing : RefreshState.Pulling;
237
+ }
238
+
239
+ function onTouchEnd() {
240
+ if (!isTouching.value || props.disabled) return;
241
+ isTouching.value = false;
242
+
243
+ if (refreshState.value === RefreshState.Loading) return;
244
+
245
+ if (refreshState.value === RefreshState.Releasing) {
246
+ startRefresh();
247
+ } else {
248
+ resetPullState();
249
+ }
250
+ }
251
+
252
+ function startRefresh() {
253
+ refreshState.value = RefreshState.Loading;
254
+ emit('refresh', completeRefresh);
255
+ }
256
+
257
+ function completeRefresh(success: boolean = true) {
258
+ refreshState.value = success ? RefreshState.Success : RefreshState.Error;
259
+
260
+ if (timer) {
261
+ clearTimeout(timer);
262
+ }
263
+ timer = setTimeout(() => {
264
+ resetPullState();
265
+ }, props.resultDuration) as unknown as number;
266
+ }
267
+
268
+ function resetPullState() {
269
+ startY.value = 0;
270
+ currentY.value = 0;
271
+ if (refreshState.value !== RefreshState.Loading) {
272
+ refreshState.value = RefreshState.Pulling;
273
+ }
274
+ }
275
+ </script>
276
+
277
+ <style lang="scss" scoped>
278
+ .pull-to-refresh {
279
+ position: relative;
280
+ width: 100%;
281
+ height: 100%;
282
+ overflow: hidden;
283
+ touch-action: pan-y;
284
+
285
+ .refresh-indicator {
286
+ position: absolute;
287
+ top: 0;
288
+ left: 0;
289
+ width: 100%;
290
+ height: v-bind('props.threshold + "px"');
291
+ display: flex;
292
+ justify-content: center;
293
+ align-items: center;
294
+ color: #666;
295
+ font-size: 14px;
296
+ opacity: 0;
297
+ transition: opacity 0.2s;
298
+ background-color: transparent;
299
+ z-index: 10;
300
+
301
+ &.visible {
302
+ opacity: 1;
303
+ }
304
+
305
+ .refresh-arrow {
306
+ width: 16px;
307
+ height: 16px;
308
+ margin-right: 8px;
309
+ rotate: 180deg;
310
+ transition: transform 0.3s;
311
+ fill: currentColor;
312
+
313
+ &.releasing {
314
+ transform: rotate(180deg);
315
+ }
316
+ }
317
+
318
+ .refresh-loading {
319
+ width: 18px;
320
+ height: 18px;
321
+ margin-right: 8px;
322
+ border: 2px solid #e0e0e0;
323
+ border-top: 2px solid #007aff;
324
+ border-radius: 50%;
325
+ animation: spin 1s linear infinite;
326
+ }
327
+
328
+ .refresh-success {
329
+ width: 18px;
330
+ height: 18px;
331
+ margin-right: 8px;
332
+ color: #4caf50;
333
+ }
334
+
335
+ .refresh-error {
336
+ width: 18px;
337
+ height: 18px;
338
+ margin-right: 8px;
339
+ color: #f44336;
340
+ }
341
+
342
+ .refresh-text {
343
+ font-weight: 500;
344
+ }
345
+ }
346
+
347
+ .refresh-content {
348
+ transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
349
+ height: 100%;
350
+ overflow-y: auto;
351
+ -webkit-overflow-scrolling: touch;
352
+ scrollbar-width: none;
353
+ }
354
+ }
355
+
356
+ @keyframes spin {
357
+ 0% {
358
+ transform: rotate(0deg);
359
+ }
360
+ 100% {
361
+ transform: rotate(360deg);
362
+ }
363
+ }
364
+ </style>
@@ -32,7 +32,7 @@
32
32
  </template>
33
33
 
34
34
  <script setup lang="ts">
35
- import { ref, Ref, computed, watch, onMounted, onUnmounted } from 'vue';
35
+ import { ref, Ref, computed, watch, onMounted, onBeforeUnmount } from 'vue';
36
36
  import { useDeviceState } from '../../states/DeviceState';
37
37
  import { MediaSource } from '../../types';
38
38
  import {
@@ -59,10 +59,6 @@ const props = defineProps<{
59
59
 
60
60
  const emits = defineEmits(['addCameraMaterial', 'updateCameraMaterial', 'close']);
61
61
 
62
- onUnmounted(async () => {
63
- await previewTRTCCloud.stopCameraDeviceTest();
64
- });
65
-
66
62
  const title = computed(() => {
67
63
  return props.mediaSource ? t('Update Camera') : t('Add Camera');
68
64
  });
@@ -103,6 +99,11 @@ onMounted(async () => {
103
99
  await previewTRTCCloud.startCameraDeviceTest('video-preview');
104
100
  });
105
101
 
102
+ onBeforeUnmount(async () => {
103
+ await previewTRTCCloud.stopCameraDeviceTest();
104
+ previewTRTCCloud.destroy();
105
+ });
106
+
106
107
  watch(
107
108
  () => props.mediaSource,
108
109
  async (mediaSource: any) => {
@@ -39,7 +39,7 @@ import TUIRoomEngine, {
39
39
  } from '@tencentcloud/tuiroom-engine-js';
40
40
  import LiveSceneSelect from './LiveSceneSelect.vue';
41
41
  import { TUIToast, TOAST_TYPE, useUIKit } from '@tencentcloud/uikit-base-component-vue3';
42
- import { onUnmounted, ref, computed } from 'vue';
42
+ import { onBeforeUnmount, ref, computed } from 'vue';
43
43
  import CameraSettingDialog from './CameraSettingDialog.vue';
44
44
  import MaterialRenameDialog from './MaterialRenameDialog.vue';
45
45
  import MaterialItem from './MaterialItem.vue';
@@ -241,7 +241,7 @@ const updateCameraSetting = (material: MediaSource) => {
241
241
  showCameraSettingDialog.value = true;
242
242
  };
243
243
 
244
- onUnmounted(() => {
244
+ onBeforeUnmount(() => {
245
245
  clearMediaSource();
246
246
  })
247
247
  </script>
@@ -4,6 +4,7 @@
4
4
 
5
5
  &__icon {
6
6
  cursor: pointer;
7
+ display: flex;
7
8
  }
8
9
 
9
10
  &__popup {
@@ -20,12 +21,15 @@
20
21
  &--expanded {
21
22
  display: flex;
22
23
  flex-direction: row;
24
+ gap: 8px;
25
+
23
26
  .attachment-picker__item {
24
27
  padding: 4px;
25
28
  }
26
29
  }
27
30
 
28
31
  &__item {
32
+ outline: none !important;
29
33
  border: none;
30
34
  display: flex;
31
35
  flex-direction: row;