diff --git a/src/elderly/components/MemoryPlayer.tsx b/src/elderly/components/MemoryPlayer.tsx new file mode 100644 index 0000000..5911c34 --- /dev/null +++ b/src/elderly/components/MemoryPlayer.tsx @@ -0,0 +1,269 @@ +import React, { useState } from 'react'; +import { ThumbsUp, ThumbsDown, X, Maximize2, ChevronLeft, ChevronRight, Grid3x3 } from 'lucide-react'; +import { MediaLibraryGrid } from './MediaLibraryGrid'; + +interface MediaItem { + id: string; + url: string; + type: 'photo' | 'video'; + caption: string; +} + +interface MemoryPlayerProps { + mediaUrl?: string; + mediaType: 'photo' | 'video'; + title?: string; + caption?: string; + mode?: 'pip' | 'fullscreen'; + mediaList?: MediaItem[]; + currentIndex?: number; + onLike?: () => void; + onDislike?: () => void; + onClose?: () => void; + onToggleMode?: () => void; + onNext?: () => void; + onPrevious?: () => void; + onSelectMedia?: (index: number) => void; +} + +/** + * 媒体播放组件 + * 支持 PIP(画中画)和全屏模式 + */ +export const MemoryPlayer: React.FC = ({ + mediaUrl = '/placeholder-photo.jpg', + mediaType, + caption = '小米 2018 秋游', + mode = 'fullscreen', + mediaList = [], + currentIndex = 0, + onLike, + onDislike, + onClose, + onToggleMode, + onNext, + onPrevious, + onSelectMedia, +}) => { + const [liked, setLiked] = useState(null); + const [showGrid, setShowGrid] = useState(false); + + // 如果有素材库,使用当前索引的媒体 + const currentMedia = mediaList.length > 0 ? mediaList[currentIndex] : null; + const displayUrl = currentMedia?.url || mediaUrl; + const displayType = currentMedia?.type || mediaType; + const displayCaption = currentMedia?.caption || caption; + + const hasPrevious = mediaList.length > 0 && currentIndex > 0; + const hasNext = mediaList.length > 0 && currentIndex < mediaList.length - 1; + + const handleLike = () => { + setLiked(true); + onLike?.(); + }; + + const handleDislike = () => { + setLiked(false); + onDislike?.(); + }; + + const isPIP = mode === 'pip'; + + if (isPIP) { + // PIP 模式 - 小窗口在右上角 + return ( +
+ {/* 媒体内容 */} +
+ {mediaType === 'photo' ? ( + {caption} + ) : ( +
+ + {/* 标题 */} +
+

{caption}

+
+
+ ); + } + + // 全屏模式 - 照片/视频占满屏幕,数字人小圆圈在右下角 + return ( +
+ {/* 媒体内容区 - 占满整个屏幕 */} +
+ {displayType === 'photo' ? ( + {displayCaption} + ) : ( +
+ + {/* 左侧切换按钮 */} + {hasPrevious && ( + + )} + + {/* 右侧切换按钮 */} + {hasNext && ( + + )} + + {/* 标题和进度 - 顶部悬浮 */} + {displayCaption && ( +
+

+ {displayCaption} +

+ {mediaList.length > 0 && ( +

+ {currentIndex + 1} / {mediaList.length} +

+ )} +
+ )} + + {/* 数字人小圆圈 - 右上角悬浮 */} +
+
+ {/* 数字人圆圈 */} +
+
👤
+
+ + {/* 提示文字 */} +
+

随时问我

+
+
+
+ + {/* 底部操作栏 - 悬浮 */} +
+
+ {/* 喜欢按钮 */} + + + {/* 不喜欢按钮 */} + + + {/* 网格视图按钮 */} + {mediaList.length > 0 && ( + + )} + + {/* 关闭按钮 */} + +
+
+ + {/* 网格视图弹窗 */} + {showGrid && ( + { + onSelectMedia?.(index); + setShowGrid(false); + }} + onClose={() => setShowGrid(false)} + /> + )} +
+ ); +};