Clear stale preview iframe errors (#65)
This commit is contained in:
@@ -29,19 +29,13 @@ import {
|
||||
} from "@/atoms/chatAtoms";
|
||||
import { atom, useAtom, useSetAtom, useAtomValue } from "jotai";
|
||||
import { useStreamChat } from "@/hooks/useStreamChat";
|
||||
import { useChats } from "@/hooks/useChats";
|
||||
import { selectedAppIdAtom } from "@/atoms/appAtoms";
|
||||
import { useLoadApp } from "@/hooks/useLoadApp";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { useProposal } from "@/hooks/useProposal";
|
||||
import {
|
||||
CodeProposal,
|
||||
ActionProposal,
|
||||
Proposal,
|
||||
SuggestedAction,
|
||||
ProposalResult,
|
||||
FileChange,
|
||||
SqlQuery,
|
||||
} from "@/lib/schemas";
|
||||
@@ -69,7 +63,6 @@ export function ChatInput({ chatId }: { chatId?: number }) {
|
||||
const { settings, updateSettings, isAnyProviderSetup } = useSettings();
|
||||
const { streamMessage, isStreaming, setIsStreaming, error, setError } =
|
||||
useStreamChat();
|
||||
const [selectedAppId] = useAtom(selectedAppIdAtom);
|
||||
const [showError, setShowError] = useState(true);
|
||||
const [isApproving, setIsApproving] = useState(false); // State for approving
|
||||
const [isRejecting, setIsRejecting] = useState(false); // State for rejecting
|
||||
@@ -77,8 +70,6 @@ export function ChatInput({ chatId }: { chatId?: number }) {
|
||||
const setIsPreviewOpen = useSetAtom(isPreviewOpenAtom);
|
||||
const [showTokenBar, setShowTokenBar] = useAtom(showTokenBarAtom);
|
||||
|
||||
const { refreshAppIframe } = useRunApp();
|
||||
|
||||
// Use the hook to fetch the proposal
|
||||
const {
|
||||
proposalResult,
|
||||
@@ -171,7 +162,6 @@ export function ChatInput({ chatId }: { chatId?: number }) {
|
||||
} finally {
|
||||
setIsApproving(false);
|
||||
setIsPreviewOpen(true);
|
||||
refreshAppIframe();
|
||||
|
||||
// Keep same as handleReject
|
||||
refreshProposal();
|
||||
|
||||
@@ -13,12 +13,11 @@ interface App {
|
||||
|
||||
export interface CodeViewProps {
|
||||
loading: boolean;
|
||||
error: Error | null;
|
||||
app: App | null;
|
||||
}
|
||||
|
||||
// Code view component that displays app files or status messages
|
||||
export const CodeView = ({ loading, error, app }: CodeViewProps) => {
|
||||
export const CodeView = ({ loading, app }: CodeViewProps) => {
|
||||
const selectedFile = useAtomValue(selectedFileAtom);
|
||||
const { refreshApp } = useLoadApp(app?.id ?? null);
|
||||
|
||||
@@ -26,14 +25,6 @@ export const CodeView = ({ loading, error, app }: CodeViewProps) => {
|
||||
return <div className="text-center py-4">Loading files...</div>;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="text-center py-4 text-red-500">
|
||||
Error loading files: {error.message}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!app) {
|
||||
return (
|
||||
<div className="text-center py-4 text-gray-500">No app selected</div>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { selectedAppIdAtom, appUrlAtom, appOutputAtom } from "@/atoms/appAtoms";
|
||||
import { useAtomValue, useSetAtom } from "jotai";
|
||||
import {
|
||||
selectedAppIdAtom,
|
||||
appUrlAtom,
|
||||
appOutputAtom,
|
||||
previewErrorMessageAtom,
|
||||
} from "@/atoms/appAtoms";
|
||||
import { useAtomValue, useSetAtom, useAtom } from "jotai";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
ArrowLeft,
|
||||
@@ -23,6 +28,7 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { useSettings } from "@/hooks/useSettings";
|
||||
import { useRunApp } from "@/hooks/useRunApp";
|
||||
|
||||
interface ErrorBannerProps {
|
||||
error: string | undefined;
|
||||
@@ -78,23 +84,13 @@ const ErrorBanner = ({ error, onDismiss, onAIFix }: ErrorBannerProps) => {
|
||||
};
|
||||
|
||||
// Preview iframe component
|
||||
export const PreviewIframe = ({
|
||||
loading,
|
||||
loadingErrorMessage,
|
||||
}: {
|
||||
loading: boolean;
|
||||
loadingErrorMessage: string | undefined;
|
||||
}) => {
|
||||
export const PreviewIframe = ({ loading }: { loading: boolean }) => {
|
||||
const selectedAppId = useAtomValue(selectedAppIdAtom);
|
||||
const { appUrl } = useAtomValue(appUrlAtom);
|
||||
const setAppOutput = useSetAtom(appOutputAtom);
|
||||
const { app } = useLoadApp(selectedAppId);
|
||||
|
||||
// State to trigger iframe reload
|
||||
const [reloadKey, setReloadKey] = useState(0);
|
||||
const [errorMessage, setErrorMessage] = useState<string | undefined>(
|
||||
loadingErrorMessage
|
||||
);
|
||||
const [errorMessage, setErrorMessage] = useAtom(previewErrorMessageAtom);
|
||||
const setInputValue = useSetAtom(chatInputValueAtom);
|
||||
const [availableRoutes, setAvailableRoutes] = useState<
|
||||
Array<{ path: string; label: string }>
|
||||
@@ -179,6 +175,7 @@ export const PreviewIframe = ({
|
||||
message: `Iframe error: ${errorMessage}`,
|
||||
type: "client-error",
|
||||
appId: selectedAppId!,
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
]);
|
||||
} else if (type === "pushState" || type === "replaceState") {
|
||||
@@ -204,7 +201,13 @@ export const PreviewIframe = ({
|
||||
|
||||
window.addEventListener("message", handleMessage);
|
||||
return () => window.removeEventListener("message", handleMessage);
|
||||
}, [navigationHistory, currentHistoryPosition, selectedAppId]);
|
||||
}, [
|
||||
navigationHistory,
|
||||
currentHistoryPosition,
|
||||
selectedAppId,
|
||||
errorMessage,
|
||||
setErrorMessage,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
// Update navigation buttons state
|
||||
|
||||
@@ -149,7 +149,7 @@ export function PreviewPanel() {
|
||||
const [previewMode, setPreviewMode] = useAtom(previewModeAtom);
|
||||
const selectedAppId = useAtomValue(selectedAppIdAtom);
|
||||
const [isConsoleOpen, setIsConsoleOpen] = useState(false);
|
||||
const { runApp, stopApp, restartApp, error, loading, app } = useRunApp();
|
||||
const { runApp, stopApp, restartApp, loading, app } = useRunApp();
|
||||
const runningAppIdRef = useRef<number | null>(null);
|
||||
const key = useAtomValue(previewPanelKeyAtom);
|
||||
const appOutput = useAtomValue(appOutputAtom);
|
||||
@@ -223,13 +223,9 @@ export function PreviewPanel() {
|
||||
<Panel id="content" minSize={30}>
|
||||
<div className="h-full overflow-y-auto">
|
||||
{previewMode === "preview" ? (
|
||||
<PreviewIframe
|
||||
key={key}
|
||||
loading={loading}
|
||||
loadingErrorMessage={error?.message}
|
||||
/>
|
||||
<PreviewIframe key={key} loading={loading} />
|
||||
) : (
|
||||
<CodeView loading={loading} error={error} app={app} />
|
||||
<CodeView loading={loading} app={app} />
|
||||
)}
|
||||
</div>
|
||||
</Panel>
|
||||
|
||||
Reference in New Issue
Block a user