diff --git a/apps/web/src/components/common/container/CollapsibleContent.tsx b/apps/web/src/components/common/container/CollapsibleContent.tsx new file mode 100644 index 0000000..6d1ea96 --- /dev/null +++ b/apps/web/src/components/common/container/CollapsibleContent.tsx @@ -0,0 +1,54 @@ +import React, { useRef, useState } from "react"; + +interface CollapsibleContentProps { + content: string; + maxHeight?: number; +} + +const CollapsibleContent: React.FC = ({ + content, + maxHeight = 150, +}) => { + const contentWrapperRef = useRef(null); + const [isExpanded, setIsExpanded] = useState(false); + + // Determine if content needs to be collapsed + const shouldCollapse = contentWrapperRef.current + ? contentWrapperRef.current.scrollHeight > maxHeight + : false; + + return ( +
+
+
+ + {/* Gradient overlay */} + {shouldCollapse && !isExpanded && ( +
+ )} +
+ + {/* Expand/Collapse button */} + {shouldCollapse && ( + + )} +
+ ); +}; + +export default CollapsibleContent; diff --git a/apps/web/src/components/models/course/detail/CourseDetailDisplayArea.tsx b/apps/web/src/components/models/course/detail/CourseDetailDisplayArea.tsx index 4f956b5..3a2d6ff 100644 --- a/apps/web/src/components/models/course/detail/CourseDetailDisplayArea.tsx +++ b/apps/web/src/components/models/course/detail/CourseDetailDisplayArea.tsx @@ -1,10 +1,11 @@ // components/CourseDetailDisplayArea.tsx import { motion, useScroll, useTransform } from "framer-motion"; -import React, { useContext } from "react"; +import React, { useContext, useRef, useState } from "react"; import { VideoPlayer } from "@web/src/components/presentation/video-player/VideoPlayer"; import { CourseDetailDescription } from "./CourseDetailDescription/CourseDetailDescription"; -import { Course, PostType } from "@nice/common"; +import { Course, LectureType, PostType } from "@nice/common"; import { CourseDetailContext } from "./CourseDetailContext"; +import CollapsibleContent from "@web/src/components/common/container/CollapsibleContent"; interface CourseDetailDisplayAreaProps { // course: Course; @@ -21,23 +22,34 @@ export const CourseDetailDisplayArea: React.FC< const { scrollY } = useScroll(); const videoScale = useTransform(scrollY, [0, 200], [1, 0.8]); const videoOpacity = useTransform(scrollY, [0, 200], [1, 0.8]); - + const contentWrapperRef = useRef(null); + const [isExpanded, setIsExpanded] = useState(false); + const [shouldCollapse, setShouldCollapse] = useState(false); return (
{/* 固定的视频区域 */} {/* 移除 sticky 定位,让视频区域随页面滚动 */} - - {lecture.type === PostType.LECTURE && ( + {lecture?.meta?.type === LectureType.VIDEO && ( +
- )} -
- +
+ )} + {lecture?.meta?.type === LectureType.ARTICLE && ( +
+
+ +
+
+ )} {/* 课程内容区域 */} { 123