fix: refresh pending changes from chat input

Keeps pending changes state fresh even when the bar is hidden
Updates the composer when workspace changes appear or disappear
Removes duplicate refresh handling from the pending changes bar
This commit is contained in:
Bohdan Triapitsyn
2026-06-15 15:10:12 +03:00
parent 313f04e916
commit 41160ed5b2
2 changed files with 16 additions and 25 deletions
+16 -1
View File
@@ -69,6 +69,7 @@ import { buildSessionTargetOptions } from '@/sync/session-worktree-contract';
import { usePermissionStore } from '@/stores/permissionStore'; import { usePermissionStore } from '@/stores/permissionStore';
import { extractGitChangedFiles } from './changedFiles'; import { extractGitChangedFiles } from './changedFiles';
import { useI18n } from '@/lib/i18n'; import { useI18n } from '@/lib/i18n';
import { sessionEvents } from '@/lib/sessionEvents';
import { fetchResponseStyleInstruction } from '@/lib/responseStyle'; import { fetchResponseStyleInstruction } from '@/lib/responseStyle';
import { wrapSystemReminder } from '@/lib/systemReminder'; import { wrapSystemReminder } from '@/lib/systemReminder';
import { getSyncMessages } from '@/sync/sync-refs'; import { getSyncMessages } from '@/sync/sync-refs';
@@ -1044,6 +1045,8 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
const currentGitStatus = useGitStore((state) => const currentGitStatus = useGitStore((state) =>
currentDirectory ? state.directories.get(currentDirectory)?.status ?? null : null, currentDirectory ? state.directories.get(currentDirectory)?.status ?? null : null,
); );
const ensureGitStatus = useGitStore((state) => state.ensureStatus);
const fetchGitStatus = useGitStore((state) => state.fetchStatus);
const [showAbortStatus, setShowAbortStatus] = React.useState(false); const [showAbortStatus, setShowAbortStatus] = React.useState(false);
const setSessionAutoAccept = usePermissionStore((state) => state.setSessionAutoAccept); const setSessionAutoAccept = usePermissionStore((state) => state.setSessionAutoAccept);
const composerHighlightRef = React.useRef<HTMLDivElement | null>(null); const composerHighlightRef = React.useRef<HTMLDivElement | null>(null);
@@ -1065,6 +1068,19 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
setImagePreviewOpen(open); setImagePreviewOpen(open);
}, [setImagePreviewOpen]); }, [setImagePreviewOpen]);
React.useEffect(() => {
if (!currentDirectory || !runtimeGit) return;
void ensureGitStatus(currentDirectory, runtimeGit);
}, [currentDirectory, runtimeGit, ensureGitStatus]);
React.useEffect(() => {
if (!currentDirectory || !runtimeGit) return;
return sessionEvents.onGitRefreshHint((hint) => {
if (normalizePath(hint.directory) !== normalizePath(currentDirectory)) return;
void fetchGitStatus(currentDirectory, runtimeGit);
});
}, [currentDirectory, runtimeGit, fetchGitStatus]);
const handleStartReviewFlow = React.useCallback(async (execution: ReviewFlowExecution) => { const handleStartReviewFlow = React.useCallback(async (execution: ReviewFlowExecution) => {
if (!currentSessionId) return; if (!currentSessionId) return;
const directory = useSessionUIStore.getState().getDirectoryForSession(currentSessionId) || currentDirectory || ''; const directory = useSessionUIStore.getState().getDirectoryForSession(currentSessionId) || currentDirectory || '';
@@ -3556,7 +3572,6 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
); );
const selectedDraftProjectIsGitRepo = useIsGitRepo(selectedDraftProjectPath); const selectedDraftProjectIsGitRepo = useIsGitRepo(selectedDraftProjectPath);
const hasDraftBranchList = Boolean(selectedDraftProjectBranches?.all); const hasDraftBranchList = Boolean(selectedDraftProjectBranches?.all);
const fetchGitStatus = useGitStore((state) => state.fetchStatus);
const fetchBranches = useGitStore((state) => state.fetchBranches); const fetchBranches = useGitStore((state) => state.fetchBranches);
const [isDiscoveringDraftBranches, setIsDiscoveringDraftBranches] = React.useState(false); const [isDiscoveringDraftBranches, setIsDiscoveringDraftBranches] = React.useState(false);
@@ -4,8 +4,6 @@ import { useGitStore, useIsGitRepo } from '@/stores/useGitStore';
import { useUIStore } from '@/stores/useUIStore'; import { useUIStore } from '@/stores/useUIStore';
import { RuntimeAPIContext } from '@/contexts/runtimeAPIContext'; import { RuntimeAPIContext } from '@/contexts/runtimeAPIContext';
import { useMobileAppActions } from '@/apps/mobileAppContext'; import { useMobileAppActions } from '@/apps/mobileAppContext';
import { sessionEvents } from '@/lib/sessionEvents';
import { normalizePath } from '@/components/session/sidebar/utils';
import { Icon } from "@/components/icon/Icon"; import { Icon } from "@/components/icon/Icon";
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { import {
@@ -28,8 +26,6 @@ export const PendingChangesBar: React.FC = React.memo(() => {
const gitStatus = useGitStore((s) => const gitStatus = useGitStore((s) =>
currentDirectory ? s.directories.get(currentDirectory)?.status ?? null : null, currentDirectory ? s.directories.get(currentDirectory)?.status ?? null : null,
); );
const ensureStatus = useGitStore((s) => s.ensureStatus);
const fetchStatus = useGitStore((s) => s.fetchStatus);
const mobileActions = useMobileAppActions(); const mobileActions = useMobileAppActions();
// Close popover when clicking outside // Close popover when clicking outside
@@ -46,26 +42,6 @@ export const PendingChangesBar: React.FC = React.memo(() => {
return () => document.removeEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside);
}, [isExpanded]); }, [isExpanded]);
// Seed git store for currentDirectory so the bar can render independently of
// DiffView/GitView/right-sidebar mounting. ensureStatus has a 5s staleness
// gate and inFlightStatusFetchesByDirectory dedupes against concurrent callers.
React.useEffect(() => {
if (!currentDirectory || !runtime?.git) return;
void ensureStatus(currentDirectory, runtime.git);
}, [currentDirectory, runtime?.git, ensureStatus]);
// Mirror the onGitRefreshHint listener that lives in DiffView/GitView so the
// bar refreshes after mutating tools (edit/write/apply_patch/bash/...) even
// when neither of those views is open — e.g. VS Code runtime.
React.useEffect(() => {
if (!currentDirectory || !runtime?.git) return;
const git = runtime.git;
return sessionEvents.onGitRefreshHint((hint) => {
if (normalizePath(hint.directory) !== normalizePath(currentDirectory)) return;
void fetchStatus(currentDirectory, git);
});
}, [currentDirectory, runtime?.git, fetchStatus]);
const gitChangedFiles = React.useMemo<GitChangedFile[]>(() => { const gitChangedFiles = React.useMemo<GitChangedFile[]>(() => {
if (isGitRepo !== true || !gitStatus || gitStatus.isClean) return []; if (isGitRepo !== true || !gitStatus || gitStatus.isClean) return [];
return extractGitChangedFiles(gitStatus.files, gitStatus.diffStats, currentDirectory); return extractGitChangedFiles(gitStatus.files, gitStatus.diffStats, currentDirectory);