直播卡片

This commit is contained in:
Developer
2026-03-13 21:52:09 +08:00
parent b447ec0c76
commit a971a65f96
10 changed files with 860 additions and 100 deletions

View File

@@ -13,26 +13,20 @@ export interface BigRow {
export type ListRow = NormalRow | BigRow;
const PAGE = 21; // matches API page size
/**
* Transform a flat VideoItem array into display rows.
* Videos are chunked by page size (20). The last item of each chunk
* becomes a full-width BigRow so BigVideoCards stay at stable positions
* even as more pages are loaded.
*/
export function toListRows(videos: VideoItem[]): ListRow[] {
if (videos.length === 0) return [];
export function toListRows(pages: VideoItem[][]): ListRow[] {
const rows: ListRow[] = [];
for (let start = 0; start < videos.length; start += PAGE) {
const chunk = videos.slice(start, start + PAGE);
// Pick the video with the highest view count as the BigRow
let bigIdx = 0;
let maxView = chunk[0].stat?.view ?? 0;
for (let i = 1; i < chunk.length; i++) {
const v = chunk[i].stat?.view ?? 0;
if (v > maxView) { maxView = v; bigIdx = i; }
for (const chunk of pages) {
if (chunk.length === 0) continue;
// Prioritize: first live item becomes BigRow
let bigIdx = chunk.findIndex(item => item.goto === 'live');
if (bigIdx === -1) {
// Fallback: highest view count
bigIdx = 0;
let maxView = chunk[0].stat?.view ?? 0;
for (let i = 1; i < chunk.length; i++) {
const v = chunk[i].stat?.view ?? 0;
if (v > maxView) { maxView = v; bigIdx = i; }
}
}
const bigItem = chunk[bigIdx];
const rest = chunk.filter((_, i) => i !== bigIdx);
@@ -41,6 +35,5 @@ export function toListRows(videos: VideoItem[]): ListRow[] {
}
rows.push({ type: 'big', item: bigItem });
}
return rows;
}