feat: improve session sidebar archive and pagination controls
Add a toggle for displaying archived sessions in the sidebar menu Load more sessions in smaller increments Reset expanded session counts when collapsing groups or projects
This commit is contained in:
@@ -176,7 +176,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
const [collapsedProjects, setCollapsedProjects] = React.useState<Set<string>>(new Set());
|
||||
|
||||
const [projectRepoStatus, setProjectRepoStatus] = React.useState<Map<string, boolean | null>>(new Map());
|
||||
const [expandedSessionGroups, setExpandedSessionGroups] = React.useState<Set<string>>(new Set());
|
||||
const [visibleSessionCountByGroup, setVisibleSessionCountByGroup] = React.useState<Map<string, number>>(new Map());
|
||||
const [newWorktreeDialogOpen, setNewWorktreeDialogOpen] = React.useState(false);
|
||||
const [updateDialogOpen, setUpdateDialogOpen] = React.useState(false);
|
||||
const [openSidebarMenuKey, setOpenSidebarMenuKey] = React.useState<string | null>(null);
|
||||
@@ -681,20 +681,43 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
[collapsedFolderIds, toggleFolderCollapse, createFolder, t],
|
||||
);
|
||||
|
||||
const toggleGroupSessionLimit = React.useCallback((groupId: string) => {
|
||||
setExpandedSessionGroups((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (next.has(groupId)) {
|
||||
next.delete(groupId);
|
||||
} else {
|
||||
next.add(groupId);
|
||||
}
|
||||
const showMoreGroupSessions = React.useCallback((groupId: string, currentVisibleCount: number) => {
|
||||
setVisibleSessionCountByGroup((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(groupId, currentVisibleCount + 7);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const resetGroupSessionLimit = React.useCallback((groupId: string) => {
|
||||
setVisibleSessionCountByGroup((prev) => {
|
||||
if (!prev.has(groupId)) {
|
||||
return prev;
|
||||
}
|
||||
const next = new Map(prev);
|
||||
next.delete(groupId);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const resetProjectSessionLimits = React.useCallback((projectId: string) => {
|
||||
setVisibleSessionCountByGroup((prev) => {
|
||||
let changed = false;
|
||||
const next = new Map(prev);
|
||||
const projectGroupPrefix = `${projectId}:`;
|
||||
for (const groupId of next.keys()) {
|
||||
if (groupId.startsWith(projectGroupPrefix)) {
|
||||
next.delete(groupId);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed ? next : prev;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const collapseAllProjects = React.useCallback(() => {
|
||||
ignoreIntersectionUntil.current = Date.now() + 150;
|
||||
setVisibleSessionCountByGroup(new Map());
|
||||
setCollapsedProjects(() => {
|
||||
const allIds = new Set(projects.map((p) => p.id));
|
||||
try {
|
||||
@@ -709,6 +732,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
|
||||
const expandAllProjects = React.useCallback(() => {
|
||||
ignoreIntersectionUntil.current = Date.now() + 150;
|
||||
setVisibleSessionCountByGroup(new Map());
|
||||
setCollapsedProjects(() => {
|
||||
const empty = new Set<string>();
|
||||
try {
|
||||
@@ -724,6 +748,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
const toggleProject = React.useCallback((projectId: string) => {
|
||||
// Ignore intersection events for a short period after toggling
|
||||
ignoreIntersectionUntil.current = Date.now() + 150;
|
||||
resetProjectSessionLimits(projectId);
|
||||
setCollapsedProjects((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (next.has(projectId)) {
|
||||
@@ -741,7 +766,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
}
|
||||
return next;
|
||||
});
|
||||
}, [isVSCode, safeStorage, scheduleCollapsedProjectsPersist]);
|
||||
}, [isVSCode, resetProjectSessionLimits, safeStorage, scheduleCollapsedProjectsPersist]);
|
||||
|
||||
const normalizedProjects = React.useMemo(() => {
|
||||
return projects
|
||||
@@ -933,6 +958,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
}, [projectSections, homeDirectory]);
|
||||
|
||||
const showRecentSection = useSessionDisplayStore((state) => state.showRecentSection);
|
||||
const showArchivedSessions = useSessionDisplayStore((state) => state.showArchivedSessions);
|
||||
|
||||
const activeNowSessions = React.useMemo(() => {
|
||||
if (!showRecentSection) {
|
||||
@@ -1010,8 +1036,15 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
});
|
||||
|
||||
const sectionsForSidebarRender = React.useMemo(() => {
|
||||
const archiveFilteredSections = showArchivedSessions
|
||||
? sectionsForRender
|
||||
: sectionsForRender.map((section) => ({
|
||||
...section,
|
||||
groups: section.groups.filter((group) => !group.isArchivedBucket),
|
||||
}));
|
||||
|
||||
if (isVSCode || hasSessionSearchQuery || recentSessionIds.size === 0) {
|
||||
return sectionsForRender;
|
||||
return archiveFilteredSections;
|
||||
}
|
||||
|
||||
const filterNodes = (nodes: SessionNode[]): SessionNode[] => {
|
||||
@@ -1034,14 +1067,14 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
}, []);
|
||||
};
|
||||
|
||||
return sectionsForRender.map((section) => ({
|
||||
return archiveFilteredSections.map((section) => ({
|
||||
...section,
|
||||
groups: section.groups.map((group) => ({
|
||||
...group,
|
||||
sessions: filterNodes(group.sessions),
|
||||
})),
|
||||
}));
|
||||
}, [isVSCode, hasSessionSearchQuery, recentSessionIds, sectionsForRender]);
|
||||
}, [isVSCode, hasSessionSearchQuery, recentSessionIds, sectionsForRender, showArchivedSessions]);
|
||||
|
||||
const prLookupKeys = React.useMemo(() => {
|
||||
const keys = new Set<string>();
|
||||
@@ -1247,13 +1280,14 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
);
|
||||
|
||||
const toggleCollapsedGroup = React.useCallback((key: string) => {
|
||||
resetGroupSessionLimit(key);
|
||||
setCollapsedGroups((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (next.has(key)) next.delete(key);
|
||||
else next.add(key);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
}, [resetGroupSessionLimit]);
|
||||
|
||||
const prVisualStateByDirectoryBranch = React.useMemo(() => {
|
||||
const result = new Map<string, PrIndicator>();
|
||||
@@ -1287,7 +1321,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
hasSessionSearchQuery={hasSessionSearchQuery}
|
||||
normalizedSessionSearchQuery={normalizedSessionSearchQuery}
|
||||
groupSearchDataByGroup={groupSearchDataByGroup}
|
||||
expandedSessionGroups={expandedSessionGroups}
|
||||
visibleSessionCount={visibleSessionCountByGroup.get(groupKey)}
|
||||
collapsedGroups={collapsedGroups}
|
||||
hideDirectoryControls={hideDirectoryControls}
|
||||
collapsedFolderIds={collapsedFolderIds}
|
||||
@@ -1300,7 +1334,8 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
currentSessionDirectory={currentSessionDirectory}
|
||||
projectRepoStatus={projectRepoStatus}
|
||||
lastRepoStatus={lastRepoStatusRef.current}
|
||||
toggleGroupSessionLimit={toggleGroupSessionLimit}
|
||||
showMoreGroupSessions={showMoreGroupSessions}
|
||||
resetGroupSessionLimit={resetGroupSessionLimit}
|
||||
mobileVariant={mobileVariant}
|
||||
alwaysShowActions={alwaysShowSidebarActions}
|
||||
activeProjectId={activeProjectId}
|
||||
@@ -1325,7 +1360,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
hasSessionSearchQuery,
|
||||
normalizedSessionSearchQuery,
|
||||
groupSearchDataByGroup,
|
||||
expandedSessionGroups,
|
||||
visibleSessionCountByGroup,
|
||||
collapsedGroups,
|
||||
hideDirectoryControls,
|
||||
collapsedFolderIds,
|
||||
@@ -1336,7 +1371,8 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
renderSessionNode,
|
||||
currentSessionDirectory,
|
||||
projectRepoStatus,
|
||||
toggleGroupSessionLimit,
|
||||
showMoreGroupSessions,
|
||||
resetGroupSessionLimit,
|
||||
mobileVariant,
|
||||
alwaysShowSidebarActions,
|
||||
activeProjectId,
|
||||
|
||||
Reference in New Issue
Block a user