114 lines
3.7 KiB
TypeScript
114 lines
3.7 KiB
TypeScript
// utils/transform.ts
|
||
import type { FeedItem, StencilItem, ShareElementItem, ShortFilm, Tutorial, MediaAsset } from '../types/home';
|
||
|
||
type FeedItemData = ShortFilm | Tutorial | MediaAsset;
|
||
|
||
export function transformFeedItem(item: FeedItem): StencilItem | null {
|
||
// 根据 type 确定实际数据来源
|
||
let data: FeedItemData | null = null;
|
||
if (item.type === 'short_film' && item.short_film) {
|
||
data = item.short_film;
|
||
} else if (item.type === 'tutorial' && item.tutorial) {
|
||
data = item.tutorial;
|
||
} else if (item.type === 'media_asset' && item.media_asset) {
|
||
data = item.media_asset;
|
||
} else {
|
||
return null;
|
||
}
|
||
|
||
if (!data) return null;
|
||
|
||
const creation = data.creation;
|
||
if (!creation) return null;
|
||
|
||
// 构建宽高比字符串(CSS 支持 "宽/高" 格式)
|
||
const { width, height } = creation.size;
|
||
const aspectRatio = `${width}/${height}`;
|
||
|
||
return {
|
||
id: data.id,
|
||
type: 'video', // 当前所有项都是视频,可根据实际情况调整
|
||
src: creation.uri,
|
||
poster: creation.cover_uri,
|
||
aspectRatio,
|
||
avatar: data.creator?.avatar ?? '',
|
||
userName: data.creator?.nick_name ?? '',
|
||
likes: data.react_info?.vote_count ?? 0,
|
||
title: 'title' in data ? data.title : data.tag || data.brief || '未命名作品',
|
||
description: data.detail || ('brief' in data ? data.brief : '') || '',
|
||
createdAt: data.created_at || '',
|
||
contentType: item.type,
|
||
displayTag: 'tag' in data ? data.tag : data.type,
|
||
collectCount: data.react_info?.collect_count ?? 0,
|
||
recreateCount: 'recreate_count' in data ? data.recreate_count : undefined,
|
||
creatorId: data.creator?.id ?? '',
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 转换 Share Elements 数据格式为 StencilItem 格式
|
||
*/
|
||
export function transformShareElementItem(item: ShareElementItem): StencilItem | null {
|
||
const element = item.element;
|
||
const share = item.share;
|
||
|
||
if (!element || !share) return null;
|
||
|
||
// 尝试从 creations 中获取第一个视频/图片
|
||
const firstCreation = share.creations?.[0];
|
||
let src = '';
|
||
let poster = '';
|
||
let aspectRatio = '1/1';
|
||
|
||
if (firstCreation) {
|
||
// 从 creation 获取
|
||
src = firstCreation.uri;
|
||
poster = firstCreation.cover_uri;
|
||
|
||
// 计算宽高比
|
||
const width = firstCreation.resolution?.width || 1920;
|
||
const height = firstCreation.resolution?.height || 1080;
|
||
aspectRatio = `${width}/${height}`;
|
||
}
|
||
// else if (element.components?.[0]) {
|
||
// // 从 components 获取(降级方案)
|
||
// const component = element.components[0];
|
||
// src = component.content;
|
||
// poster = component.cover_uri || component.src_img;
|
||
|
||
// // 尝试从 selected_region 获取宽高
|
||
// if (component.selected_region) {
|
||
// const { x: x1, y: y1 } = component.selected_region.top_left;
|
||
// const { x: x2, y: y2 } = component.selected_region.bottom_right;
|
||
// const width = x2 - x1;
|
||
// const height = y2 - y1;
|
||
// if (width > 0 && height > 0) {
|
||
// aspectRatio = `${width}/${height}`;
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
// 如果仍然没有数据,返回 null
|
||
if (!src) return null;
|
||
|
||
// 如果没有 poster,使用 src 作为 poster
|
||
if (!poster) poster = src;
|
||
|
||
return {
|
||
id: element.id,
|
||
type: 'video',
|
||
src,
|
||
poster,
|
||
aspectRatio,
|
||
avatar: element.creator?.avatar ?? '',
|
||
userName: element.creator?.nick_name ?? '',
|
||
likes: share.react_info?.vote_count ?? 0,
|
||
title: element.name || '未命名作品',
|
||
description: share.introduce || element.recaption?.description || '',
|
||
createdAt: share.created_at || element.created_at || '',
|
||
contentType: 'share_elements',
|
||
displayTag: share.category_display?.[0] || element.type || '素材',
|
||
collectCount: share.react_info?.collect_count ?? 0,
|
||
creatorId: element.creator?.id ?? '',
|
||
};
|
||
} |