- {isNotMainBranch && (
+ {/* If the version pane is open, it's expected to not always be on the main branch. */}
+ {isNotMainBranch && !isVersionPaneOpen && (
@@ -138,9 +131,9 @@ export function ChatHeader({
variant="outline"
size="sm"
onClick={handleCheckoutMainBranch}
- disabled={checkingOutMain || branchInfoLoading}
+ disabled={isCheckingOutVersion || branchInfoLoading}
>
- {checkingOutMain ? "Checking out..." : "Switch to main branch"}
+ {isCheckingOutVersion ? "Checking out..." : "Switch to main branch"}
)}
diff --git a/src/components/chat/VersionPane.tsx b/src/components/chat/VersionPane.tsx
index 81adaa7..6a521d4 100644
--- a/src/components/chat/VersionPane.tsx
+++ b/src/components/chat/VersionPane.tsx
@@ -4,9 +4,9 @@ import { useVersions } from "@/hooks/useVersions";
import { formatDistanceToNow } from "date-fns";
import { RotateCcw, X } from "lucide-react";
import type { Version } from "@/ipc/ipc_types";
-import { IpcClient } from "@/ipc/ipc_client";
import { cn } from "@/lib/utils";
-import { useEffect } from "react";
+import { useEffect, useRef, useState } from "react";
+import { useCheckoutVersion } from "@/hooks/useCheckoutVersion";
interface VersionPaneProps {
isVisible: boolean;
@@ -15,31 +15,69 @@ interface VersionPaneProps {
export function VersionPane({ isVisible, onClose }: VersionPaneProps) {
const appId = useAtomValue(selectedAppIdAtom);
- const { versions, loading, refreshVersions, revertVersion } =
- useVersions(appId);
+ const {
+ versions: liveVersions,
+ refreshVersions,
+ revertVersion,
+ } = useVersions(appId);
const [selectedVersionId, setSelectedVersionId] = useAtom(
selectedVersionIdAtom,
);
+ const { checkoutVersion, isCheckingOutVersion } = useCheckoutVersion();
+ const wasVisibleRef = useRef(false);
+ const [cachedVersions, setCachedVersions] = useState([]);
+
useEffect(() => {
- async function updateVersions() {
- // Refresh versions in case the user updated versions outside of the app
- // (e.g. manually using git).
- // Avoid loading state which causes brief flash of loading state.
+ async function updatePaneState() {
+ // When pane becomes visible after being closed
+ if (isVisible && !wasVisibleRef.current) {
+ if (appId) {
+ await refreshVersions();
+ setCachedVersions(liveVersions);
+ }
+ }
+
+ // Reset when closing
if (!isVisible && selectedVersionId) {
setSelectedVersionId(null);
- await IpcClient.getInstance().checkoutVersion({
- appId: appId!,
- versionId: "main",
- });
+ if (appId) {
+ await checkoutVersion({ appId, versionId: "main" });
+ }
}
- refreshVersions();
+
+ wasVisibleRef.current = isVisible;
}
- updateVersions();
- }, [isVisible, refreshVersions]);
+ updatePaneState();
+ }, [
+ isVisible,
+ selectedVersionId,
+ setSelectedVersionId,
+ appId,
+ checkoutVersion,
+ refreshVersions,
+ liveVersions,
+ ]);
+
+ // Initial load of cached versions when live versions become available
+ useEffect(() => {
+ if (isVisible && liveVersions.length > 0 && cachedVersions.length === 0) {
+ setCachedVersions(liveVersions);
+ }
+ }, [isVisible, liveVersions, cachedVersions.length]);
+
if (!isVisible) {
return null;
}
+ const handleVersionClick = async (versionOid: string) => {
+ if (appId) {
+ setSelectedVersionId(versionOid);
+ await checkoutVersion({ appId, versionId: versionOid });
+ }
+ };
+
+ const versions = cachedVersions.length > 0 ? cachedVersions : liveVersions;
+
return (