|
|
@@ -0,0 +1,118 @@
|
|
|
+/**
|
|
|
+ * NavidromeRandomLoader.ets
|
|
|
+ * 用于渐进式随机播放时加载更多页数据的工具
|
|
|
+ */
|
|
|
+import { VideoItem } from '../../viewmodel/VideoItem';
|
|
|
+import { appendToNavidromePlaylist } from './NavidromePlaylistStore';
|
|
|
+import Logger from './Logger';
|
|
|
+
|
|
|
+const TAG = 'NavidromeRandomLoader';
|
|
|
+
|
|
|
+// 加载状态
|
|
|
+let isLoadingMore: boolean = false;
|
|
|
+
|
|
|
+// 加载回调函数类型定义
|
|
|
+type LoadMoreCallback = () => Promise<VideoItem[]>;
|
|
|
+
|
|
|
+// 加载更多页的回调(由NavidromePage注册)
|
|
|
+let loadMoreCallback: LoadMoreCallback | null = null;
|
|
|
+
|
|
|
+// 检查是否还有更多数据可加载
|
|
|
+let hasMoreDataCallback: (() => boolean) | null = null;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 注册加载更多页的回调函数(由NavidromePage在aboutToAppear中调用)
|
|
|
+ * @param callback 加载一页数据并返回新增歌曲的函数
|
|
|
+ * @param hasMoreChecker 检查是否还有更多数据的函数
|
|
|
+ */
|
|
|
+export function registerLoadMoreCallback(
|
|
|
+ callback: LoadMoreCallback,
|
|
|
+ hasMoreChecker: () => boolean
|
|
|
+): void {
|
|
|
+ loadMoreCallback = callback;
|
|
|
+ hasMoreDataCallback = hasMoreChecker;
|
|
|
+ Logger.info(TAG, '加载回调已注册');
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 注销加载回调(由NavidromePage在aboutToDisappear中调用)
|
|
|
+ */
|
|
|
+export function unregisterLoadMoreCallback(): void {
|
|
|
+ loadMoreCallback = null;
|
|
|
+ hasMoreDataCallback = null;
|
|
|
+ Logger.info(TAG, '加载回调已注销');
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 检查是否正在加载
|
|
|
+ */
|
|
|
+export function isLoading(): boolean {
|
|
|
+ return isLoadingMore;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 检查是否还有更多数据可加载
|
|
|
+ */
|
|
|
+export function hasMoreData(): boolean {
|
|
|
+ return hasMoreDataCallback ? hasMoreDataCallback() : false;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 触发加载更多页数据(由LocalMusic.randomPlay调用)
|
|
|
+ * @param pageCount 要加载的页数,默认3页
|
|
|
+ * @returns 是否成功加载(false表示正在加载中或无回调或无更多数据)
|
|
|
+ */
|
|
|
+export async function triggerLoadMoreSongs(pageCount: number = 3): Promise<boolean> {
|
|
|
+ if (isLoadingMore) {
|
|
|
+ Logger.warn(TAG, '正在加载中,跳过本次请求');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!loadMoreCallback) {
|
|
|
+ Logger.warn(TAG, '加载回调未注册,无法加载更多');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hasMoreDataCallback && !hasMoreDataCallback()) {
|
|
|
+ Logger.info(TAG, '没有更多数据可加载');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ isLoadingMore = true;
|
|
|
+ Logger.info(TAG, `开始加载${pageCount}页数据`);
|
|
|
+
|
|
|
+ try {
|
|
|
+ let totalLoaded = 0;
|
|
|
+
|
|
|
+ for (let i = 0; i < pageCount; i++) {
|
|
|
+ // 检查是否还有更多数据
|
|
|
+ if (hasMoreDataCallback && !hasMoreDataCallback()) {
|
|
|
+ Logger.info(TAG, `第${i + 1}页: 没有更多数据,停止加载`);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加载一页数据
|
|
|
+ const newItems = await loadMoreCallback();
|
|
|
+
|
|
|
+ if (newItems.length === 0) {
|
|
|
+ Logger.info(TAG, `第${i + 1}页: 返回空数据,停止加载`);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 追加到播放列表
|
|
|
+ appendToNavidromePlaylist(newItems);
|
|
|
+ totalLoaded += newItems.length;
|
|
|
+
|
|
|
+ Logger.info(TAG, `第${i + 1}页: 加载${newItems.length}首,累计${totalLoaded}首`);
|
|
|
+ }
|
|
|
+
|
|
|
+ Logger.info(TAG, `加载完成,共加载${totalLoaded}首新歌曲`);
|
|
|
+ return totalLoaded > 0;
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ Logger.error(TAG, `加载失败: ${(error as Error).message}`);
|
|
|
+ return false;
|
|
|
+ } finally {
|
|
|
+ isLoadingMore = false;
|
|
|
+ }
|
|
|
+}
|