Skip to content

Commit 9c464cf

Browse files
author
huzijie.sea
committed
feat(SessionSelector): 添加会话选择器的分页功能
实现会话列表的分页显示,支持通过左右箭头或 h/l 键翻页 添加当前页显示范围和导航提示
1 parent 609b2c8 commit 9c464cf

1 file changed

Lines changed: 67 additions & 5 deletions

File tree

src/ui/components/SessionSelector.tsx

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,17 @@ const Item: React.FC<any> = ({ isSelected, label }) => (
6868
/**
6969
* 会话选择器组件
7070
*/
71+
// 每页显示的会话数量
72+
const PAGE_SIZE = 20;
73+
7174
export const SessionSelector: React.FC<SessionSelectorProps> = ({
7275
sessions: propSessions,
7376
onSelect,
7477
onCancel,
7578
}) => {
7679
const [loadedSessions, setLoadedSessions] = useState<SessionMetadata[]>([]);
7780
const [loading, setLoading] = useState(false);
81+
const [currentPage, setCurrentPage] = useState(0);
7882

7983
// 使用 Zustand store 管理焦点
8084
const currentFocus = useCurrentFocus();
@@ -95,6 +99,23 @@ export const SessionSelector: React.FC<SessionSelectorProps> = ({
9599
// Esc: 调用 onCancel 关闭选择器
96100
if (key.escape && onCancel) {
97101
onCancel();
102+
return;
103+
}
104+
105+
// 翻页:左箭头或 h 键 - 上一页
106+
if (key.leftArrow || input === 'h' || input === 'H') {
107+
if (currentPage > 0) {
108+
setCurrentPage((prev) => prev - 1);
109+
}
110+
return;
111+
}
112+
113+
// 翻页:右箭头或 l 键 - 下一页
114+
if (key.rightArrow || input === 'l' || input === 'L') {
115+
if (currentPage < totalPages - 1) {
116+
setCurrentPage((prev) => prev + 1);
117+
}
118+
return;
98119
}
99120
},
100121
{ isActive: isFocused } // 只在有焦点时激活
@@ -140,6 +161,30 @@ export const SessionSelector: React.FC<SessionSelectorProps> = ({
140161
});
141162
}, [sessions]);
142163

164+
// 分页计算
165+
const totalPages = useMemo(
166+
() => Math.max(1, Math.ceil(items.length / PAGE_SIZE)),
167+
[items.length]
168+
);
169+
170+
const paginatedItems = useMemo(() => {
171+
const start = currentPage * PAGE_SIZE;
172+
return items.slice(start, start + PAGE_SIZE);
173+
}, [items, currentPage]);
174+
175+
const displayRange = useMemo(
176+
() => ({
177+
start: currentPage * PAGE_SIZE + 1,
178+
end: Math.min((currentPage + 1) * PAGE_SIZE, items.length),
179+
}),
180+
[currentPage, items.length]
181+
);
182+
183+
// 会话变化时重置页码
184+
useEffect(() => {
185+
setCurrentPage(0);
186+
}, [sessions.length]);
187+
143188
const handleSelect = (item: { label: string; value: string }) => {
144189
onSelect(item.value);
145190
};
@@ -169,19 +214,36 @@ export const SessionSelector: React.FC<SessionSelectorProps> = ({
169214
📂 选择要恢复的会话:
170215
</Text>
171216
<Text dimColor>
172-
{'\n'}(↑↓ 选择 | Enter 确认 | Esc 取消 | Ctrl+C 退出){'\n'}
217+
{'\n'}(←→ 翻页 | ↑↓ 选择 | Enter 确认 | Esc 取消){'\n'}
173218
</Text>
174219

175220
<SelectInput
176-
items={items}
221+
items={paginatedItems}
177222
onSelect={handleSelect}
178223
indicatorComponent={Indicator}
179224
itemComponent={Item}
180225
/>
181226

182-
<Text dimColor>
183-
{'\n'}{sessions.length} 个历史会话
184-
</Text>
227+
{/* 分页状态栏 */}
228+
<Box marginTop={1} flexDirection="column">
229+
<Text dimColor>
230+
{currentPage + 1}/{totalPages} 页 · 共 {sessions.length} 个会话 · 显示{' '}
231+
{displayRange.start}-{displayRange.end}
232+
</Text>
233+
234+
{/* 翻页导航提示(仅在有多页时显示) */}
235+
{totalPages > 1 && (
236+
<Box marginTop={1}>
237+
<Text color={currentPage > 0 ? 'cyan' : 'gray'}>
238+
{currentPage > 0 ? '◀ ← 上一页' : ' '}
239+
</Text>
240+
<Text> </Text>
241+
<Text color={currentPage < totalPages - 1 ? 'cyan' : 'gray'}>
242+
{currentPage < totalPages - 1 ? '下一页 → ▶' : ''}
243+
</Text>
244+
</Box>
245+
)}
246+
</Box>
185247
</Box>
186248
);
187249
};

0 commit comments

Comments
 (0)