refactor(sidebar): remove dead directoryStatus probe artifact (#1660)
Commit 7205d7a3 replaced runtime directory probing with buildKnownSessionDirectories
filtering, but left the hook, prop, state, and UI checks as a transitional artifact.
- Delete useDirectoryStatusProbe.ts
- Remove directoryStatus state/prop from SessionSidebar, SessionGroupSection, SessionNodeItem
- Remove isMissingDirectory checks, opacity-75 styling, and disabled states
- Simplify handleSessionSelect signature
- Update sidebar DOCUMENTATION.md
Co-authored-by: Leonid Skorobogatyy <bash@opencode.itc.local>
This commit is contained in:
committed by
GitHub
co-authored by
Leonid Skorobogatyy
parent
a73090f396
commit
d909c43979
@@ -178,9 +178,6 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
|||||||
const [editTitle, setEditTitle] = React.useState('');
|
const [editTitle, setEditTitle] = React.useState('');
|
||||||
const [editingProjectDialogId, setEditingProjectDialogId] = React.useState<string | null>(null);
|
const [editingProjectDialogId, setEditingProjectDialogId] = React.useState<string | null>(null);
|
||||||
const [expandedParents, setExpandedParents] = React.useState<Set<string>>(new Set());
|
const [expandedParents, setExpandedParents] = React.useState<Set<string>>(new Set());
|
||||||
const [directoryStatus] = React.useState<Map<string, 'unknown' | 'exists' | 'missing'>>(
|
|
||||||
() => new Map(),
|
|
||||||
);
|
|
||||||
const safeStorage = React.useMemo(() => getSafeStorage(), []);
|
const safeStorage = React.useMemo(() => getSafeStorage(), []);
|
||||||
const [collapsedProjects, setCollapsedProjects] = React.useState<Set<string>>(new Set());
|
const [collapsedProjects, setCollapsedProjects] = React.useState<Set<string>>(new Set());
|
||||||
|
|
||||||
@@ -1233,7 +1230,6 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
|||||||
groupDirectory={groupDirectory}
|
groupDirectory={groupDirectory}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
archivedBucket={archivedBucket}
|
archivedBucket={archivedBucket}
|
||||||
directoryStatus={directoryStatus}
|
|
||||||
currentSessionId={currentSessionId}
|
currentSessionId={currentSessionId}
|
||||||
pinnedSessionIds={pinnedSessionIds}
|
pinnedSessionIds={pinnedSessionIds}
|
||||||
expandedParents={expandedParents}
|
expandedParents={expandedParents}
|
||||||
@@ -1272,7 +1268,6 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
|||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
directoryStatus,
|
|
||||||
currentSessionId,
|
currentSessionId,
|
||||||
pinnedSessionIds,
|
pinnedSessionIds,
|
||||||
expandedParents,
|
expandedParents,
|
||||||
|
|||||||
@@ -39,7 +39,6 @@
|
|||||||
- `hooks/useSessionActions.ts`: Centralizes session row actions (select/open, rename, share/unshare, archive/delete, confirmations).
|
- `hooks/useSessionActions.ts`: Centralizes session row actions (select/open, rename, share/unshare, archive/delete, confirmations).
|
||||||
- `hooks/useSessionSearchEffects.ts`: Handles search open/close UX and input focus behavior.
|
- `hooks/useSessionSearchEffects.ts`: Handles search open/close UX and input focus behavior.
|
||||||
- `hooks/useSessionPrefetch.ts`: Prefetches messages for nearby/active sessions to improve perceived load speed.
|
- `hooks/useSessionPrefetch.ts`: Prefetches messages for nearby/active sessions to improve perceived load speed.
|
||||||
- `hooks/useDirectoryStatusProbe.ts`: Probes and caches directory existence status for session/path indicators.
|
|
||||||
- `hooks/useSessionGrouping.ts`: Builds grouped session structures and search text/filter helpers.
|
- `hooks/useSessionGrouping.ts`: Builds grouped session structures and search text/filter helpers.
|
||||||
- `hooks/useSessionSidebarSections.ts`: Composes final per-project sections and group search metadata for rendering.
|
- `hooks/useSessionSidebarSections.ts`: Composes final per-project sections and group search metadata for rendering.
|
||||||
- `hooks/useProjectSessionSelection.ts`: Resolves active/current project-session selection logic and session-directory context.
|
- `hooks/useProjectSessionSelection.ts`: Resolves active/current project-session selection logic and session-directory context.
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ type Props = {
|
|||||||
groupDirectory?: string | null;
|
groupDirectory?: string | null;
|
||||||
projectId?: string | null;
|
projectId?: string | null;
|
||||||
archivedBucket?: boolean;
|
archivedBucket?: boolean;
|
||||||
directoryStatus: Map<string, 'unknown' | 'exists' | 'missing'>;
|
|
||||||
currentSessionId: string | null;
|
currentSessionId: string | null;
|
||||||
pinnedSessionIds: Set<string>;
|
pinnedSessionIds: Set<string>;
|
||||||
expandedParents: Set<string>;
|
expandedParents: Set<string>;
|
||||||
@@ -65,7 +64,7 @@ type Props = {
|
|||||||
handleSaveEdit: () => void;
|
handleSaveEdit: () => void;
|
||||||
handleCancelEdit: () => void;
|
handleCancelEdit: () => void;
|
||||||
toggleParent: (expansionKey: string) => void;
|
toggleParent: (expansionKey: string) => void;
|
||||||
handleSessionSelect: (sessionId: string, sessionDirectory: string | null, isMissingDirectory: boolean, projectId?: string | null) => void;
|
handleSessionSelect: (sessionId: string, sessionDirectory: string | null, projectId?: string | null) => void;
|
||||||
handleSessionDoubleClick: (sessionId: string, sessionTitle: string) => void;
|
handleSessionDoubleClick: (sessionId: string, sessionTitle: string) => void;
|
||||||
togglePinnedSession: (sessionId: string) => void;
|
togglePinnedSession: (sessionId: string) => void;
|
||||||
handleShareSession: (session: Session) => void;
|
handleShareSession: (session: Session) => void;
|
||||||
@@ -202,7 +201,6 @@ const areEqual = (prev: Props, next: Props): boolean => {
|
|||||||
const nextDirectory = normalizePath((nextSession as Session & { directory?: string | null }).directory ?? null)
|
const nextDirectory = normalizePath((nextSession as Session & { directory?: string | null }).directory ?? null)
|
||||||
?? normalizePath(next.groupDirectory ?? null);
|
?? normalizePath(next.groupDirectory ?? null);
|
||||||
if (prevDirectory !== nextDirectory) return false;
|
if (prevDirectory !== nextDirectory) return false;
|
||||||
if ((prevDirectory ? prev.directoryStatus.get(prevDirectory) : null) !== (nextDirectory ? next.directoryStatus.get(nextDirectory) : null)) return false;
|
|
||||||
|
|
||||||
if ((prev.secondaryMeta?.projectLabel ?? null) !== (next.secondaryMeta?.projectLabel ?? null)) return false;
|
if ((prev.secondaryMeta?.projectLabel ?? null) !== (next.secondaryMeta?.projectLabel ?? null)) return false;
|
||||||
if ((prev.secondaryMeta?.branchLabel ?? null) !== (next.secondaryMeta?.branchLabel ?? null)) return false;
|
if ((prev.secondaryMeta?.branchLabel ?? null) !== (next.secondaryMeta?.branchLabel ?? null)) return false;
|
||||||
@@ -222,7 +220,6 @@ function SessionNodeItemComponent(props: Props): React.ReactNode {
|
|||||||
groupDirectory,
|
groupDirectory,
|
||||||
projectId,
|
projectId,
|
||||||
archivedBucket = false,
|
archivedBucket = false,
|
||||||
directoryStatus,
|
|
||||||
currentSessionId,
|
currentSessionId,
|
||||||
pinnedSessionIds,
|
pinnedSessionIds,
|
||||||
expandedParents,
|
expandedParents,
|
||||||
@@ -351,8 +348,6 @@ function SessionNodeItemComponent(props: Props): React.ReactNode {
|
|||||||
);
|
);
|
||||||
const sessionStatus = useGlobalSessionStatus(session.id);
|
const sessionStatus = useGlobalSessionStatus(session.id);
|
||||||
const sessionPermissions = useSessionPermissions(session.id, sessionDirectory ?? undefined);
|
const sessionPermissions = useSessionPermissions(session.id, sessionDirectory ?? undefined);
|
||||||
const directoryState = sessionDirectory ? directoryStatus.get(sessionDirectory) : null;
|
|
||||||
const isMissingDirectory = directoryState === 'missing';
|
|
||||||
const isActive = currentSessionId === session.id;
|
const isActive = currentSessionId === session.id;
|
||||||
const sessionTitle = resolvedSession.title || t('sessions.sidebar.session.untitled');
|
const sessionTitle = resolvedSession.title || t('sessions.sidebar.session.untitled');
|
||||||
const hasChildren = node.children.length > 0;
|
const hasChildren = node.children.length > 0;
|
||||||
@@ -718,7 +713,7 @@ function SessionNodeItemComponent(props: Props): React.ReactNode {
|
|||||||
toggleRowSelected(session.id, sessionDirectory ?? null, collectNodeDescendantIds(node));
|
toggleRowSelected(session.id, sessionDirectory ?? null, collectNodeDescendantIds(node));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handleSessionSelect(session.id, sessionDirectory, isMissingDirectory, projectId);
|
handleSessionSelect(session.id, sessionDirectory, projectId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRowMouseDown = (event: React.MouseEvent<HTMLButtonElement>) => {
|
const handleRowMouseDown = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
@@ -955,7 +950,6 @@ function SessionNodeItemComponent(props: Props): React.ReactNode {
|
|||||||
// stays put.
|
// stays put.
|
||||||
'-ml-3',
|
'-ml-3',
|
||||||
depth > 0 ? 'pl-[32px]' : 'pl-[18px]',
|
depth > 0 ? 'pl-[32px]' : 'pl-[18px]',
|
||||||
isMissingDirectory ? 'opacity-75' : '',
|
|
||||||
// Active (currently open) session gets a subtle primary tint;
|
// Active (currently open) session gets a subtle primary tint;
|
||||||
// multi-select highlight takes precedence when both apply.
|
// multi-select highlight takes precedence when both apply.
|
||||||
isActive && !isRowSelected && 'bg-primary/10',
|
isActive && !isRowSelected && 'bg-primary/10',
|
||||||
@@ -972,18 +966,17 @@ function SessionNodeItemComponent(props: Props): React.ReactNode {
|
|||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={isMissingDirectory}
|
onPointerDown={handleRowPointerDown}
|
||||||
onPointerDown={handleRowPointerDown}
|
onPointerUp={handleRowPointerEnd}
|
||||||
onPointerUp={handleRowPointerEnd}
|
onPointerCancel={handleRowPointerEnd}
|
||||||
onPointerCancel={handleRowPointerEnd}
|
onMouseDown={handleRowMouseDown}
|
||||||
onMouseDown={handleRowMouseDown}
|
onClick={(event) => handleRowSelect(event)}
|
||||||
onClick={(event) => handleRowSelect(event)}
|
|
||||||
onDoubleClick={(e) => {
|
onDoubleClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleSessionDoubleClick(session.id, sessionTitle);
|
handleSessionDoubleClick(session.id, sessionTitle);
|
||||||
}}
|
}}
|
||||||
className={cn(
|
className={cn(
|
||||||
'flex min-w-0 flex-1 cursor-pointer flex-col gap-0 overflow-hidden rounded-md text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 text-foreground select-none disabled:cursor-not-allowed transition-[padding]',
|
'flex min-w-0 flex-1 cursor-pointer flex-col gap-0 overflow-hidden rounded-md text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 text-foreground select-none transition-[padding]',
|
||||||
isTouchPressed && 'bg-interactive-hover/70',
|
isTouchPressed && 'bg-interactive-hover/70',
|
||||||
alwaysShowActions
|
alwaysShowActions
|
||||||
? (isVSCode ? revealPaddingClass : alwaysActionPaddingClass)
|
? (isVSCode ? revealPaddingClass : alwaysActionPaddingClass)
|
||||||
@@ -1037,19 +1030,18 @@ function SessionNodeItemComponent(props: Props): React.ReactNode {
|
|||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={isMissingDirectory}
|
onPointerDown={handleRowPointerDown}
|
||||||
onPointerDown={handleRowPointerDown}
|
onPointerUp={handleRowPointerEnd}
|
||||||
onPointerUp={handleRowPointerEnd}
|
onPointerCancel={handleRowPointerEnd}
|
||||||
onPointerCancel={handleRowPointerEnd}
|
onMouseDown={handleRowMouseDown}
|
||||||
onMouseDown={handleRowMouseDown}
|
onClick={(event) => handleRowSelect(event)}
|
||||||
onClick={(event) => handleRowSelect(event)}
|
|
||||||
onDoubleClick={(e) => {
|
onDoubleClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleSessionDoubleClick(session.id, sessionTitle);
|
handleSessionDoubleClick(session.id, sessionTitle);
|
||||||
}}
|
}}
|
||||||
className={cn(
|
className={cn(
|
||||||
'flex min-w-0 flex-1 cursor-pointer flex-col gap-0 overflow-hidden rounded-md text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 text-foreground select-none disabled:cursor-not-allowed transition-[padding]',
|
'flex min-w-0 flex-1 cursor-pointer flex-col gap-0 overflow-hidden rounded-md text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 text-foreground select-none transition-[padding]',
|
||||||
isTouchPressed && 'bg-interactive-hover/70',
|
isTouchPressed && 'bg-interactive-hover/70',
|
||||||
alwaysShowActions
|
alwaysShowActions
|
||||||
? (isVSCode ? revealPaddingClass : alwaysActionPaddingClass)
|
? (isVSCode ? revealPaddingClass : alwaysActionPaddingClass)
|
||||||
: revealPaddingClass
|
: revealPaddingClass
|
||||||
|
|||||||
@@ -1,187 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import type { Session } from '@opencode-ai/sdk/v2';
|
|
||||||
import { opencodeClient } from '@/lib/opencode/client';
|
|
||||||
import { mapWithConcurrency } from '@/lib/concurrency';
|
|
||||||
import { normalizePath } from '../utils';
|
|
||||||
|
|
||||||
type ProjectLike = { path: string };
|
|
||||||
|
|
||||||
type DirectoryStatusValue = 'unknown' | 'exists' | 'missing';
|
|
||||||
|
|
||||||
type Args = {
|
|
||||||
sortedSessions: Session[];
|
|
||||||
projects: ProjectLike[];
|
|
||||||
directoryStatus: Map<string, DirectoryStatusValue>;
|
|
||||||
setDirectoryStatus: React.Dispatch<React.SetStateAction<Map<string, DirectoryStatusValue>>>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const PROBE_CONCURRENCY = 3;
|
|
||||||
const MISSING_CACHE_KEY = 'oc.directoryProbe.missing';
|
|
||||||
// Re-probe missing directories periodically in case they're recreated
|
|
||||||
const MISSING_REPROBE_MS = 10 * 60 * 1000; // 10 minutes
|
|
||||||
|
|
||||||
type MissingCache = Record<string, number>; // directory -> timestamp
|
|
||||||
|
|
||||||
function loadMissingCache(): MissingCache {
|
|
||||||
try {
|
|
||||||
const raw = localStorage.getItem(MISSING_CACHE_KEY);
|
|
||||||
if (!raw) return {};
|
|
||||||
return JSON.parse(raw) as MissingCache;
|
|
||||||
} catch {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveMissingCache(cache: MissingCache): void {
|
|
||||||
try {
|
|
||||||
localStorage.setItem(MISSING_CACHE_KEY, JSON.stringify(cache));
|
|
||||||
} catch {
|
|
||||||
// ignore quota errors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function probeDirectory(directory: string): Promise<DirectoryStatusValue> {
|
|
||||||
try {
|
|
||||||
await opencodeClient.listLocalDirectory(directory);
|
|
||||||
return 'exists';
|
|
||||||
} catch (error) {
|
|
||||||
const looksLikeSdkWorktree =
|
|
||||||
directory.includes('/opencode/worktree/') ||
|
|
||||||
directory.includes('/.opencode/data/worktree/') ||
|
|
||||||
directory.includes('/.local/share/opencode/worktree/');
|
|
||||||
|
|
||||||
const reachable = await opencodeClient.probeDirectory(directory).catch(() => false);
|
|
||||||
if (reachable) {
|
|
||||||
return 'exists';
|
|
||||||
}
|
|
||||||
|
|
||||||
const message = error instanceof Error ? error.message.toLowerCase() : '';
|
|
||||||
const definitelyMissing =
|
|
||||||
message.includes('enoent') ||
|
|
||||||
message.includes('not found') ||
|
|
||||||
message.includes('does not exist') ||
|
|
||||||
message.includes('no such file');
|
|
||||||
|
|
||||||
if (definitelyMissing || looksLikeSdkWorktree) {
|
|
||||||
return 'missing';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'unknown';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useDirectoryStatusProbe = ({
|
|
||||||
sortedSessions,
|
|
||||||
projects,
|
|
||||||
directoryStatus,
|
|
||||||
setDirectoryStatus,
|
|
||||||
}: Args): void => {
|
|
||||||
const directoryStatusRef = React.useRef<Map<string, DirectoryStatusValue>>(new Map());
|
|
||||||
const probeInFlightRef = React.useRef(false);
|
|
||||||
const missingCacheRef = React.useRef<MissingCache>(loadMissingCache());
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
directoryStatusRef.current = directoryStatus;
|
|
||||||
}, [directoryStatus]);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const directories = new Set<string>();
|
|
||||||
const normalizedProjectRoots = new Set<string>();
|
|
||||||
sortedSessions.forEach((session) => {
|
|
||||||
const dir = normalizePath((session as Session & { directory?: string | null }).directory ?? null);
|
|
||||||
if (dir) directories.add(dir);
|
|
||||||
});
|
|
||||||
projects.forEach((project) => {
|
|
||||||
const normalized = normalizePath(project.path);
|
|
||||||
if (normalized) {
|
|
||||||
directories.add(normalized);
|
|
||||||
normalizedProjectRoots.add(normalized);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const now = Date.now();
|
|
||||||
const missingCache = missingCacheRef.current;
|
|
||||||
const toProbe: string[] = [];
|
|
||||||
const preseeded = new Map<string, DirectoryStatusValue>();
|
|
||||||
|
|
||||||
for (const directory of directories) {
|
|
||||||
const isProjectRoot = normalizedProjectRoots.has(directory);
|
|
||||||
const known = directoryStatusRef.current.get(directory);
|
|
||||||
if (known === 'exists') continue;
|
|
||||||
|
|
||||||
const cachedAt = missingCache[directory];
|
|
||||||
if (known === 'missing') {
|
|
||||||
if (isProjectRoot) {
|
|
||||||
toProbe.push(directory);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (cachedAt && now - cachedAt < MISSING_REPROBE_MS) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
toProbe.push(directory);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use cached "missing" status if fresh enough — skip the HTTP probe
|
|
||||||
if (!isProjectRoot && cachedAt && now - cachedAt < MISSING_REPROBE_MS) {
|
|
||||||
preseeded.set(directory, 'missing');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
toProbe.push(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply preseeded missing statuses immediately (no HTTP call)
|
|
||||||
if (preseeded.size > 0) {
|
|
||||||
setDirectoryStatus((prev) => {
|
|
||||||
let changed = false;
|
|
||||||
const next = new Map(prev);
|
|
||||||
for (const [dir, status] of preseeded) {
|
|
||||||
if (next.get(dir) !== status) {
|
|
||||||
next.set(dir, status);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changed ? next : prev;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toProbe.length === 0 || probeInFlightRef.current) return;
|
|
||||||
probeInFlightRef.current = true;
|
|
||||||
|
|
||||||
let cancelled = false;
|
|
||||||
let cacheChanged = false;
|
|
||||||
|
|
||||||
void mapWithConcurrency(toProbe, PROBE_CONCURRENCY, async (directory) => {
|
|
||||||
const status = await probeDirectory(directory);
|
|
||||||
|
|
||||||
// Update missing cache
|
|
||||||
if (status === 'missing') {
|
|
||||||
missingCache[directory] = Date.now();
|
|
||||||
cacheChanged = true;
|
|
||||||
} else if (missingCache[directory]) {
|
|
||||||
delete missingCache[directory];
|
|
||||||
cacheChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cancelled) {
|
|
||||||
setDirectoryStatus((prev) => {
|
|
||||||
if (prev.get(directory) === status) return prev;
|
|
||||||
const next = new Map(prev);
|
|
||||||
next.set(directory, status);
|
|
||||||
return next;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return { directory, status };
|
|
||||||
}).finally(() => {
|
|
||||||
probeInFlightRef.current = false;
|
|
||||||
if (cacheChanged) {
|
|
||||||
saveMissingCache(missingCache);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
cancelled = true;
|
|
||||||
};
|
|
||||||
}, [sortedSessions, projects, setDirectoryStatus]);
|
|
||||||
};
|
|
||||||
@@ -16,7 +16,7 @@ type Args = {
|
|||||||
activeSessionByProject: Map<string, string>;
|
activeSessionByProject: Map<string, string>;
|
||||||
setActiveSessionByProject: React.Dispatch<React.SetStateAction<Map<string, string>>>;
|
setActiveSessionByProject: React.Dispatch<React.SetStateAction<Map<string, string>>>;
|
||||||
currentSessionId: string | null;
|
currentSessionId: string | null;
|
||||||
handleSessionSelect: (sessionId: string, sessionDirectory: string | null, isMissingDirectory: boolean, projectId?: string | null) => void;
|
handleSessionSelect: (sessionId: string, sessionDirectory: string | null, projectId?: string | null) => void;
|
||||||
newSessionDraftOpen: boolean;
|
newSessionDraftOpen: boolean;
|
||||||
mobileVariant: boolean;
|
mobileVariant: boolean;
|
||||||
openNewSessionDraft: (options?: { directoryOverride?: string | null }) => void;
|
openNewSessionDraft: (options?: { directoryOverride?: string | null }) => void;
|
||||||
@@ -139,7 +139,7 @@ export const useProjectSessionSelection = (args: Args): { currentSessionDirector
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const targetDirectory = projectMap.get(targetSessionId)?.directory ?? null;
|
const targetDirectory = projectMap.get(targetSessionId)?.directory ?? null;
|
||||||
handleSessionSelect(targetSessionId, targetDirectory, false, activeProjectId);
|
handleSessionSelect(targetSessionId, targetDirectory, activeProjectId);
|
||||||
}, [
|
}, [
|
||||||
activeProjectId,
|
activeProjectId,
|
||||||
activeSessionByProject,
|
activeSessionByProject,
|
||||||
|
|||||||
@@ -64,11 +64,7 @@ export const useSessionActions = (args: Args) => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleSessionSelect = React.useCallback(
|
const handleSessionSelect = React.useCallback(
|
||||||
(sessionId: string, sessionDirectory?: string | null, disabled?: boolean, projectId?: string | null) => {
|
(sessionId: string, sessionDirectory?: string | null, projectId?: string | null) => {
|
||||||
if (disabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const resetSessionSearch = () => {
|
const resetSessionSearch = () => {
|
||||||
if (!args.isSessionSearchOpen && args.sessionSearchQuery.length === 0) {
|
if (!args.isSessionSearchOpen && args.sessionSearchQuery.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user