@quicktvui/ai 1.0.9 → 1.1.1

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 (348) hide show
  1. package/README.md +31 -0
  2. package/USAGE.md +22 -7
  3. package/package.json +1 -1
  4. package/rules/.clinerules +1 -0
  5. package/rules/.cursorrules +1 -0
  6. package/rules/.docs/zh-CN/guide/ai/ai-assistant.md +16 -6
  7. package/rules/.github/copilot-instructions.md +1 -0
  8. package/rules/.source/hellotv/PROJECT-README.md +52 -0
  9. package/rules/.source/hellotv/app.d.ts +11 -0
  10. package/rules/.source/hellotv/package.json +146 -0
  11. package/rules/.source/hellotv/scripts/build-apk.ts +12 -0
  12. package/rules/.source/hellotv/scripts/build.ts +35 -0
  13. package/rules/.source/hellotv/scripts/dev.ts +12 -0
  14. package/rules/.source/hellotv/scripts/pack.ts +24 -0
  15. package/rules/.source/hellotv/scripts/process.ts +37 -0
  16. package/rules/.source/hellotv/scripts/quicktvui-webpack.android.ts +187 -0
  17. package/rules/.source/hellotv/scripts/quicktvui-webpack.dev.ts +147 -0
  18. package/rules/.source/hellotv/scripts/webpack-watch.ts +24 -0
  19. package/rules/.source/hellotv/src/App.vue +192 -0
  20. package/rules/.source/hellotv/src/api/my/index.ts +198 -0
  21. package/rules/.source/hellotv/src/api/user/impl-user.ts +52 -0
  22. package/rules/.source/hellotv/src/api/user/qr-code-mock.ts +2 -0
  23. package/rules/.source/hellotv/src/api/user/request-url.ts +11 -0
  24. package/rules/.source/hellotv/src/api/user/user-manager.ts +258 -0
  25. package/rules/.source/hellotv/src/app.scss +8 -0
  26. package/rules/.source/hellotv/src/assets/component-media/ic_media_btn_pause.png +0 -0
  27. package/rules/.source/hellotv/src/assets/component-media/ic_media_btn_play.png +0 -0
  28. package/rules/.source/hellotv/src/assets/component-media/ic_media_menu_setting_focused.png +0 -0
  29. package/rules/.source/hellotv/src/assets/component-media/ic_media_menu_setting_normal.png +0 -0
  30. package/rules/.source/hellotv/src/assets/component-media/ic_media_menu_xuanji_focused.png +0 -0
  31. package/rules/.source/hellotv/src/assets/component-media/ic_media_menu_xuanji_normal.png +0 -0
  32. package/rules/.source/hellotv/src/assets/component-media/ic_media_ok_focused.png +0 -0
  33. package/rules/.source/hellotv/src/assets/component-media/ic_media_ok_selected.png +0 -0
  34. package/rules/.source/hellotv/src/assets/detail/ic_collect_focused.png +0 -0
  35. package/rules/.source/hellotv/src/assets/detail/ic_collect_normal.png +0 -0
  36. package/rules/.source/hellotv/src/assets/detail/ic_full_focused.png +0 -0
  37. package/rules/.source/hellotv/src/assets/detail/ic_full_normal.png +0 -0
  38. package/rules/.source/hellotv/src/assets/detail/ic_info_focused.png +0 -0
  39. package/rules/.source/hellotv/src/assets/detail/ic_info_normal.png +0 -0
  40. package/rules/.source/hellotv/src/assets/detail/ic_introduction_bg.png +0 -0
  41. package/rules/.source/hellotv/src/assets/detail/ic_media_list_item_normal.png +0 -0
  42. package/rules/.source/hellotv/src/assets/detail/ic_media_list_item_selected.png +0 -0
  43. package/rules/.source/hellotv/src/assets/detail/ic_media_player_pause.png +0 -0
  44. package/rules/.source/hellotv/src/assets/detail/ic_media_player_placeholder.png +0 -0
  45. package/rules/.source/hellotv/src/assets/detail/ic_media_player_play.png +0 -0
  46. package/rules/.source/hellotv/src/assets/detail/ic_vip_focused.png +0 -0
  47. package/rules/.source/hellotv/src/assets/detail/ic_vip_normal.png +0 -0
  48. package/rules/.source/hellotv/src/assets/detail/skeleton.png +0 -0
  49. package/rules/.source/hellotv/src/assets/filter/ic_empty.png +0 -0
  50. package/rules/.source/hellotv/src/assets/filter/ic_filter_focused.png +0 -0
  51. package/rules/.source/hellotv/src/assets/filter/ic_filter_normal.png +0 -0
  52. package/rules/.source/hellotv/src/assets/filter/ic_filter_selected.png +0 -0
  53. package/rules/.source/hellotv/src/assets/filter/ic_left_focused.png +0 -0
  54. package/rules/.source/hellotv/src/assets/filter/ic_left_normal.png +0 -0
  55. package/rules/.source/hellotv/src/assets/filter/ic_left_selected.png +0 -0
  56. package/rules/.source/hellotv/src/assets/history/ic_delete.png +0 -0
  57. package/rules/.source/hellotv/src/assets/history/ic_empty.png +0 -0
  58. package/rules/.source/hellotv/src/assets/home/bg_history_item.png +0 -0
  59. package/rules/.source/hellotv/src/assets/home/bg_shadow.png +0 -0
  60. package/rules/.source/hellotv/src/assets/home/ic_4k_logo.png +0 -0
  61. package/rules/.source/hellotv/src/assets/home/ic_4k_play_focused.png +0 -0
  62. package/rules/.source/hellotv/src/assets/home/ic_4k_subtitle_normal.png +0 -0
  63. package/rules/.source/hellotv/src/assets/home/ic_arrow_focused.png +0 -0
  64. package/rules/.source/hellotv/src/assets/home/ic_arrow_normal.png +0 -0
  65. package/rules/.source/hellotv/src/assets/home/ic_exit_corner.png +0 -0
  66. package/rules/.source/hellotv/src/assets/home/ic_exit_header.png +0 -0
  67. package/rules/.source/hellotv/src/assets/home/ic_play.png +0 -0
  68. package/rules/.source/hellotv/src/assets/live/bg-error.png +0 -0
  69. package/rules/.source/hellotv/src/assets/live/bg-play-info.png +0 -0
  70. package/rules/.source/hellotv/src/assets/live/ic-arrow-left.png +0 -0
  71. package/rules/.source/hellotv/src/assets/live/ic-arrow-right.png +0 -0
  72. package/rules/.source/hellotv/src/assets/live/ic-back.png +0 -0
  73. package/rules/.source/hellotv/src/assets/live/ic-change.png +0 -0
  74. package/rules/.source/hellotv/src/assets/live/ic-corner-vip-tips.png +0 -0
  75. package/rules/.source/hellotv/src/assets/live/ic-corner-vip.png +0 -0
  76. package/rules/.source/hellotv/src/assets/live/ic-key.png +0 -0
  77. package/rules/.source/hellotv/src/assets/live/ic-loading-error.png +0 -0
  78. package/rules/.source/hellotv/src/assets/live/ic-menu-ext-arrow.png +0 -0
  79. package/rules/.source/hellotv/src/assets/live/ic-menu-ext.png +0 -0
  80. package/rules/.source/hellotv/src/assets/live/ic-menu.png +0 -0
  81. package/rules/.source/hellotv/src/assets/live/ic-mine.png +0 -0
  82. package/rules/.source/hellotv/src/assets/live/ic-network-error.png +0 -0
  83. package/rules/.source/hellotv/src/assets/live/ic-ok.png +0 -0
  84. package/rules/.source/hellotv/src/assets/live/ic-playing.png +0 -0
  85. package/rules/.source/hellotv/src/assets/live/ic-playing2.png +0 -0
  86. package/rules/.source/hellotv/src/assets/live/ic-playing3.png +0 -0
  87. package/rules/.source/hellotv/src/assets/live/ic-service.png +0 -0
  88. package/rules/.source/hellotv/src/assets/live/ic_live_broadcast.png +0 -0
  89. package/rules/.source/hellotv/src/assets/live/ic_live_broadcast_focused.png +0 -0
  90. package/rules/.source/hellotv/src/assets/my/ic_collect_focus.png +0 -0
  91. package/rules/.source/hellotv/src/assets/my/ic_collect_normal.png +0 -0
  92. package/rules/.source/hellotv/src/assets/my/ic_order_focus.png +0 -0
  93. package/rules/.source/hellotv/src/assets/my/ic_order_normal.png +0 -0
  94. package/rules/.source/hellotv/src/assets/my/ic_record_focus.png +0 -0
  95. package/rules/.source/hellotv/src/assets/my/ic_record_normal.png +0 -0
  96. package/rules/.source/hellotv/src/assets/my/ic_user.png +0 -0
  97. package/rules/.source/hellotv/src/assets/my/ic_vip_normal.png +0 -0
  98. package/rules/.source/hellotv/src/assets/search/ic_back.png +0 -0
  99. package/rules/.source/hellotv/src/assets/search/ic_back_focused.png +0 -0
  100. package/rules/.source/hellotv/src/assets/search/ic_clear.png +0 -0
  101. package/rules/.source/hellotv/src/assets/search/ic_clear_dark.png +0 -0
  102. package/rules/.source/hellotv/src/assets/search/ic_clear_focused.png +0 -0
  103. package/rules/.source/hellotv/src/assets/search/ic_search.png +0 -0
  104. package/rules/.source/hellotv/src/assets/top-view/ic_logo.png +0 -0
  105. package/rules/.source/hellotv/src/assets/top-view/ic_top_search_focused.png +0 -0
  106. package/rules/.source/hellotv/src/assets/top-view/ic_top_search_normal.png +0 -0
  107. package/rules/.source/hellotv/src/assets/top-view/ic_top_user_focused.png +0 -0
  108. package/rules/.source/hellotv/src/assets/top-view/ic_top_user_normal.png +0 -0
  109. package/rules/.source/hellotv/src/components/bg-animation.scss +14 -0
  110. package/rules/.source/hellotv/src/components/bg-animation.vue +176 -0
  111. package/rules/.source/hellotv/src/components/btn-pack-view.vue +172 -0
  112. package/rules/.source/hellotv/src/components/btn-pack.scss +53 -0
  113. package/rules/.source/hellotv/src/components/grid-item-horizontal.vue +203 -0
  114. package/rules/.source/hellotv/src/components/grid-item-vertical.vue +201 -0
  115. package/rules/.source/hellotv/src/components/media/build-data/media-config.ts +4 -0
  116. package/rules/.source/hellotv/src/components/media/build-data/media-control-adapter.ts +378 -0
  117. package/rules/.source/hellotv/src/components/media/build-data/media-imp.ts +44 -0
  118. package/rules/.source/hellotv/src/components/media/view/media-loading-component.vue +50 -0
  119. package/rules/.source/hellotv/src/components/media/view/media-loading-view.vue +154 -0
  120. package/rules/.source/hellotv/src/components/media/view/media-manager-view.vue +931 -0
  121. package/rules/.source/hellotv/src/components/media/view/media-menu-detail-item.vue +42 -0
  122. package/rules/.source/hellotv/src/components/media/view/media-menu-detail-view.vue +109 -0
  123. package/rules/.source/hellotv/src/components/media/view/media-menu-icon-item.vue +43 -0
  124. package/rules/.source/hellotv/src/components/media/view/media-menu-text-item.vue +27 -0
  125. package/rules/.source/hellotv/src/components/media/view/media-menu-view.vue +88 -0
  126. package/rules/.source/hellotv/src/components/media/view/media-player-view.vue +408 -0
  127. package/rules/.source/hellotv/src/components/media/view/scss/media-loading.scss +51 -0
  128. package/rules/.source/hellotv/src/components/media/view/scss/media-manager.scss +79 -0
  129. package/rules/.source/hellotv/src/components/media/view/scss/media-menu.scss +114 -0
  130. package/rules/.source/hellotv/src/components/media/view/scss/media-player.scss +6 -0
  131. package/rules/.source/hellotv/src/components/qt-tabs-component.ts +268 -0
  132. package/rules/.source/hellotv/src/components/qt-ul-component.ts +792 -0
  133. package/rules/.source/hellotv/src/components/top-view.scss +38 -0
  134. package/rules/.source/hellotv/src/components/top-view.vue +114 -0
  135. package/rules/.source/hellotv/src/config/README.md +22 -0
  136. package/rules/.source/hellotv/src/config/build-config.ts +22 -0
  137. package/rules/.source/hellotv/src/config/private-theme-config.ts +21 -0
  138. package/rules/.source/hellotv/src/config/public-config.scss +16 -0
  139. package/rules/.source/hellotv/src/config/test.scss +45 -0
  140. package/rules/.source/hellotv/src/config/theme-config.ts +51 -0
  141. package/rules/.source/hellotv/src/main.ts +45 -0
  142. package/rules/.source/hellotv/src/pages/activity/adapter/config.ts +37 -0
  143. package/rules/.source/hellotv/src/pages/activity/adapter/index.ts +849 -0
  144. package/rules/.source/hellotv/src/pages/activity/adapter/interface.ts +173 -0
  145. package/rules/.source/hellotv/src/pages/activity/api/index.ts +36 -0
  146. package/rules/.source/hellotv/src/pages/activity/api/interface.ts +11 -0
  147. package/rules/.source/hellotv/src/pages/activity/api/request-url.ts +10 -0
  148. package/rules/.source/hellotv/src/pages/activity/components/item/focus-change-img-item.vue +40 -0
  149. package/rules/.source/hellotv/src/pages/activity/components/item/inner-out-title-item.vue +59 -0
  150. package/rules/.source/hellotv/src/pages/activity/components/item/no-title-item.vue +45 -0
  151. package/rules/.source/hellotv/src/pages/activity/components/item/placeholder-item.vue +25 -0
  152. package/rules/.source/hellotv/src/pages/activity/index.vue +219 -0
  153. package/rules/.source/hellotv/src/pages/activity/scss/index.scss +46 -0
  154. package/rules/.source/hellotv/src/pages/activity/scss/item.scss +69 -0
  155. package/rules/.source/hellotv/src/pages/detail/adapter/index.ts +317 -0
  156. package/rules/.source/hellotv/src/pages/detail/adapter/interface.ts +150 -0
  157. package/rules/.source/hellotv/src/pages/detail/adapter/media-player.ts +378 -0
  158. package/rules/.source/hellotv/src/pages/detail/api/index.ts +77 -0
  159. package/rules/.source/hellotv/src/pages/detail/api/request-url.ts +8 -0
  160. package/rules/.source/hellotv/src/pages/detail/components/media-player/collapse/media-collapse-definition.vue +192 -0
  161. package/rules/.source/hellotv/src/pages/detail/components/media-player/collapse/media-collapse-list-item.vue +108 -0
  162. package/rules/.source/hellotv/src/pages/detail/components/media-player/collapse/media-collapse-media-series.vue +349 -0
  163. package/rules/.source/hellotv/src/pages/detail/components/media-player/collapse/media-collapse-order.vue +194 -0
  164. package/rules/.source/hellotv/src/pages/detail/components/media-player/collapse/media-collapse-speed.vue +192 -0
  165. package/rules/.source/hellotv/src/pages/detail/components/media-player/index.vue +404 -0
  166. package/rules/.source/hellotv/src/pages/detail/components/media-player/media-player-small-view.vue +382 -0
  167. package/rules/.source/hellotv/src/pages/detail/components/media-player/media-player-view.vue +1099 -0
  168. package/rules/.source/hellotv/src/pages/detail/components/recommend-item.vue +167 -0
  169. package/rules/.source/hellotv/src/pages/detail/components/section/basic-section.vue +218 -0
  170. package/rules/.source/hellotv/src/pages/detail/components/section/config.ts +6 -0
  171. package/rules/.source/hellotv/src/pages/detail/components/section/header-section.vue +15 -0
  172. package/rules/.source/hellotv/src/pages/detail/components/section/item/button-menu.vue +259 -0
  173. package/rules/.source/hellotv/src/pages/detail/components/section/item/media-introduction.vue +238 -0
  174. package/rules/.source/hellotv/src/pages/detail/components/section/item/media-series.vue +308 -0
  175. package/rules/.source/hellotv/src/pages/detail/components/section/item/player-placeholder.vue +88 -0
  176. package/rules/.source/hellotv/src/pages/detail/index.vue +571 -0
  177. package/rules/.source/hellotv/src/pages/detail/scss/index.scss +22 -0
  178. package/rules/.source/hellotv/src/pages/detail-full-player/components/media-player/full-player-loading.vue +78 -0
  179. package/rules/.source/hellotv/src/pages/detail-full-player/components/media-player/full-player-menu-view.vue +803 -0
  180. package/rules/.source/hellotv/src/pages/detail-full-player/components/media-player/full-player-view.vue +219 -0
  181. package/rules/.source/hellotv/src/pages/detail-full-player/index.vue +101 -0
  182. package/rules/.source/hellotv/src/pages/detail-full-player/scss/full-player-view.scss +6 -0
  183. package/rules/.source/hellotv/src/pages/detail-full-screen/adapter/index.ts +0 -0
  184. package/rules/.source/hellotv/src/pages/detail-full-screen/adapter/interface.ts +133 -0
  185. package/rules/.source/hellotv/src/pages/detail-full-screen/api/index.ts +77 -0
  186. package/rules/.source/hellotv/src/pages/detail-full-screen/api/request-url.ts +8 -0
  187. package/rules/.source/hellotv/src/pages/detail-full-screen/components/media-info.vue +263 -0
  188. package/rules/.source/hellotv/src/pages/detail-full-screen/components/media-player.vue +42 -0
  189. package/rules/.source/hellotv/src/pages/detail-full-screen/components/media-series-section.vue +26 -0
  190. package/rules/.source/hellotv/src/pages/detail-full-screen/components/recommend-item.vue +167 -0
  191. package/rules/.source/hellotv/src/pages/detail-full-screen/index.vue +163 -0
  192. package/rules/.source/hellotv/src/pages/detail-full-screen/scss/index.scss +41 -0
  193. package/rules/.source/hellotv/src/pages/device-info/index.vue +106 -0
  194. package/rules/.source/hellotv/src/pages/device-info/scss/device-info.scss +49 -0
  195. package/rules/.source/hellotv/src/pages/filter/README.md +66 -0
  196. package/rules/.source/hellotv/src/pages/filter/adapter/index.ts +180 -0
  197. package/rules/.source/hellotv/src/pages/filter/adapter/interface.ts +111 -0
  198. package/rules/.source/hellotv/src/pages/filter/api/index.ts +38 -0
  199. package/rules/.source/hellotv/src/pages/filter/api/interface.ts +44 -0
  200. package/rules/.source/hellotv/src/pages/filter/api/request-url.ts +8 -0
  201. package/rules/.source/hellotv/src/pages/filter/components/content/index.vue +469 -0
  202. package/rules/.source/hellotv/src/pages/filter/components/content/list-item-record.vue +16 -0
  203. package/rules/.source/hellotv/src/pages/filter/components/content/list-item.vue +78 -0
  204. package/rules/.source/hellotv/src/pages/filter/components/expand/index.vue +83 -0
  205. package/rules/.source/hellotv/src/pages/filter/components/sidebar/index.vue +81 -0
  206. package/rules/.source/hellotv/src/pages/filter/components/sidebar/list-item-filter-title.vue +78 -0
  207. package/rules/.source/hellotv/src/pages/filter/components/sidebar/list-item-filter.vue +68 -0
  208. package/rules/.source/hellotv/src/pages/filter/components/sidebar/list-item-line.vue +11 -0
  209. package/rules/.source/hellotv/src/pages/filter/components/sidebar/list-item-text.vue +43 -0
  210. package/rules/.source/hellotv/src/pages/filter/components/sidebar/list-item-title.vue +14 -0
  211. package/rules/.source/hellotv/src/pages/filter/config.ts +10 -0
  212. package/rules/.source/hellotv/src/pages/filter/expand-sidebar-contents.vue +203 -0
  213. package/rules/.source/hellotv/src/pages/filter/scss/filter-content-list-item.scss +42 -0
  214. package/rules/.source/hellotv/src/pages/filter/scss/filter-content.scss +60 -0
  215. package/rules/.source/hellotv/src/pages/filter/scss/filter-expand.scss +30 -0
  216. package/rules/.source/hellotv/src/pages/filter/scss/filter-sidebar.scss +45 -0
  217. package/rules/.source/hellotv/src/pages/filter/scss/filter.scss +21 -0
  218. package/rules/.source/hellotv/src/pages/filter/sidebar-contents.vue +145 -0
  219. package/rules/.source/hellotv/src/pages/filter/single-contents.vue +61 -0
  220. package/rules/.source/hellotv/src/pages/history/adapter/index.ts +51 -0
  221. package/rules/.source/hellotv/src/pages/history/adapter/interface.ts +22 -0
  222. package/rules/.source/hellotv/src/pages/history/api/index.ts +54 -0
  223. package/rules/.source/hellotv/src/pages/history/api/interface.ts +41 -0
  224. package/rules/.source/hellotv/src/pages/history/api/request-url.ts +10 -0
  225. package/rules/.source/hellotv/src/pages/history/components/confirm-dialog.vue +155 -0
  226. package/rules/.source/hellotv/src/pages/history/config.ts +8 -0
  227. package/rules/.source/hellotv/src/pages/history/index-raw.vue +540 -0
  228. package/rules/.source/hellotv/src/pages/history/index.vue +431 -0
  229. package/rules/.source/hellotv/src/pages/history/mock.ts +32 -0
  230. package/rules/.source/hellotv/src/pages/history/scss/history-raw.scss +181 -0
  231. package/rules/.source/hellotv/src/pages/history/scss/history.scss +148 -0
  232. package/rules/.source/hellotv/src/pages/home/adapter/exit/home-exit-adapter.ts +20 -0
  233. package/rules/.source/hellotv/src/pages/home/adapter/exit/home-exit-imp.ts +13 -0
  234. package/rules/.source/hellotv/src/pages/home/adapter/media/create-home-player-interceptor.ts +50 -0
  235. package/rules/.source/hellotv/src/pages/home/adapter/media/home-media-imp.ts +74 -0
  236. package/rules/.source/hellotv/src/pages/home/adapter/tab-bar/tab-bar-adapter.ts +151 -0
  237. package/rules/.source/hellotv/src/pages/home/adapter/tab-bar/tab-bar-config.ts +17 -0
  238. package/rules/.source/hellotv/src/pages/home/adapter/tab-bar/tab-bar-imp.ts +53 -0
  239. package/rules/.source/hellotv/src/pages/home/adapter/tab-bar/tab-bar-item-type.ts +6 -0
  240. package/rules/.source/hellotv/src/pages/home/adapter/tab-content/tab-content-adapter.ts +1304 -0
  241. package/rules/.source/hellotv/src/pages/home/adapter/tab-content/tab-content-config.ts +30 -0
  242. package/rules/.source/hellotv/src/pages/home/adapter/tab-content/tab-content-imp.ts +173 -0
  243. package/rules/.source/hellotv/src/pages/home/adapter/tab-content/tab-content-item-type.ts +17 -0
  244. package/rules/.source/hellotv/src/pages/home/api/index.ts +157 -0
  245. package/rules/.source/hellotv/src/pages/home/api/interface.ts +56 -0
  246. package/rules/.source/hellotv/src/pages/home/api/request-url.ts +22 -0
  247. package/rules/.source/hellotv/src/pages/home/components/exit-dialog.vue +148 -0
  248. package/rules/.source/hellotv/src/pages/home/components/media/bg-player.vue +440 -0
  249. package/rules/.source/hellotv/src/pages/home/components/nav-bar/bar-img-item.vue +39 -0
  250. package/rules/.source/hellotv/src/pages/home/components/nav-bar/bar-text-item.vue +100 -0
  251. package/rules/.source/hellotv/src/pages/home/components/tab-content/bg-player-cell-list-item-img.vue +54 -0
  252. package/rules/.source/hellotv/src/pages/home/components/tab-content/bg-player-cell-list-item-text.vue +67 -0
  253. package/rules/.source/hellotv/src/pages/home/components/tab-content/cell-list-player-item.vue +74 -0
  254. package/rules/.source/hellotv/src/pages/home/components/tab-content/cell-player-item.vue +40 -0
  255. package/rules/.source/hellotv/src/pages/home/components/tab-content/focus-change-img-item.vue +41 -0
  256. package/rules/.source/hellotv/src/pages/home/components/tab-content/history-item.vue +362 -0
  257. package/rules/.source/hellotv/src/pages/home/components/tab-content/inner-out-title-item.vue +60 -0
  258. package/rules/.source/hellotv/src/pages/home/components/tab-content/no-title-item.vue +46 -0
  259. package/rules/.source/hellotv/src/pages/home/components/tab-content/placeholder-item.vue +25 -0
  260. package/rules/.source/hellotv/src/pages/home/components/tab-content/short-video/short-video-section-item.vue +80 -0
  261. package/rules/.source/hellotv/src/pages/home/components/tab-content/short-video/short-video-section.vue +70 -0
  262. package/rules/.source/hellotv/src/pages/home/components/tab-content/small-4k/small-four-section.vue +76 -0
  263. package/rules/.source/hellotv/src/pages/home/components/tab-content/world-4k/world-four-section-item.vue +90 -0
  264. package/rules/.source/hellotv/src/pages/home/components/tab-content/world-4k/world-four-section.vue +57 -0
  265. package/rules/.source/hellotv/src/pages/home/components/waterfall-tabs.vue +1307 -0
  266. package/rules/.source/hellotv/src/pages/home/index.vue +117 -0
  267. package/rules/.source/hellotv/src/pages/home/scss/bar-img-item.scss +11 -0
  268. package/rules/.source/hellotv/src/pages/home/scss/bar-text-item.scss +80 -0
  269. package/rules/.source/hellotv/src/pages/home/scss/base.scss +8 -0
  270. package/rules/.source/hellotv/src/pages/home/scss/bg-player-cell-list-item.scss +24 -0
  271. package/rules/.source/hellotv/src/pages/home/scss/bg-player.scss +50 -0
  272. package/rules/.source/hellotv/src/pages/home/scss/cell-player-item.scss +24 -0
  273. package/rules/.source/hellotv/src/pages/home/scss/exit-dialog.scss +89 -0
  274. package/rules/.source/hellotv/src/pages/home/scss/focus-change-img-item.scss +12 -0
  275. package/rules/.source/hellotv/src/pages/home/scss/home.scss +32 -0
  276. package/rules/.source/hellotv/src/pages/home/scss/inner-out-title-item.scss +24 -0
  277. package/rules/.source/hellotv/src/pages/home/scss/no-title-item.scss +15 -0
  278. package/rules/.source/hellotv/src/pages/home/scss/placeholder-item.scss +14 -0
  279. package/rules/.source/hellotv/src/pages/home/scss/short-video-section.scss +59 -0
  280. package/rules/.source/hellotv/src/pages/home/scss/small-four-section.scss +14 -0
  281. package/rules/.source/hellotv/src/pages/home/scss/waterfall-tabs.scss +50 -0
  282. package/rules/.source/hellotv/src/pages/home/scss/world-four-section.scss +106 -0
  283. package/rules/.source/hellotv/src/pages/introduction/index.vue +227 -0
  284. package/rules/.source/hellotv/src/pages/live/components/menu/first-list-item-icon-text.vue +35 -0
  285. package/rules/.source/hellotv/src/pages/live/components/menu/first-list-item-img.vue +16 -0
  286. package/rules/.source/hellotv/src/pages/live/components/menu/first-list-item-text.vue +16 -0
  287. package/rules/.source/hellotv/src/pages/live/components/menu/index.vue +266 -0
  288. package/rules/.source/hellotv/src/pages/live/components/menu/second-list-item.vue +80 -0
  289. package/rules/.source/hellotv/src/pages/live/components/menu/third-list-item.vue +68 -0
  290. package/rules/.source/hellotv/src/pages/live/components/player/index.vue +168 -0
  291. package/rules/.source/hellotv/src/pages/live/components/player/player-error.vue +48 -0
  292. package/rules/.source/hellotv/src/pages/live/components/player/player-loading.vue +50 -0
  293. package/rules/.source/hellotv/src/pages/live/components/player/player-tips.vue +125 -0
  294. package/rules/.source/hellotv/src/pages/live/components/player/tips-icon-text.vue +27 -0
  295. package/rules/.source/hellotv/src/pages/live/css/menu.css +109 -0
  296. package/rules/.source/hellotv/src/pages/live/css/player.css +56 -0
  297. package/rules/.source/hellotv/src/pages/live/index.vue +128 -0
  298. package/rules/.source/hellotv/src/pages/live/mock/index.ts +263 -0
  299. package/rules/.source/hellotv/src/pages/live/types/index.ts +42 -0
  300. package/rules/.source/hellotv/src/pages/login/index.vue +116 -0
  301. package/rules/.source/hellotv/src/pages/login/scss/login.scss +61 -0
  302. package/rules/.source/hellotv/src/pages/m-test.vue +84 -0
  303. package/rules/.source/hellotv/src/pages/my/README.md +87 -0
  304. package/rules/.source/hellotv/src/pages/my/index.vue +177 -0
  305. package/rules/.source/hellotv/src/pages/my/my-data-manager.ts +606 -0
  306. package/rules/.source/hellotv/src/pages/my/my-templates.vue +24 -0
  307. package/rules/.source/hellotv/src/pages/my/poster/index.vue +98 -0
  308. package/rules/.source/hellotv/src/pages/my/poster/my-card2.vue +90 -0
  309. package/rules/.source/hellotv/src/pages/my/poster/my-icon-title-col.vue +72 -0
  310. package/rules/.source/hellotv/src/pages/my/poster/my-icon-title-row.vue +72 -0
  311. package/rules/.source/hellotv/src/pages/my/poster/my-info.vue +50 -0
  312. package/rules/.source/hellotv/src/pages/my/poster/my-user.vue +126 -0
  313. package/rules/.source/hellotv/src/pages/play-test.vue +95 -0
  314. package/rules/.source/hellotv/src/pages/search/README.md +57 -0
  315. package/rules/.source/hellotv/src/pages/search/adapter/index.ts +285 -0
  316. package/rules/.source/hellotv/src/pages/search/adapter/interface.ts +60 -0
  317. package/rules/.source/hellotv/src/pages/search/api/index.ts +100 -0
  318. package/rules/.source/hellotv/src/pages/search/api/interface.ts +64 -0
  319. package/rules/.source/hellotv/src/pages/search/api/request-url.ts +20 -0
  320. package/rules/.source/hellotv/src/pages/search/components/search-content-tabs.vue +153 -0
  321. package/rules/.source/hellotv/src/pages/search/components/search-content.vue +282 -0
  322. package/rules/.source/hellotv/src/pages/search/components/search-keyboard.vue +252 -0
  323. package/rules/.source/hellotv/src/pages/search/components/search-keyword-grid.vue +85 -0
  324. package/rules/.source/hellotv/src/pages/search/components/search-keyword.vue +346 -0
  325. package/rules/.source/hellotv/src/pages/search/config.ts +10 -0
  326. package/rules/.source/hellotv/src/pages/search/scss/search-content.scss +130 -0
  327. package/rules/.source/hellotv/src/pages/search/scss/search-keyboard.scss +91 -0
  328. package/rules/.source/hellotv/src/pages/search/scss/search-keyword-grid.scss +30 -0
  329. package/rules/.source/hellotv/src/pages/search/scss/search-keyword.scss +104 -0
  330. package/rules/.source/hellotv/src/pages/search/scss/search.scss +18 -0
  331. package/rules/.source/hellotv/src/pages/search/three-columns.vue +164 -0
  332. package/rules/.source/hellotv/src/pages/search/two-columns.vue +128 -0
  333. package/rules/.source/hellotv/src/pages/tabs-test.vue +339 -0
  334. package/rules/.source/hellotv/src/pages/webview/load-web-view.vue +44 -0
  335. package/rules/.source/hellotv/src/routes.ts +142 -0
  336. package/rules/.source/hellotv/src/tools/common.ts +18 -0
  337. package/rules/.source/hellotv/src/tools/format-date.ts +16 -0
  338. package/rules/.source/hellotv/src/tools/index.ts +58 -0
  339. package/rules/.source/hellotv/src/tools/launch.ts +339 -0
  340. package/rules/.source/hellotv/src/tools/request/index.ts +206 -0
  341. package/rules/.source/hellotv/src/tools/request/interface.ts +64 -0
  342. package/rules/.source/hellotv/src/typings/shims-vue.d.ts +6 -0
  343. package/rules/.source/hellotv/src/vue.config.js +3 -0
  344. package/rules/.source/hellotv/tsconfig.json +34 -0
  345. package/rules/.windsurfrules +1 -0
  346. package/rules/AGENTS.md +1 -0
  347. package/rules/CLAUDE.md +1 -0
  348. package/rules/GEMINI.md +1 -0
@@ -0,0 +1,1304 @@
1
+ import {
2
+ QTFlexStyleText,
3
+ QTTabPageData,
4
+ QTWaterfallItem,
5
+ QTWaterfallSection,
6
+ QTWaterfallSectionType,
7
+ } from "@quicktvui/quicktvui3";
8
+ import { QTListViewItemDecoration } from "@quicktvui/quicktvui3/dist/src/list-view/core/QTListViewItemDecoration";
9
+ import { QTWaterfallFlexStyle } from "@quicktvui/quicktvui3/dist/src/waterfall/core/QTWaterfallFlexStyle";
10
+ import homeManager from "../../api";
11
+ import ThemeConfig from "../../../../config/theme-config";
12
+ import { CellListItemType, HomePlayType } from "../media/home-media-imp";
13
+ import barsDataManager from "../tab-bar/tab-bar-adapter";
14
+ import TabContentConfig from "./tab-content-config";
15
+ import {
16
+ PlayType,
17
+ Section,
18
+ Section4KItem,
19
+ SectionItem,
20
+ SectionItemType,
21
+ SectionType,
22
+ TabContent,
23
+ } from "./tab-content-imp";
24
+ import TabContentItemType from "./tab-content-item-type";
25
+
26
+ class TabsContent {
27
+ //存储板块高度
28
+ sectionTotalHeight: Map<string, number> = new Map<string, number>();
29
+ //存储二屏图
30
+ tab2BackgroundUrls: Map<string, string> = new Map<string, string>();
31
+ // 首页4k列表,短视频第一页数据
32
+ homeSectionCacheList: Map<string, Array<any>> = new Map<string, Array<any>>();
33
+ // 记录历史格子位置 {tanIndex: 1, itemIndex: 1}
34
+ historyItemPos: Array<any> = [];
35
+ }
36
+
37
+ const tabsContent = new TabsContent();
38
+ export default tabsContent;
39
+
40
+ /**
41
+ * build导航下对应内容
42
+ * @param tabContent 接口数据
43
+ * @param pageNo 当前页数
44
+ * @param tabId 导航 ID
45
+ * @param tabPageIndex 导航 index
46
+ */
47
+ export async function buildTabContentAdapter(
48
+ tabContent: TabContent,
49
+ pageNo: number = 1,
50
+ tabId: string,
51
+ tabPageIndex: number,
52
+ ): Promise<QTTabPageData> {
53
+ const isFirstPage = pageNo === 1;
54
+ //首次加载清除当前板块高度
55
+ if (isFirstPage) {
56
+ tabsContent.sectionTotalHeight.delete(tabId);
57
+ }
58
+ //解析自定义参数
59
+ const {
60
+ firstSectionMarginTop,
61
+ content4kId,
62
+ shortVideoId,
63
+ disableScrollOnFirstScreen,
64
+ } = parseParameter(tabContent.customParams);
65
+ //4K 视频
66
+ if (content4kId && pageNo === 1) {
67
+ return build4kTabPage(content4kId, tabPageIndex);
68
+ } else if (shortVideoId && pageNo === 1) {
69
+ return buildShortTabPage(shortVideoId, tabPageIndex);
70
+ }
71
+ if (!tabContent || !tabContent.sections || tabContent.sections.length === 0) {
72
+ return {
73
+ data: [],
74
+ isLoadPageEnd: true,
75
+ };
76
+ }
77
+ //存储二屏图
78
+ if (tabContent.backgroundImage != null) {
79
+ tabsContent.tab2BackgroundUrls.set(tabId, tabContent.backgroundImage);
80
+ }
81
+ //获取当前导航Tab下Section原始数据
82
+ const sectionSourceData: Array<Section> = tabContent.sections;
83
+ //创建sectionList板块集合列表
84
+ const sectionList: Array<QTWaterfallSection> = [];
85
+ if (sectionSourceData && sectionSourceData.length > 0) {
86
+ for (
87
+ let sectionIndex = 0;
88
+ sectionIndex < sectionSourceData.length;
89
+ sectionIndex++
90
+ ) {
91
+ const section: Section = sectionSourceData[sectionIndex];
92
+ //如果是图片标题 板块标题高度从后台获取
93
+ if (
94
+ section.title?.image &&
95
+ section.title?.style?.height &&
96
+ section.title?.style?.width
97
+ ) {
98
+ TabContentConfig.sectionTitleHeightDefault = section.title.style.height;
99
+ }
100
+ //检测小 4K 放映厅 板块 是否存在 单独处理
101
+ const sectionType = section.type;
102
+ if (sectionType === SectionType.TYPE_SWIPER_PLAY) {
103
+ section.style["height"] = 484;
104
+ }
105
+
106
+ //获取板块高度
107
+ const sectionHeight: number = getSectionHeight(section);
108
+ //存储板块高度 用于判断是否展示底部提示
109
+ saveSectionTotalHeight(sectionHeight, tabId);
110
+ const firstSectionIndex: boolean = sectionIndex === 0 && isFirstPage;
111
+ if (sectionType === SectionType.TYPE_SWIPER_PLAY && section.contentId) {
112
+ //获取展示的板块高度
113
+ section.style.height = buildSectionHeightBySectionType(section);
114
+ const buildSectionData: QTWaterfallSection = await buildSmall4KSection(
115
+ section,
116
+ tabPageIndex,
117
+ sectionIndex,
118
+ firstSectionIndex,
119
+ firstSectionMarginTop,
120
+ );
121
+ sectionList.push(buildSectionData);
122
+ } else {
123
+ // build section列表数据
124
+ const res = buildSectionItemList(
125
+ section,
126
+ sectionIndex,
127
+ tabPageIndex,
128
+ pageNo,
129
+ );
130
+ const sectionWaterfallItemList: Array<QTWaterfallItem> =
131
+ res.buildSectionItemList;
132
+ const isFocusScrollTarget: boolean = res.isFocusScrollTarget;
133
+ //获取展示的板块高度
134
+ section.style.height = buildSectionHeightBySectionType(section);
135
+ //build 板块数据
136
+ const buildSectionData: QTWaterfallSection = buildSection(
137
+ section,
138
+ sectionWaterfallItemList,
139
+ firstSectionIndex,
140
+ firstSectionMarginTop,
141
+ isFocusScrollTarget,
142
+ );
143
+ sectionList.push(buildSectionData);
144
+ }
145
+ }
146
+ }
147
+ /********根据板块高度,分页是否结束数据判断是否加载结束板块***********/
148
+ //加载结束标识
149
+ let isLoadPageEnd: boolean;
150
+ //当前已经加载的板块个数
151
+ const curLoadTotal =
152
+ (pageNo - 1) * TabContentConfig.sectionLoadLimit +
153
+ sectionSourceData?.length;
154
+ //当前板块总高度
155
+ const singleNavBarOffsetY =
156
+ barsDataManager.barsData.itemList?.length > 1
157
+ ? 0
158
+ : TabContentConfig.firstSectionOffsetY;
159
+ const sectionTotalHeight =
160
+ getSectionTotalHeight(tabId) +
161
+ firstSectionMarginTop +
162
+ TabContentConfig.firstSectionTop +
163
+ singleNavBarOffsetY;
164
+ if (sectionTotalHeight > 1080 && curLoadTotal >= (tabContent.total || 0)) {
165
+ isLoadPageEnd = true;
166
+
167
+ // 如果最后一个板块格子标题在外部, 到底提示板块增加上边距
168
+ if (
169
+ sectionList[sectionList.length - 1].itemList[0].title?.type ===
170
+ SectionItemType.TYPE_OUT
171
+ ) {
172
+ sectionList.push(buildEndSection("5", { top: 40 }));
173
+ } else {
174
+ sectionList.push(buildEndSection("5"));
175
+ }
176
+ } else {
177
+ isLoadPageEnd = sectionList.length === 0;
178
+ }
179
+ const tabPage: QTTabPageData = buildTabContent(
180
+ disableScrollOnFirstScreen,
181
+ sectionList,
182
+ );
183
+ tabPage.isLoadPageEnd = isLoadPageEnd;
184
+ return tabPage;
185
+ }
186
+
187
+ /**
188
+ * 根据板块类型 build 板块展示高度
189
+ * @param section type:SectionType.TYPE_DEFAULT / SectionType.TYPE_LINE_SCROLL
190
+ */
191
+ export function buildSectionHeightBySectionType(section: Section): number {
192
+ const sectionType = section.type;
193
+ let height: number = getSectionHeight(section);
194
+ if (sectionType === SectionType.TYPE_DEFAULT) {
195
+ //默认flex布局的板块 会自动计算板块标题高度所以此处减掉板块标题高度
196
+ height = section.showTitle
197
+ ? height - TabContentConfig.sectionTitleHeightDefault
198
+ : height;
199
+ }
200
+ return height;
201
+ }
202
+
203
+ /**
204
+ * 获取板块高度
205
+ * @param section
206
+ */
207
+ export function getSectionHeight(section: Section): number {
208
+ let sectionHeight: number = section.style?.height || 0;
209
+ //获取是否展示板块标题 flag
210
+ const showTitle = section.showTitle;
211
+ if (showTitle) {
212
+ if (section.type === SectionType.TYPE_SWIPER_PLAY) {
213
+ //放映厅板块 需要展示标题的时候,不加间距高度
214
+ sectionHeight += TabContentConfig.sectionTitleHeightDefault;
215
+ } else {
216
+ sectionHeight +=
217
+ TabContentConfig.sectionGap +
218
+ TabContentConfig.sectionTitleHeightDefault;
219
+ }
220
+ }
221
+ return sectionHeight;
222
+ }
223
+
224
+ /**
225
+ * 存储板块整体高度
226
+ * @param sectionHeight 已有板块高度
227
+ * @param tabId 导航 ID
228
+ */
229
+ export function saveSectionTotalHeight(
230
+ sectionHeight: number,
231
+ tabId: string,
232
+ ): void {
233
+ const sectionHeightOld = tabsContent.sectionTotalHeight.get(tabId) || 0;
234
+ const totalH = sectionHeightOld + sectionHeight;
235
+ tabsContent.sectionTotalHeight.set(tabId, totalH);
236
+ }
237
+
238
+ /**
239
+ * 获取板块总高度
240
+ * @param tabId
241
+ */
242
+ export function getSectionTotalHeight(tabId: string): number {
243
+ return tabsContent.sectionTotalHeight.get(tabId) || 0;
244
+ }
245
+
246
+ /**
247
+ * 解析自定义参数
248
+ * @param parameter
249
+ */
250
+ export function parseParameter(parameter) {
251
+ const params = {
252
+ //首个板块距离顶部距离
253
+ firstSectionMarginTop: 0,
254
+ //首次获得焦点是否禁止移动
255
+ disableScrollOnFirstScreen: false,
256
+ //4k内容Id
257
+ content4kId: "",
258
+ //短视频内容Id
259
+ shortVideoId: "",
260
+ //预约内容Id
261
+ reservationId: "",
262
+ };
263
+ if (parameter) {
264
+ const param = JSON.parse(parameter);
265
+ for (let j = 0; j < param.length; j++) {
266
+ const key = param[j].key;
267
+ switch (key) {
268
+ case "switchBgMarginTop":
269
+ if (param[j].value) {
270
+ const value = Number(param[j].value);
271
+ if (value) {
272
+ params.firstSectionMarginTop += value;
273
+ }
274
+ }
275
+ break;
276
+ case "disableScrollOnFirstScreen":
277
+ if (param[j].value) {
278
+ params.disableScrollOnFirstScreen = param[j].value === "true";
279
+ }
280
+ break;
281
+ case "content4kId":
282
+ if (param[j].value) {
283
+ params.content4kId = param[j].value;
284
+ }
285
+ break;
286
+ case "shortVideoId":
287
+ if (param[j].value) {
288
+ params.shortVideoId = param[j].value;
289
+ }
290
+ break;
291
+ default:
292
+ if (param[j].value) {
293
+ params[key] = param[j].value;
294
+ }
295
+ break;
296
+ }
297
+ }
298
+ }
299
+ return params;
300
+ }
301
+
302
+ /**
303
+ * 封装板块数据
304
+ * @param section 板块数据
305
+ * @param sectionIndex 板块 index
306
+ * @param tabPageIndex 导航 index
307
+ */
308
+ export function buildSectionItemList(
309
+ section: Section,
310
+ sectionIndex: number,
311
+ tabPageIndex: number,
312
+ pageNo: number,
313
+ ): {
314
+ buildSectionItemList: Array<QTWaterfallItem>;
315
+ isFocusScrollTarget: boolean;
316
+ } {
317
+ //定义封装后的数据
318
+ const buildSectionItemList: Array<QTWaterfallItem> = [];
319
+ let isFocusScrollTarget: boolean = false;
320
+ //获取板块内容列表
321
+ const sectionItemList: Array<SectionItem> = section.items;
322
+ if (sectionItemList && sectionItemList.length > 0) {
323
+ const length = sectionItemList.length;
324
+ //板块类型
325
+ const type = section.type;
326
+ //是否展示板块标题
327
+ const showTitle = section.showTitle;
328
+ let isFirstSetPlay: boolean = true;
329
+ for (const sectionItem of sectionItemList) {
330
+ const sectionItemIndex: number = sectionItemList.indexOf(sectionItem);
331
+ //封装格子数据
332
+ const qtWaterfallItem: QTWaterfallItem = buildSectionItem(
333
+ sectionItem,
334
+ showTitle,
335
+ tabPageIndex,
336
+ type,
337
+ sectionItemIndex,
338
+ );
339
+ //针对一行滚动格子设置decoration
340
+ if (type === SectionType.TYPE_LINE_SCROLL) {
341
+ qtWaterfallItem.decoration = {
342
+ left:
343
+ sectionItemIndex === 0
344
+ ? TabContentConfig.decorationLeftGap
345
+ : TabContentConfig.sectionItemGap,
346
+ right:
347
+ sectionItemIndex === length - 1
348
+ ? TabContentConfig.decorationLeftGap
349
+ : 0,
350
+ top: section.showTitle ? TabContentConfig.sectionItemGap : 0,
351
+ };
352
+ }
353
+ if (sectionIndex === 0 && pageNo === 1) {
354
+ //检测第一个板块中是否有播放器
355
+ const sectionItemType = sectionItem.type;
356
+ if (
357
+ (sectionItemType === SectionItemType.TYPE_SMALL_PLAY ||
358
+ sectionItemType === SectionItemType.TYPE_SMALL_LIST_PLAY) &&
359
+ isFirstSetPlay
360
+ ) {
361
+ isFirstSetPlay = false;
362
+ isFocusScrollTarget = true;
363
+ //保存小窗播放/小窗播放列表数据
364
+ barsDataManager.barsData.itemList[tabPageIndex].isPlay = true;
365
+ const playType =
366
+ sectionItemType === SectionItemType.TYPE_SMALL_PLAY
367
+ ? HomePlayType.TYPE_CELL
368
+ : HomePlayType.TYPE_CELL_LIST;
369
+ barsDataManager.barsData.itemList[tabPageIndex].playType = playType;
370
+ barsDataManager.barsData.itemList[tabPageIndex].sectionItemIndex =
371
+ sectionItemIndex;
372
+ } else if (sectionItem.playBackgroundId) {
373
+ //背景播放
374
+ if (isFirstSetPlay) {
375
+ isFirstSetPlay = false;
376
+ barsDataManager.barsData.itemList[tabPageIndex].isPlay = true;
377
+ barsDataManager.barsData.itemList[tabPageIndex].playType =
378
+ HomePlayType.TYPE_BG;
379
+ barsDataManager.barsData.itemList[tabPageIndex].sectionItemIndex =
380
+ sectionItemIndex;
381
+ }
382
+ const playBackgroundUrl = sectionItem.playBackgroundUrl;
383
+ const play = {
384
+ playData: [
385
+ {
386
+ id: sectionItem.playBackgroundId,
387
+ index: sectionItemIndex,
388
+ type: PlayType.TYPE_LONG,
389
+ cover: sectionItem.imageFocusBackground,
390
+ isRequestUrl: !playBackgroundUrl,
391
+ url: playBackgroundUrl
392
+ ? [
393
+ {
394
+ definition: "1",
395
+ playUrl: playBackgroundUrl,
396
+ },
397
+ ]
398
+ : [],
399
+ },
400
+ ],
401
+ };
402
+ qtWaterfallItem.play = play;
403
+ }
404
+ }
405
+ buildSectionItemList.push(qtWaterfallItem);
406
+ }
407
+ }
408
+ return {
409
+ buildSectionItemList: buildSectionItemList,
410
+ isFocusScrollTarget: isFocusScrollTarget,
411
+ };
412
+ }
413
+
414
+ /**
415
+ * 封装格子数据
416
+ * @param sectionItem
417
+ * @param showTitle
418
+ * @param tabPageIndex
419
+ * @param sectionType
420
+ */
421
+ export function buildSectionItem(
422
+ sectionItem: SectionItem,
423
+ showTitle: boolean,
424
+ tabPageIndex: number,
425
+ sectionType: number | string,
426
+ sectionItemIndex?: number,
427
+ ): QTWaterfallItem {
428
+ //根据是否展示板块标题和是否是一行滚动
429
+ const posY =
430
+ sectionItem.posY + (showTitle ? TabContentConfig.sectionItemGap : 0);
431
+ if (sectionType === SectionType.TYPE_LINE_SCROLL) {
432
+ sectionItem.posY = 0;
433
+ } else {
434
+ sectionItem.posY = posY;
435
+ }
436
+ let buildSectionItem: QTWaterfallItem;
437
+ let historyItemFlag = false;
438
+ const sectionItemType: SectionItemType = sectionItem.type;
439
+ switch (sectionItemType) {
440
+ case SectionItemType.TYPE_DEFAULT: //无标题
441
+ buildSectionItem = buildNoTitleSectionItem(sectionItem);
442
+ break;
443
+ case SectionItemType.TYPE_INNER:
444
+ case SectionItemType.TYPE_OUT: //带标题
445
+ buildSectionItem = buildTitleSectionItem(sectionItem);
446
+ break;
447
+ case SectionItemType.TYPE_PLACE_HOLDER: //占位格子
448
+ buildSectionItem = buildPlaceHolderSectionItem(sectionItem);
449
+ break;
450
+ case SectionItemType.TYPE_TEXT_HISTORY: //文字历史格子
451
+ case SectionItemType.TYPE_IMG_HISTORY: //图片历史格子
452
+ buildSectionItem = buildTextHistorySectionItem(sectionItem);
453
+ // 记录历史格子的位置
454
+ tabsContent.historyItemPos.map((item) => {
455
+ if (item.tabIndex == tabPageIndex) historyItemFlag = true;
456
+ });
457
+ if (!historyItemFlag)
458
+ tabsContent.historyItemPos.push({
459
+ tabIndex: tabPageIndex,
460
+ itemIndex: sectionItemIndex,
461
+ });
462
+ break;
463
+ case SectionItemType.TYPE_FOCUS_CHANGE_IMG: //焦点换图格子
464
+ buildSectionItem = buildFocusChangeImgSectionItem(sectionItem);
465
+ break;
466
+ case SectionItemType.TYPE_SMALL_PLAY: //小窗播放
467
+ buildSectionItem = buildSmallPlayerSectionItem(sectionItem, tabPageIndex);
468
+ break;
469
+ case SectionItemType.TYPE_SMALL_LIST_PLAY: // 小窗列表播放
470
+ buildSectionItem = buildSmallListPlayerSectionItem(
471
+ sectionItem,
472
+ tabPageIndex,
473
+ );
474
+ break;
475
+ default: //默认--无标题格子
476
+ buildSectionItem = buildNoTitleSectionItem(sectionItem);
477
+ break;
478
+ }
479
+ return buildSectionItem;
480
+ }
481
+
482
+ /**
483
+ * 封装无标题格子
484
+ * @param sectionItem 格子数据
485
+ */
486
+ export function buildNoTitleSectionItem(
487
+ sectionItem: SectionItem,
488
+ ): QTWaterfallItem {
489
+ return {
490
+ type: TabContentItemType.TYPE_ITEM_SECTION_NO_TITLE,
491
+ style: buildStyle(sectionItem),
492
+ image: {
493
+ style: {
494
+ width: sectionItem.width,
495
+ height: sectionItem.height,
496
+ },
497
+ normal: sectionItem.image,
498
+ },
499
+ corner: buildCorner(sectionItem),
500
+ imageFocusBackground: sectionItem.imageFocusBackground,
501
+ jumpParams: sectionItem.jumpParams,
502
+ shimmer: {
503
+ enable: true,
504
+ size: [sectionItem.width, sectionItem.height],
505
+ },
506
+ };
507
+ }
508
+
509
+ /**
510
+ * 封装带题格子
511
+ * @param sectionItem 格子数据
512
+ */
513
+ export function buildTitleSectionItem(
514
+ sectionItem: SectionItem,
515
+ ): QTWaterfallItem {
516
+ const style = buildStyle(sectionItem);
517
+ const type = sectionItem.type;
518
+ let height = sectionItem.height;
519
+ let colors = ["#00000000", "#00000000"];
520
+ if (type === SectionItemType.TYPE_OUT) {
521
+ height += TabContentConfig.sectionItemHeight;
522
+ } else {
523
+ colors = ThemeConfig.tabContentFloatBgColor;
524
+ }
525
+ style.height = height;
526
+ return {
527
+ type: TabContentItemType.TYPE_ITEM_SECTION_HAS_TITLE,
528
+ style: style,
529
+ image: {
530
+ style: {
531
+ width: sectionItem.width,
532
+ height: sectionItem.height,
533
+ },
534
+ normal: sectionItem.image,
535
+ },
536
+ title: {
537
+ type,
538
+ style: {
539
+ width: sectionItem.width,
540
+ height: TabContentConfig.sectionItemHeight,
541
+ marginTop: height - TabContentConfig.sectionItemHeight,
542
+ },
543
+ text: sectionItem.title,
544
+ background: {
545
+ colors: colors,
546
+ cornerRadii4: [
547
+ 0,
548
+ 0,
549
+ ThemeConfig.focusBorderCorner,
550
+ ThemeConfig.focusBorderCorner,
551
+ ],
552
+ orientation: 4,
553
+ },
554
+ },
555
+ corner: buildCorner(sectionItem),
556
+ shimmer: {
557
+ enable: true,
558
+ size: [sectionItem.width, sectionItem.height],
559
+ },
560
+ jumpParams: sectionItem.jumpParams,
561
+ };
562
+ }
563
+
564
+ /**
565
+ * 封装焦点变图格子
566
+ * @param sectionItem 格子数据
567
+ */
568
+ export function buildFocusChangeImgSectionItem(
569
+ sectionItem: SectionItem,
570
+ ): QTWaterfallItem {
571
+ return {
572
+ type: TabContentItemType.TYPE_ITEM_SECTION_FOCUS_CHANGE_IMG,
573
+ style: buildStyle(sectionItem),
574
+ image: {
575
+ style: {
576
+ width: sectionItem.width,
577
+ height: sectionItem.height,
578
+ },
579
+ normal: sectionItem.image,
580
+ focused: sectionItem.imageFocus,
581
+ },
582
+ jumpParams: sectionItem.jumpParams,
583
+ imageFocusBackground: sectionItem.imageFocusBackground,
584
+ shimmer: {
585
+ enable: true,
586
+ size: [sectionItem.width, sectionItem.height],
587
+ },
588
+ };
589
+ }
590
+
591
+ /**
592
+ * 封装小窗播放格子数据
593
+ * @param sectionItem 格子数据
594
+ * @param tabPageIndex tab 导航 index
595
+ */
596
+ export function buildSmallPlayerSectionItem(
597
+ sectionItem: SectionItem,
598
+ tabPageIndex: number,
599
+ ): QTWaterfallItem {
600
+ return {
601
+ type: TabContentItemType.TYPE_ITEM_SECTION_CELL_PLAYER,
602
+ style: buildStyle(sectionItem),
603
+ image: {
604
+ style: {
605
+ width: sectionItem.width,
606
+ height: sectionItem.height,
607
+ },
608
+ normal: sectionItem.image,
609
+ },
610
+ play: {
611
+ style: {
612
+ width: sectionItem.width,
613
+ height: sectionItem.height,
614
+ },
615
+ sid: "cellSid" + sectionItem.id + "tabIndex" + tabPageIndex,
616
+ playData: sectionItem.playData,
617
+ },
618
+ jumpParams: sectionItem.jumpParams,
619
+ };
620
+ }
621
+
622
+ /**
623
+ * 封装小窗列表播放格子数据
624
+ * @param sectionItem 格子数据
625
+ * @param tabPageIndex tab 导航 index
626
+ */
627
+ export function buildSmallListPlayerSectionItem(
628
+ sectionItem: SectionItem,
629
+ tabPageIndex: number,
630
+ ): QTWaterfallItem {
631
+ const playData = sectionItem.playData;
632
+ if (!playData) {
633
+ return {
634
+ type: TabContentItemType.TYPE_ITEM_SECTION_CELL_PLAYER_LIST,
635
+ style: buildStyle(sectionItem),
636
+ };
637
+ }
638
+ const length = playData.length;
639
+ const cellMode = TabContentConfig.cellListItemType;
640
+ //设置小窗列表item 高度 , 文字高度 116, 图片高度 160
641
+ const itemHeight = cellMode === CellListItemType.TYPE_TEXT ? 116 : 160;
642
+ const buildPlayData = playData?.map((item, index) => {
643
+ return cellMode === CellListItemType.TYPE_TEXT
644
+ ? {
645
+ type: 86,
646
+ name: TabContentConfig.cellListSectionItemName,
647
+ imgUrl: item.cover,
648
+ text: item.title,
649
+ textFocus: " " + item.title,
650
+ itemStyle: {
651
+ width: 410,
652
+ height: itemHeight,
653
+ },
654
+ gradientBackground: {
655
+ colors: ["#ffffff", "#ffffff"],
656
+ cornerRadii4: [
657
+ 0,
658
+ index === 0 ? 16 : 0,
659
+ index === length - 1 ? 16 : 0,
660
+ 0,
661
+ ],
662
+ },
663
+ }
664
+ : {
665
+ type: index === 0 ? 82 : index === length - 1 ? 84 : 83, // TODO: 让底层支持 flexStyle: { borderTopRightRadius、borderBottomRightRadius }
666
+ name: TabContentConfig.cellListSectionItemName,
667
+ imgUrl: item.cover,
668
+ cover: item.cover,
669
+ itemStyle: {
670
+ width: 410,
671
+ height: itemHeight,
672
+ },
673
+ markStyle: {
674
+ width: 42,
675
+ height: 42,
676
+ marginTop: itemHeight - 36,
677
+ marginLeft: 410 - 42,
678
+ },
679
+ gradientBackground: {
680
+ colors: ["#8C000000", "#8C000000"],
681
+ cornerRadii4: [
682
+ 0,
683
+ index === 0 ? 16 : 0,
684
+ index === length - 1 ? 16 : 0,
685
+ 0,
686
+ ],
687
+ },
688
+ };
689
+ });
690
+ return {
691
+ type: TabContentItemType.TYPE_ITEM_SECTION_CELL_PLAYER_LIST,
692
+ style: buildStyle(sectionItem),
693
+ image: {
694
+ style: {
695
+ width: sectionItem.width - 410,
696
+ height: sectionItem.height,
697
+ },
698
+ normal: sectionItem.playData[0].cover,
699
+ sid: "cellPlayerListBgSid",
700
+ },
701
+ listStyle: {
702
+ width: 410,
703
+ height: sectionItem.height,
704
+ marginLeft: sectionItem.width - 410,
705
+ },
706
+ cellListSid: "cellPlayerListSid",
707
+ play: {
708
+ style: {
709
+ width: sectionItem.width - 410,
710
+ height: sectionItem.height,
711
+ },
712
+ sid: "cellSid" + sectionItem.id + "tabIndex" + tabPageIndex,
713
+ buildPlayData,
714
+ playData: sectionItem.playData,
715
+ },
716
+ };
717
+ }
718
+
719
+ /**
720
+ * 封装占位格子
721
+ * @param sectionItem 格子数据
722
+ */
723
+ export function buildPlaceHolderSectionItem(
724
+ sectionItem: SectionItem,
725
+ ): QTWaterfallItem {
726
+ return {
727
+ type: TabContentItemType.TYPE_ITEM_SECTION_PLACEHOLDER,
728
+ style: buildStyle(sectionItem),
729
+ image: {
730
+ style: {
731
+ width: sectionItem.width,
732
+ height: sectionItem.height,
733
+ },
734
+ normal: sectionItem.image,
735
+ },
736
+ };
737
+ }
738
+
739
+ export function buildTextHistorySectionItem(
740
+ sectionItem: SectionItem,
741
+ ): QTWaterfallItem {
742
+ return {
743
+ type: TabContentItemType.TYPE_ITEM_HISTORY_TEXT,
744
+ style: buildStyle(sectionItem),
745
+ };
746
+ }
747
+
748
+ /**
749
+ * build 板块
750
+ * @param section 板块数据
751
+ * @param sectionWaterfallItemList 板块中格子数据
752
+ * @param isFirstSection 是否第一个板块
753
+ * @param firstSectionMarginTop 首个板块距离顶部距离
754
+ * @param isFocusScrollTarget 焦点滚动
755
+ *
756
+ */
757
+ export function buildSection(
758
+ section: Section,
759
+ sectionWaterfallItemList: Array<QTWaterfallItem>,
760
+ isFirstSection: boolean,
761
+ firstSectionMarginTop: number,
762
+ isFocusScrollTarget: boolean,
763
+ ): QTWaterfallSection {
764
+ let buildSection: QTWaterfallSection;
765
+ if (
766
+ section.title?.image &&
767
+ section.title?.style?.height &&
768
+ section.title?.style?.width
769
+ ) {
770
+ buildSection = buildImgSectionTitle(
771
+ section,
772
+ sectionWaterfallItemList,
773
+ isFirstSection,
774
+ firstSectionMarginTop,
775
+ isFocusScrollTarget,
776
+ );
777
+ } else {
778
+ buildSection = buildTextSectionTitle(
779
+ section,
780
+ sectionWaterfallItemList,
781
+ isFirstSection,
782
+ firstSectionMarginTop,
783
+ isFocusScrollTarget,
784
+ );
785
+ }
786
+ return buildSection;
787
+ }
788
+
789
+ /**
790
+ * 文字板块标题 build 对应数据
791
+ * @param section 板块数据
792
+ * @param sectionWaterfallItemList 板块中格子数据
793
+ * @param isFirstSection 是否第一个板块
794
+ * @param firstSectionMarginTop 首个板块距离顶部距离
795
+ * @param isFocusScrollTarget 焦点滚动
796
+ */
797
+ export function buildTextSectionTitle(
798
+ section: Section,
799
+ sectionWaterfallItemList: Array<QTWaterfallItem>,
800
+ isFirstSection: boolean,
801
+ firstSectionMarginTop: number,
802
+ isFocusScrollTarget: boolean,
803
+ ): QTWaterfallSection {
804
+ return {
805
+ _id: section.id,
806
+ type: buildSectionType(section.type),
807
+ title: section.showTitle ? section.title.text : "",
808
+ titleStyle: buildSectionTitleStyle(section),
809
+ decoration: buildSectionDecoration(isFirstSection, firstSectionMarginTop),
810
+ style: buildSectionStyle(section.style.height),
811
+ itemList: sectionWaterfallItemList,
812
+ isFocusScrollTarget: isFocusScrollTarget,
813
+ };
814
+ }
815
+
816
+ /**
817
+ * 图片板块标题 build 对应数据
818
+ * @param section 板块数据
819
+ * @param sectionWaterfallItemList 板块中格子数据
820
+ * @param isFirstSection 是否第一个板块
821
+ * @param firstSectionMarginTop 首个板块距离顶部距离
822
+ * @param isFocusScrollTarget 焦点滚动
823
+ */
824
+ export function buildImgSectionTitle(
825
+ section: Section,
826
+ sectionWaterfallItemList: Array<QTWaterfallItem>,
827
+ isFirstSection: boolean,
828
+ firstSectionMarginTop: number,
829
+ isFocusScrollTarget: boolean,
830
+ ): QTWaterfallSection {
831
+ return {
832
+ _id: section.id,
833
+ type: buildSectionType(section.type),
834
+ imgTitle: section.showTitle ? section.title.image : "",
835
+ imgTitleStyle: buildSectionTitleStyle(section, true),
836
+ decoration: buildSectionDecoration(isFirstSection, firstSectionMarginTop),
837
+ style: buildSectionStyle(section.style.height),
838
+ itemList: sectionWaterfallItemList,
839
+ isFocusScrollTarget: isFocusScrollTarget,
840
+ };
841
+ }
842
+
843
+ /**
844
+ * 小 4K 板块 对应数据
845
+ * @param section
846
+ * @param sectionWaterfallItemList
847
+ * @param isFirstSection
848
+ * @param firstSectionMarginTop
849
+ */
850
+ export function buildSmallSection(
851
+ section: Section,
852
+ sectionWaterfallItemList: Array<QTWaterfallItem>,
853
+ isFirstSection: boolean,
854
+ firstSectionMarginTop: number,
855
+ ): QTWaterfallSection {
856
+ const isShowPlateName = section.showTitle;
857
+ return {
858
+ _id: section.id,
859
+ type: buildSectionType(section.type),
860
+ title: section.showTitle ? section.title.text : "",
861
+ titleStyle: buildSectionTitleStyle(section),
862
+ decoration: buildSectionDecoration(isFirstSection, firstSectionMarginTop),
863
+ style: buildSectionStyle(section.style.height),
864
+ listStyle: { width: 1920, height: 484 },
865
+ replaceChildStyle: {
866
+ width: 860,
867
+ height: 484,
868
+ },
869
+ mLayout: isShowPlateName
870
+ ? [530, TabContentConfig.sectionTitleHeightDefault, 860, 484]
871
+ : [530, 0, 860, 484],
872
+ itemList: sectionWaterfallItemList,
873
+ };
874
+ }
875
+
876
+ /**
877
+ * build 板块 style 数据
878
+ * @param sectionHeight 板块高度
879
+ */
880
+ export function buildSectionStyle(sectionHeight: number): QTWaterfallFlexStyle {
881
+ return {
882
+ width: 1920,
883
+ height: sectionHeight,
884
+ marginLeft: -1,
885
+ // gradientBackground:{ colors: ['#FFFF00', '#00FFFF'],orientation:0 }
886
+ };
887
+ }
888
+
889
+ /**
890
+ * build 板块间距
891
+ * @param isFirstSection 是否第一个板块
892
+ * @param firstSectionMarginTop 第一个板块距离顶部距离
893
+ */
894
+ export function buildSectionDecoration(
895
+ isFirstSection: boolean,
896
+ firstSectionMarginTop: number,
897
+ ): QTListViewItemDecoration {
898
+ let decoration: QTListViewItemDecoration;
899
+ if (isFirstSection) {
900
+ const singleNavBarOffsetY =
901
+ barsDataManager.barsData.itemList?.length > 1
902
+ ? 0
903
+ : TabContentConfig.firstSectionOffsetY;
904
+ decoration = {
905
+ top:
906
+ TabContentConfig.firstSectionTop +
907
+ firstSectionMarginTop +
908
+ singleNavBarOffsetY,
909
+ };
910
+ } else {
911
+ decoration = {
912
+ top: TabContentConfig.sectionItemGap,
913
+ };
914
+ }
915
+ return decoration;
916
+ }
917
+
918
+ /**
919
+ * build板块类型
920
+ * @param sectionType 板块类型
921
+ */
922
+ function buildSectionType(sectionType: SectionType): number {
923
+ let type: number;
924
+ switch (sectionType) {
925
+ case SectionType.TYPE_DEFAULT:
926
+ type = QTWaterfallSectionType.QT_WATERFALL_SECTION_TYPE_FLEX;
927
+ break;
928
+ case SectionType.TYPE_LINE_SCROLL:
929
+ type = QTWaterfallSectionType.QT_WATERFALL_SECTION_TYPE_LIST;
930
+ break;
931
+ case SectionType.TYPE_SWIPER_PLAY:
932
+ type = TabContentItemType.TYPE_WATERFALL_SECTION_SMALL_4K;
933
+ break;
934
+ default:
935
+ type = QTWaterfallSectionType.QT_WATERFALL_SECTION_TYPE_FLEX;
936
+ break;
937
+ }
938
+ return type;
939
+ }
940
+
941
+ /**
942
+ * build板块标题样式
943
+ * @param section 板块数据
944
+ * @param isImgTitle 标题类型
945
+ */
946
+ function buildSectionTitleStyle(
947
+ section: Section,
948
+ isImgTitle: boolean = false,
949
+ ): QTWaterfallFlexStyle & QTFlexStyleText {
950
+ let titleStyle: QTWaterfallFlexStyle & QTFlexStyleText = {
951
+ width: 0,
952
+ height: 0,
953
+ };
954
+ if (isImgTitle) {
955
+ if (section.showTitle) {
956
+ titleStyle = {
957
+ width: section.title.style?.width,
958
+ height: section.title.style?.height,
959
+ marginLeft: TabContentConfig.decorationLeftGap,
960
+ };
961
+ }
962
+ } else {
963
+ if (section.showTitle) {
964
+ titleStyle = {
965
+ height: TabContentConfig.sectionTitleHeightDefault,
966
+ marginLeft: TabContentConfig.decorationLeftGap,
967
+ fontSize: TabContentConfig.sectionTitleFontSize,
968
+ };
969
+ }
970
+ }
971
+ return titleStyle;
972
+ }
973
+
974
+ /**
975
+ * 封装 整体格子style
976
+ * @param sectionItem 格子内容
977
+ */
978
+ function buildStyle(sectionItem: SectionItem): QTWaterfallFlexStyle {
979
+ return {
980
+ width: sectionItem.width,
981
+ height: sectionItem.height,
982
+ x: sectionItem.posX,
983
+ y: sectionItem.posY,
984
+ };
985
+ }
986
+
987
+ /**
988
+ * 封装 Corner 角标
989
+ * @param sectionItem 格子内容
990
+ */
991
+ function buildCorner(sectionItem: SectionItem) {
992
+ const colors =
993
+ sectionItem.corner?.textGradient || ThemeConfig.tabCornerColors;
994
+ return {
995
+ enable: !!sectionItem.corner?.text,
996
+ text: sectionItem.corner?.text ?? "",
997
+ background: {
998
+ colors: colors,
999
+ cornerRadii4: [
1000
+ 0,
1001
+ ThemeConfig.focusBorderCorner,
1002
+ 0,
1003
+ ThemeConfig.focusBorderCorner,
1004
+ ],
1005
+ orientation: 2,
1006
+ },
1007
+ };
1008
+ }
1009
+
1010
+ /**
1011
+ * 底部
1012
+ * @param sectionId 板块id
1013
+ */
1014
+ export function buildEndSection(
1015
+ sectionId: string,
1016
+ decoration?: object,
1017
+ ): QTWaterfallSection {
1018
+ return {
1019
+ _id: sectionId,
1020
+ type: QTWaterfallSectionType.QT_WATERFALL_SECTION_TYPE_END,
1021
+ decoration: decoration,
1022
+ title: "已经到底啦,按【返回键】回到顶部",
1023
+ style: {
1024
+ width: 1920,
1025
+ height: 200,
1026
+ },
1027
+ titleStyle: {
1028
+ fontSize: 30,
1029
+ },
1030
+ itemList: [],
1031
+ };
1032
+ }
1033
+
1034
+ /**
1035
+ * build瀑布流Tab Content内容
1036
+ * @param disableScrollOnFirstScreen 首次移动是否滚动
1037
+ * @param waterfallSectionList 加载内容
1038
+ */
1039
+ export function buildTabContent(
1040
+ disableScrollOnFirstScreen: boolean = false,
1041
+ sections: Array<QTWaterfallSection>,
1042
+ ): QTTabPageData {
1043
+ return {
1044
+ useDiff: false,
1045
+ disableScrollOnFirstScreen,
1046
+ data: sections,
1047
+ bindingPlayer: "",
1048
+ };
1049
+ }
1050
+
1051
+ /**
1052
+ * 封装 4K 世界 板块数据
1053
+ * @param content4kId
1054
+ */
1055
+ export function build4kTabPage(
1056
+ content4kId: string,
1057
+ tabPageIndex: number,
1058
+ ): QTTabPageData {
1059
+ barsDataManager.barsData.itemList[tabPageIndex].isPlay = true;
1060
+ barsDataManager.barsData.itemList[tabPageIndex].playType =
1061
+ HomePlayType.TYPE_4K;
1062
+ barsDataManager.barsData.itemList[tabPageIndex].sectionItemIndex = 0;
1063
+ const cacheList = tabsContent.homeSectionCacheList.get(content4kId);
1064
+ const section: QTWaterfallSection = {
1065
+ _id: content4kId,
1066
+ type: TabContentItemType.TYPE_WATERFALL_SECTION_4K,
1067
+ style: {
1068
+ width: 1920,
1069
+ height: 855,
1070
+ },
1071
+ decoration: {
1072
+ top: TabContentConfig.firstSectionTop - 30,
1073
+ },
1074
+ list4KSid: "plate4K" + content4kId,
1075
+ content4kId,
1076
+ itemList: cacheList && cacheList?.length > 0 ? cacheList : [],
1077
+ };
1078
+ const tabPage: QTTabPageData = {
1079
+ useDiff: false,
1080
+ isEndPage: true,
1081
+ disableScrollOnFirstScreen: true,
1082
+ data: [section],
1083
+ };
1084
+ return tabPage;
1085
+ }
1086
+
1087
+ /**
1088
+ * 封装 短视频 板块数据
1089
+ * @param shortVideoId
1090
+ * @param tabPageIndex
1091
+ */
1092
+ export function buildShortTabPage(
1093
+ shortVideoId: string,
1094
+ tabPageIndex: number,
1095
+ ): QTTabPageData {
1096
+ barsDataManager.barsData.itemList[tabPageIndex].isPlay = true;
1097
+ barsDataManager.barsData.itemList[tabPageIndex].playType =
1098
+ HomePlayType.TYPE_SHORT_SCREEN;
1099
+ barsDataManager.barsData.itemList[tabPageIndex].sectionItemIndex = 0;
1100
+ // TODO test data
1101
+ // shortVideoId = "1849006805280256002"
1102
+ const cacheList = tabsContent.homeSectionCacheList.get(shortVideoId);
1103
+ const section: QTWaterfallSection = {
1104
+ _id: shortVideoId,
1105
+ type: TabContentItemType.TYPE_WATERFALL_SECTION_SHORT_SCREEN,
1106
+ style: {
1107
+ width: 556,
1108
+ height: 800,
1109
+ },
1110
+ shortList: {
1111
+ style: {
1112
+ width: 556,
1113
+ height: 855,
1114
+ },
1115
+ sid: "shortVideo" + shortVideoId,
1116
+ },
1117
+ itemList: cacheList && cacheList?.length > 0 ? cacheList : [],
1118
+ decoration: {
1119
+ top: TabContentConfig.firstSectionTop,
1120
+ left: TabContentConfig.decorationLeftGap,
1121
+ },
1122
+ shortVideoId,
1123
+ };
1124
+ const tabPage: QTTabPageData = {
1125
+ useDiff: false,
1126
+ isEndPage: true,
1127
+ disableScrollOnFirstScreen: true,
1128
+ data: [section],
1129
+ };
1130
+ return tabPage;
1131
+ }
1132
+
1133
+ /**
1134
+ * 封装 4K 板块内容数据
1135
+ * @param section4K 原始内容数据
1136
+ */
1137
+ export function build4KSectionData(
1138
+ section4K: Array<Section4KItem>,
1139
+ ): Array<QTWaterfallItem> {
1140
+ const waterfallItems: Array<QTWaterfallItem> = [];
1141
+ if (section4K && section4K.length > 0) {
1142
+ const length = section4K.length;
1143
+ const endSid = `helloTv4k${section4K[length - 1].id}img`;
1144
+ const startSid = `helloTv4k${section4K[0].id}img`;
1145
+ let mCurSid = "";
1146
+ for (
1147
+ let section4KItemIndex = 0;
1148
+ section4KItemIndex < length;
1149
+ section4KItemIndex++
1150
+ ) {
1151
+ const section4kItem = section4K[section4KItemIndex];
1152
+ const beforeSid = section4KItemIndex === 0 ? endSid : mCurSid;
1153
+ mCurSid = `helloTv4k${section4kItem.id}img`;
1154
+ const nextSid =
1155
+ section4KItemIndex === length - 1
1156
+ ? startSid
1157
+ : `helloTv4k${section4K[section4KItemIndex + 1].id}img`;
1158
+ const item: QTWaterfallItem = {
1159
+ type: TabContentItemType.TYPE_WATERFALL_SECTION_4K_ITEM,
1160
+ sid: mCurSid,
1161
+ name: TabContentConfig.world4kSectionItemName,
1162
+ image: {
1163
+ style: { width: 1413, height: 795 },
1164
+ normal: section4kItem.image,
1165
+ },
1166
+ style: {
1167
+ width: 1413,
1168
+ height: 795,
1169
+ },
1170
+ decoration: { right: 92 },
1171
+ title: section4kItem.title,
1172
+ subTitle: section4kItem.subTitle,
1173
+ subTitleShow: !!section4kItem.subTitle,
1174
+ jumpParams: section4kItem.jumpParams,
1175
+ play: {
1176
+ style: {
1177
+ width: 1413,
1178
+ height: 795,
1179
+ },
1180
+ playData: section4kItem.playData,
1181
+ },
1182
+ };
1183
+ if (section4kItem.playData && section4kItem.playData.length > 0) {
1184
+ const buildPlayData = section4kItem.playData[0];
1185
+ const sid = {
1186
+ beforeSid: beforeSid,
1187
+ sid: mCurSid,
1188
+ nextSid: nextSid,
1189
+ };
1190
+ item.play.playData = [{ ...buildPlayData, ...sid }];
1191
+ }
1192
+ waterfallItems.push(item);
1193
+ }
1194
+ }
1195
+ return waterfallItems;
1196
+ }
1197
+
1198
+ /**
1199
+ * 封装 短视频 板块内容数据
1200
+ * @param shortVideoData 原始内容数据
1201
+ */
1202
+ export function buildShortVideoSectionData(
1203
+ shortVideoData: Array<Section4KItem>,
1204
+ ): Array<QTWaterfallItem> {
1205
+ const waterfallItems: Array<QTWaterfallItem> = [];
1206
+ if (shortVideoData && shortVideoData.length > 0) {
1207
+ for (const shortItem of shortVideoData) {
1208
+ const shortItemIndex: number = shortVideoData.indexOf(shortItem);
1209
+ const item: QTWaterfallItem = {
1210
+ type: TabContentItemType.TYPE_WATERFALL_SECTION_SHORT_SCREEN_ITEM,
1211
+ name: TabContentConfig.shortVideoSectionItemName,
1212
+ style: {
1213
+ width: 540,
1214
+ height: 144,
1215
+ },
1216
+ decoration: {
1217
+ top: shortItemIndex == 0 ? 8 : 10,
1218
+ left: 8,
1219
+ bottom: 16,
1220
+ },
1221
+ image: {
1222
+ normal: shortItem.image,
1223
+ },
1224
+ title: {
1225
+ text: shortItem.title,
1226
+ textFocus: "  " + shortItem.title,
1227
+ sub: shortItem.subTitle,
1228
+ },
1229
+ jumpParams: shortItem.jumpParams,
1230
+ play: {
1231
+ playData: shortItem.playData,
1232
+ },
1233
+ };
1234
+ waterfallItems.push(item);
1235
+ }
1236
+ }
1237
+ return waterfallItems;
1238
+ }
1239
+
1240
+ export async function buildSmall4KSection(
1241
+ section: Section,
1242
+ tabPageIndex: number,
1243
+ sectionIndex: number,
1244
+ isFirstSection: boolean,
1245
+ firstSectionMarginTop: number,
1246
+ ): Promise<QTWaterfallSection> {
1247
+ let buildSection: QTWaterfallSection = { itemList: [], style: {}, type: -1 };
1248
+ barsDataManager.barsData.itemList[tabPageIndex].isPlay = true;
1249
+ barsDataManager.barsData.itemList[tabPageIndex].playType =
1250
+ HomePlayType.TYPE_SMALL_4K;
1251
+ barsDataManager.barsData.itemList[tabPageIndex].sectionItemIndex = 0;
1252
+ barsDataManager.barsData.itemList[tabPageIndex].sectionIndex = sectionIndex;
1253
+ // todo 记得放开 contentId
1254
+ const res: Array<QTWaterfallItem> = await homeManager.get4KSection(
1255
+ section.contentId + "",
1256
+ 10,
1257
+ TabContentItemType.TYPE_WATERFALL_SECTION_SMALL_4K,
1258
+ );
1259
+ // const res: Array<QTWaterfallItem> = await homeManager.get4KSection('1849006805280256002', 10, TabContentItemType.TYPE_WATERFALL_SECTION_SMALL_4K)
1260
+ if (res && res.length > 0) {
1261
+ buildSection = buildSmallSection(
1262
+ section,
1263
+ res,
1264
+ isFirstSection,
1265
+ firstSectionMarginTop,
1266
+ );
1267
+ }
1268
+ return buildSection;
1269
+ }
1270
+
1271
+ export function buildSmall4KSectionData(
1272
+ sectionSmall4K: Array<Section4KItem>,
1273
+ ): Array<QTWaterfallItem> {
1274
+ const waterfallItems: Array<QTWaterfallItem> = [];
1275
+ if (sectionSmall4K && sectionSmall4K.length > 0) {
1276
+ const length = sectionSmall4K.length;
1277
+ let mCurSid = "";
1278
+ for (let index = 0; index < length; index++) {
1279
+ const sectionItem = sectionSmall4K[index];
1280
+ mCurSid = `helloTvSmall4k${sectionItem.id}img`;
1281
+ const item: QTWaterfallItem = {
1282
+ type: TabContentItemType.TYPE_WATERFALL_SECTION_SMALL_4K_ITEM,
1283
+ sid: mCurSid,
1284
+ name: TabContentConfig.worldSmall4kSectionItemName,
1285
+ image: {
1286
+ style: { width: 860, height: 484 },
1287
+ normal: sectionItem.image,
1288
+ },
1289
+ style: { width: 860, height: 484 },
1290
+ decoration: { right: 92 },
1291
+ jumpParams: sectionItem.jumpParams,
1292
+ play: {
1293
+ style: {
1294
+ width: 860,
1295
+ height: 484,
1296
+ },
1297
+ playData: sectionItem.playData,
1298
+ },
1299
+ };
1300
+ waterfallItems.push(item);
1301
+ }
1302
+ }
1303
+ return waterfallItems;
1304
+ }