Fix hidden sidebar workspace shortcuts

This commit is contained in:
Mohamed Boudra
2026-03-12 22:33:27 +07:00
parent 1d3e551e7f
commit 2ff8041e15
3 changed files with 90 additions and 63 deletions
@@ -15,6 +15,7 @@ import { router, usePathname } from 'expo-router'
import { usePanelStore } from '@/stores/panel-store'
import { SidebarWorkspaceList } from './sidebar-workspace-list'
import { SidebarAgentListSkeleton } from './sidebar-agent-list-skeleton'
import { useSidebarShortcutModel } from '@/hooks/use-sidebar-shortcut-model'
import { useSidebarWorkspacesList } from '@/hooks/use-sidebar-workspaces-list'
import { useSidebarAnimation } from '@/contexts/sidebar-animation-context'
import { useTauriDragHandlers, useTrafficLightPadding } from '@/utils/tauri-window'
@@ -124,6 +125,8 @@ export function LeftSidebar({ selectedAgentId: _selectedAgentId }: LeftSidebarPr
serverId: activeServerId,
enabled: isOpen,
})
const { collapsedProjectKeys, shortcutIndexByWorkspaceKey, toggleProjectCollapsed } =
useSidebarShortcutModel(projects)
const {
translateX,
backdropOpacity,
@@ -353,6 +356,9 @@ export function LeftSidebar({ selectedAgentId: _selectedAgentId }: LeftSidebarPr
<SidebarWorkspaceList
isOpen={isOpen}
serverId={activeServerId}
collapsedProjectKeys={collapsedProjectKeys}
onToggleProjectCollapsed={toggleProjectCollapsed}
shortcutIndexByWorkspaceKey={shortcutIndexByWorkspaceKey}
projects={projects}
isRefreshing={isManualRefresh && isRevalidating}
onRefresh={handleRefresh}
@@ -477,6 +483,9 @@ export function LeftSidebar({ selectedAgentId: _selectedAgentId }: LeftSidebarPr
<SidebarWorkspaceList
isOpen={isOpen}
serverId={activeServerId}
collapsedProjectKeys={collapsedProjectKeys}
onToggleProjectCollapsed={toggleProjectCollapsed}
shortcutIndexByWorkspaceKey={shortcutIndexByWorkspaceKey}
projects={projects}
isRefreshing={isManualRefresh && isRevalidating}
onRefresh={handleRefresh}
@@ -59,7 +59,6 @@ import {
import { SyncedLoader } from '@/components/synced-loader'
import { useToast } from '@/contexts/toast-context'
import { useCheckoutGitActionsStore } from '@/stores/checkout-git-actions-store'
import { buildSidebarShortcutModel } from '@/utils/sidebar-shortcuts'
import { hasVisibleOrderChanged, mergeWithRemainder } from '@/utils/sidebar-reorder'
import { decideLongPressMove } from '@/utils/sidebar-gesture-arbitration'
import { confirmDialog } from '@/utils/confirm-dialog'
@@ -83,6 +82,9 @@ interface SidebarWorkspaceListProps {
isOpen?: boolean
projects: SidebarProjectEntry[]
serverId: string | null
collapsedProjectKeys: ReadonlySet<string>
onToggleProjectCollapsed: (projectKey: string) => void
shortcutIndexByWorkspaceKey: Map<string, number>
isRefreshing?: boolean
onRefresh?: () => void
onWorkspacePress?: () => void
@@ -1196,6 +1198,9 @@ export function SidebarWorkspaceList({
isOpen = true,
projects,
serverId,
collapsedProjectKeys,
onToggleProjectCollapsed,
shortcutIndexByWorkspaceKey,
isRefreshing = false,
onRefresh,
onWorkspacePress,
@@ -1205,16 +1210,9 @@ export function SidebarWorkspaceList({
const isMobile = UnistylesRuntime.breakpoint === 'xs' || UnistylesRuntime.breakpoint === 'sm'
const isNative = Platform.OS !== 'web'
const pathname = usePathname()
const [collapsedProjectKeys, setCollapsedProjectKeys] = useState<Set<string>>(new Set())
const isTauri = getIsTauri()
const altDown = useKeyboardShortcutsStore((state) => state.altDown)
const cmdOrCtrlDown = useKeyboardShortcutsStore((state) => state.cmdOrCtrlDown)
const setSidebarShortcutWorkspaceTargets = useKeyboardShortcutsStore(
(state) => state.setSidebarShortcutWorkspaceTargets
)
const setVisibleWorkspaceTargets = useKeyboardShortcutsStore(
(state) => state.setVisibleWorkspaceTargets
)
const showShortcutBadges = altDown || (isTauri && cmdOrCtrlDown)
const getProjectOrder = useSidebarOrderStore((state) => state.getProjectOrder)
@@ -1236,19 +1234,6 @@ export function SidebarWorkspaceList({
}
}, [pathname])
useEffect(() => {
setCollapsedProjectKeys((prev) => {
const validProjectKeys = new Set(projects.map((project) => project.projectKey))
const next = new Set<string>()
for (const key of prev) {
if (validProjectKeys.has(key)) {
next.add(key)
}
}
return next
})
}, [projects])
const projectIconRequests = useMemo(() => {
if (!isOpen || !serverId) {
return []
@@ -1316,44 +1301,6 @@ export function SidebarWorkspaceList({
return byProject
}, [projectIconQueries, projectIconRequests, projects, serverId])
const shortcutModel = useMemo(
() =>
buildSidebarShortcutModel({
projects,
collapsedProjectKeys,
}),
[collapsedProjectKeys, projects]
)
useEffect(() => {
setSidebarShortcutWorkspaceTargets(shortcutModel.shortcutTargets)
setVisibleWorkspaceTargets(shortcutModel.visibleTargets)
}, [
setSidebarShortcutWorkspaceTargets,
setVisibleWorkspaceTargets,
shortcutModel.shortcutTargets,
shortcutModel.visibleTargets,
])
useEffect(() => {
return () => {
setSidebarShortcutWorkspaceTargets([])
setVisibleWorkspaceTargets([])
}
}, [setSidebarShortcutWorkspaceTargets, setVisibleWorkspaceTargets])
const toggleProjectCollapsed = useCallback((projectKey: string) => {
setCollapsedProjectKeys((prev) => {
const next = new Set(prev)
if (next.has(projectKey)) {
next.delete(projectKey)
} else {
next.add(projectKey)
}
return next
})
}, [])
const handleProjectDragEnd = useCallback(
(reorderedProjects: SidebarProjectEntry[]) => {
if (!serverId) {
@@ -1437,9 +1384,9 @@ export function SidebarWorkspaceList({
serverId={serverId}
activeWorkspaceSelection={activeWorkspaceSelection}
showShortcutBadges={showShortcutBadges}
shortcutIndexByWorkspaceKey={shortcutModel.shortcutIndexByWorkspaceKey}
shortcutIndexByWorkspaceKey={shortcutIndexByWorkspaceKey}
parentGestureRef={parentGestureRef}
onToggleCollapsed={() => toggleProjectCollapsed(item.projectKey)}
onToggleCollapsed={() => onToggleProjectCollapsed(item.projectKey)}
onWorkspacePress={onWorkspacePress}
onWorkspaceReorder={handleWorkspaceReorder}
onCreateWorktree={handleCreateWorktree}
@@ -1456,12 +1403,12 @@ export function SidebarWorkspaceList({
handleCreateWorktree,
handleWorkspaceReorder,
onWorkspacePress,
onToggleProjectCollapsed,
parentGestureRef,
projectIconByProjectKey,
serverId,
shortcutModel.shortcutIndexByWorkspaceKey,
shortcutIndexByWorkspaceKey,
showShortcutBadges,
toggleProjectCollapsed,
isNative,
]
)
@@ -0,0 +1,71 @@
import { useCallback, useEffect, useMemo, useState } from 'react'
import type { SidebarProjectEntry } from '@/hooks/use-sidebar-workspaces-list'
import { useKeyboardShortcutsStore } from '@/stores/keyboard-shortcuts-store'
import { buildSidebarShortcutModel } from '@/utils/sidebar-shortcuts'
export function useSidebarShortcutModel(projects: SidebarProjectEntry[]) {
const [collapsedProjectKeys, setCollapsedProjectKeys] = useState<Set<string>>(new Set())
const setSidebarShortcutWorkspaceTargets = useKeyboardShortcutsStore(
(state) => state.setSidebarShortcutWorkspaceTargets
)
const setVisibleWorkspaceTargets = useKeyboardShortcutsStore(
(state) => state.setVisibleWorkspaceTargets
)
const shortcutModel = useMemo(
() =>
buildSidebarShortcutModel({
projects,
collapsedProjectKeys,
}),
[collapsedProjectKeys, projects]
)
useEffect(() => {
setCollapsedProjectKeys((prev) => {
const validProjectKeys = new Set(projects.map((project) => project.projectKey))
const next = new Set<string>()
for (const key of prev) {
if (validProjectKeys.has(key)) {
next.add(key)
}
}
return next
})
}, [projects])
useEffect(() => {
setSidebarShortcutWorkspaceTargets(shortcutModel.shortcutTargets)
setVisibleWorkspaceTargets(shortcutModel.visibleTargets)
}, [
setSidebarShortcutWorkspaceTargets,
setVisibleWorkspaceTargets,
shortcutModel.shortcutTargets,
shortcutModel.visibleTargets,
])
useEffect(() => {
return () => {
setSidebarShortcutWorkspaceTargets([])
setVisibleWorkspaceTargets([])
}
}, [setSidebarShortcutWorkspaceTargets, setVisibleWorkspaceTargets])
const toggleProjectCollapsed = useCallback((projectKey: string) => {
setCollapsedProjectKeys((prev) => {
const next = new Set(prev)
if (next.has(projectKey)) {
next.delete(projectKey)
} else {
next.add(projectKey)
}
return next
})
}, [])
return {
collapsedProjectKeys,
shortcutIndexByWorkspaceKey: shortcutModel.shortcutIndexByWorkspaceKey,
toggleProjectCollapsed,
}
}