From a5a4e9f15eb96208897b2a053be2ef0fa85cd612 Mon Sep 17 00:00:00 2001 From: shinya Date: Fri, 1 Aug 2025 00:11:02 +0800 Subject: [PATCH] feat: add DoubanCustomSelector vertical scroll --- VERSION.txt | 2 +- src/components/DoubanCustomSelector.tsx | 58 ++++++++++++++++++++++++- src/lib/version.ts | 2 +- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index d54bb2f..e1a17e4 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -20250731231027 \ No newline at end of file +20250801001103 \ No newline at end of file diff --git a/src/components/DoubanCustomSelector.tsx b/src/components/DoubanCustomSelector.tsx index b44b1a0..fe7ebdb 100644 --- a/src/components/DoubanCustomSelector.tsx +++ b/src/components/DoubanCustomSelector.tsx @@ -40,6 +40,9 @@ const DoubanCustomSelector: React.FC = ({ width: number; }>({ left: 0, width: 0 }); + // 二级选择器滚动容器的ref + const secondaryScrollContainerRef = useRef(null); + // 根据 customCategories 生成一级选择器选项(按 type 分组,电影优先) const primaryOptions = React.useMemo(() => { const types = Array.from(new Set(customCategories.map((cat) => cat.type))); @@ -66,6 +69,59 @@ const DoubanCustomSelector: React.FC = ({ })); }, [customCategories, primarySelection]); + // 处理二级选择器的鼠标滚轮事件(原生 DOM 事件) + const handleSecondaryWheel = React.useCallback((e: WheelEvent) => { + e.preventDefault(); + e.stopPropagation(); + const container = secondaryScrollContainerRef.current; + if (container) { + const scrollAmount = e.deltaY * 2; + container.scrollLeft += scrollAmount; + } + }, []); + + // 添加二级选择器的鼠标滚轮事件监听器 + useEffect(() => { + const scrollContainer = secondaryScrollContainerRef.current; + const capsuleContainer = secondaryContainerRef.current; + + if (scrollContainer && capsuleContainer) { + // 同时监听滚动容器和胶囊容器的滚轮事件 + scrollContainer.addEventListener('wheel', handleSecondaryWheel, { + passive: false, + }); + capsuleContainer.addEventListener('wheel', handleSecondaryWheel, { + passive: false, + }); + + return () => { + scrollContainer.removeEventListener('wheel', handleSecondaryWheel); + capsuleContainer.removeEventListener('wheel', handleSecondaryWheel); + }; + } + }, [handleSecondaryWheel]); + + // 当二级选项变化时重新添加事件监听器 + useEffect(() => { + const scrollContainer = secondaryScrollContainerRef.current; + const capsuleContainer = secondaryContainerRef.current; + + if (scrollContainer && capsuleContainer && secondaryOptions.length > 0) { + // 重新添加事件监听器 + scrollContainer.addEventListener('wheel', handleSecondaryWheel, { + passive: false, + }); + capsuleContainer.addEventListener('wheel', handleSecondaryWheel, { + passive: false, + }); + + return () => { + scrollContainer.removeEventListener('wheel', handleSecondaryWheel); + capsuleContainer.removeEventListener('wheel', handleSecondaryWheel); + }; + } + }, [handleSecondaryWheel, secondaryOptions]); + // 更新指示器位置的通用函数 const updateIndicatorPosition = ( activeIndex: number, @@ -244,7 +300,7 @@ const DoubanCustomSelector: React.FC = ({ 片单 -
+
{renderCapsuleSelector( secondaryOptions, secondarySelection || secondaryOptions[0]?.value, diff --git a/src/lib/version.ts b/src/lib/version.ts index 4c6c544..663ec14 100644 --- a/src/lib/version.ts +++ b/src/lib/version.ts @@ -2,7 +2,7 @@ 'use client'; -const CURRENT_VERSION = '20250731231027'; +const CURRENT_VERSION = '20250801001103'; // 版本检查结果枚举 export enum UpdateStatus {