Fix hidden sidebar workspace shortcuts
This commit is contained in:
@@ -15,6 +15,7 @@ import { router, usePathname } from 'expo-router'
|
|||||||
import { usePanelStore } from '@/stores/panel-store'
|
import { usePanelStore } from '@/stores/panel-store'
|
||||||
import { SidebarWorkspaceList } from './sidebar-workspace-list'
|
import { SidebarWorkspaceList } from './sidebar-workspace-list'
|
||||||
import { SidebarAgentListSkeleton } from './sidebar-agent-list-skeleton'
|
import { SidebarAgentListSkeleton } from './sidebar-agent-list-skeleton'
|
||||||
|
import { useSidebarShortcutModel } from '@/hooks/use-sidebar-shortcut-model'
|
||||||
import { useSidebarWorkspacesList } from '@/hooks/use-sidebar-workspaces-list'
|
import { useSidebarWorkspacesList } from '@/hooks/use-sidebar-workspaces-list'
|
||||||
import { useSidebarAnimation } from '@/contexts/sidebar-animation-context'
|
import { useSidebarAnimation } from '@/contexts/sidebar-animation-context'
|
||||||
import { useTauriDragHandlers, useTrafficLightPadding } from '@/utils/tauri-window'
|
import { useTauriDragHandlers, useTrafficLightPadding } from '@/utils/tauri-window'
|
||||||
@@ -124,6 +125,8 @@ export function LeftSidebar({ selectedAgentId: _selectedAgentId }: LeftSidebarPr
|
|||||||
serverId: activeServerId,
|
serverId: activeServerId,
|
||||||
enabled: isOpen,
|
enabled: isOpen,
|
||||||
})
|
})
|
||||||
|
const { collapsedProjectKeys, shortcutIndexByWorkspaceKey, toggleProjectCollapsed } =
|
||||||
|
useSidebarShortcutModel(projects)
|
||||||
const {
|
const {
|
||||||
translateX,
|
translateX,
|
||||||
backdropOpacity,
|
backdropOpacity,
|
||||||
@@ -353,6 +356,9 @@ export function LeftSidebar({ selectedAgentId: _selectedAgentId }: LeftSidebarPr
|
|||||||
<SidebarWorkspaceList
|
<SidebarWorkspaceList
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
serverId={activeServerId}
|
serverId={activeServerId}
|
||||||
|
collapsedProjectKeys={collapsedProjectKeys}
|
||||||
|
onToggleProjectCollapsed={toggleProjectCollapsed}
|
||||||
|
shortcutIndexByWorkspaceKey={shortcutIndexByWorkspaceKey}
|
||||||
projects={projects}
|
projects={projects}
|
||||||
isRefreshing={isManualRefresh && isRevalidating}
|
isRefreshing={isManualRefresh && isRevalidating}
|
||||||
onRefresh={handleRefresh}
|
onRefresh={handleRefresh}
|
||||||
@@ -477,6 +483,9 @@ export function LeftSidebar({ selectedAgentId: _selectedAgentId }: LeftSidebarPr
|
|||||||
<SidebarWorkspaceList
|
<SidebarWorkspaceList
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
serverId={activeServerId}
|
serverId={activeServerId}
|
||||||
|
collapsedProjectKeys={collapsedProjectKeys}
|
||||||
|
onToggleProjectCollapsed={toggleProjectCollapsed}
|
||||||
|
shortcutIndexByWorkspaceKey={shortcutIndexByWorkspaceKey}
|
||||||
projects={projects}
|
projects={projects}
|
||||||
isRefreshing={isManualRefresh && isRevalidating}
|
isRefreshing={isManualRefresh && isRevalidating}
|
||||||
onRefresh={handleRefresh}
|
onRefresh={handleRefresh}
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ import {
|
|||||||
import { SyncedLoader } from '@/components/synced-loader'
|
import { SyncedLoader } from '@/components/synced-loader'
|
||||||
import { useToast } from '@/contexts/toast-context'
|
import { useToast } from '@/contexts/toast-context'
|
||||||
import { useCheckoutGitActionsStore } from '@/stores/checkout-git-actions-store'
|
import { useCheckoutGitActionsStore } from '@/stores/checkout-git-actions-store'
|
||||||
import { buildSidebarShortcutModel } from '@/utils/sidebar-shortcuts'
|
|
||||||
import { hasVisibleOrderChanged, mergeWithRemainder } from '@/utils/sidebar-reorder'
|
import { hasVisibleOrderChanged, mergeWithRemainder } from '@/utils/sidebar-reorder'
|
||||||
import { decideLongPressMove } from '@/utils/sidebar-gesture-arbitration'
|
import { decideLongPressMove } from '@/utils/sidebar-gesture-arbitration'
|
||||||
import { confirmDialog } from '@/utils/confirm-dialog'
|
import { confirmDialog } from '@/utils/confirm-dialog'
|
||||||
@@ -83,6 +82,9 @@ interface SidebarWorkspaceListProps {
|
|||||||
isOpen?: boolean
|
isOpen?: boolean
|
||||||
projects: SidebarProjectEntry[]
|
projects: SidebarProjectEntry[]
|
||||||
serverId: string | null
|
serverId: string | null
|
||||||
|
collapsedProjectKeys: ReadonlySet<string>
|
||||||
|
onToggleProjectCollapsed: (projectKey: string) => void
|
||||||
|
shortcutIndexByWorkspaceKey: Map<string, number>
|
||||||
isRefreshing?: boolean
|
isRefreshing?: boolean
|
||||||
onRefresh?: () => void
|
onRefresh?: () => void
|
||||||
onWorkspacePress?: () => void
|
onWorkspacePress?: () => void
|
||||||
@@ -1196,6 +1198,9 @@ export function SidebarWorkspaceList({
|
|||||||
isOpen = true,
|
isOpen = true,
|
||||||
projects,
|
projects,
|
||||||
serverId,
|
serverId,
|
||||||
|
collapsedProjectKeys,
|
||||||
|
onToggleProjectCollapsed,
|
||||||
|
shortcutIndexByWorkspaceKey,
|
||||||
isRefreshing = false,
|
isRefreshing = false,
|
||||||
onRefresh,
|
onRefresh,
|
||||||
onWorkspacePress,
|
onWorkspacePress,
|
||||||
@@ -1205,16 +1210,9 @@ export function SidebarWorkspaceList({
|
|||||||
const isMobile = UnistylesRuntime.breakpoint === 'xs' || UnistylesRuntime.breakpoint === 'sm'
|
const isMobile = UnistylesRuntime.breakpoint === 'xs' || UnistylesRuntime.breakpoint === 'sm'
|
||||||
const isNative = Platform.OS !== 'web'
|
const isNative = Platform.OS !== 'web'
|
||||||
const pathname = usePathname()
|
const pathname = usePathname()
|
||||||
const [collapsedProjectKeys, setCollapsedProjectKeys] = useState<Set<string>>(new Set())
|
|
||||||
const isTauri = getIsTauri()
|
const isTauri = getIsTauri()
|
||||||
const altDown = useKeyboardShortcutsStore((state) => state.altDown)
|
const altDown = useKeyboardShortcutsStore((state) => state.altDown)
|
||||||
const cmdOrCtrlDown = useKeyboardShortcutsStore((state) => state.cmdOrCtrlDown)
|
const cmdOrCtrlDown = useKeyboardShortcutsStore((state) => state.cmdOrCtrlDown)
|
||||||
const setSidebarShortcutWorkspaceTargets = useKeyboardShortcutsStore(
|
|
||||||
(state) => state.setSidebarShortcutWorkspaceTargets
|
|
||||||
)
|
|
||||||
const setVisibleWorkspaceTargets = useKeyboardShortcutsStore(
|
|
||||||
(state) => state.setVisibleWorkspaceTargets
|
|
||||||
)
|
|
||||||
const showShortcutBadges = altDown || (isTauri && cmdOrCtrlDown)
|
const showShortcutBadges = altDown || (isTauri && cmdOrCtrlDown)
|
||||||
|
|
||||||
const getProjectOrder = useSidebarOrderStore((state) => state.getProjectOrder)
|
const getProjectOrder = useSidebarOrderStore((state) => state.getProjectOrder)
|
||||||
@@ -1236,19 +1234,6 @@ export function SidebarWorkspaceList({
|
|||||||
}
|
}
|
||||||
}, [pathname])
|
}, [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(() => {
|
const projectIconRequests = useMemo(() => {
|
||||||
if (!isOpen || !serverId) {
|
if (!isOpen || !serverId) {
|
||||||
return []
|
return []
|
||||||
@@ -1316,44 +1301,6 @@ export function SidebarWorkspaceList({
|
|||||||
return byProject
|
return byProject
|
||||||
}, [projectIconQueries, projectIconRequests, projects, serverId])
|
}, [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(
|
const handleProjectDragEnd = useCallback(
|
||||||
(reorderedProjects: SidebarProjectEntry[]) => {
|
(reorderedProjects: SidebarProjectEntry[]) => {
|
||||||
if (!serverId) {
|
if (!serverId) {
|
||||||
@@ -1437,9 +1384,9 @@ export function SidebarWorkspaceList({
|
|||||||
serverId={serverId}
|
serverId={serverId}
|
||||||
activeWorkspaceSelection={activeWorkspaceSelection}
|
activeWorkspaceSelection={activeWorkspaceSelection}
|
||||||
showShortcutBadges={showShortcutBadges}
|
showShortcutBadges={showShortcutBadges}
|
||||||
shortcutIndexByWorkspaceKey={shortcutModel.shortcutIndexByWorkspaceKey}
|
shortcutIndexByWorkspaceKey={shortcutIndexByWorkspaceKey}
|
||||||
parentGestureRef={parentGestureRef}
|
parentGestureRef={parentGestureRef}
|
||||||
onToggleCollapsed={() => toggleProjectCollapsed(item.projectKey)}
|
onToggleCollapsed={() => onToggleProjectCollapsed(item.projectKey)}
|
||||||
onWorkspacePress={onWorkspacePress}
|
onWorkspacePress={onWorkspacePress}
|
||||||
onWorkspaceReorder={handleWorkspaceReorder}
|
onWorkspaceReorder={handleWorkspaceReorder}
|
||||||
onCreateWorktree={handleCreateWorktree}
|
onCreateWorktree={handleCreateWorktree}
|
||||||
@@ -1456,12 +1403,12 @@ export function SidebarWorkspaceList({
|
|||||||
handleCreateWorktree,
|
handleCreateWorktree,
|
||||||
handleWorkspaceReorder,
|
handleWorkspaceReorder,
|
||||||
onWorkspacePress,
|
onWorkspacePress,
|
||||||
|
onToggleProjectCollapsed,
|
||||||
parentGestureRef,
|
parentGestureRef,
|
||||||
projectIconByProjectKey,
|
projectIconByProjectKey,
|
||||||
serverId,
|
serverId,
|
||||||
shortcutModel.shortcutIndexByWorkspaceKey,
|
shortcutIndexByWorkspaceKey,
|
||||||
showShortcutBadges,
|
showShortcutBadges,
|
||||||
toggleProjectCollapsed,
|
|
||||||
isNative,
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user