diff --git a/src/components/preview_panel/PreviewPanel.tsx b/src/components/preview_panel/PreviewPanel.tsx index ee65537..96c236d 100644 --- a/src/components/preview_panel/PreviewPanel.tsx +++ b/src/components/preview_panel/PreviewPanel.tsx @@ -5,6 +5,7 @@ import { previewPanelKeyAtom, selectedAppIdAtom, } from "../../atoms/appAtoms"; +import { IpcClient } from "@/ipc/ipc_client"; import { CodeView } from "./CodeView"; import { PreviewIframe } from "./PreviewIframe"; @@ -17,6 +18,7 @@ import { MoreVertical, Cog, Power, + Trash2, } from "lucide-react"; import { motion } from "framer-motion"; import { useEffect, useRef, useState, useCallback } from "react"; @@ -29,6 +31,8 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { showError, showSuccess } from "@/lib/toast"; +import { useMutation } from "@tanstack/react-query"; type PreviewMode = "preview" | "code"; @@ -37,6 +41,7 @@ interface PreviewHeaderProps { setPreviewMode: (mode: PreviewMode) => void; onRestart: () => void; onCleanRestart: () => void; + onClearSessionData: () => void; } interface ConsoleHeaderProps { @@ -51,6 +56,7 @@ const PreviewHeader = ({ setPreviewMode, onRestart, onCleanRestart, + onClearSessionData, }: PreviewHeaderProps) => (
@@ -111,6 +117,15 @@ const PreviewHeader = ({
+ + +
+ Clear Preview Data + + Clears cookies and local storage for the app preview + +
+
@@ -146,7 +161,8 @@ export function PreviewPanel() { const [previewMode, setPreviewMode] = useAtom(previewModeAtom); const selectedAppId = useAtomValue(selectedAppIdAtom); const [isConsoleOpen, setIsConsoleOpen] = useState(false); - const { runApp, stopApp, restartApp, loading, app } = useRunApp(); + const { runApp, stopApp, restartApp, loading, app, refreshAppIframe } = + useRunApp(); const runningAppIdRef = useRef(null); const key = useAtomValue(previewPanelKeyAtom); const appOutput = useAtomValue(appOutputAtom); @@ -163,6 +179,29 @@ export function PreviewPanel() { restartApp({ removeNodeModules: true }); }, [restartApp]); + const useClearSessionData = () => { + return useMutation({ + mutationFn: () => { + const ipcClient = IpcClient.getInstance(); + return ipcClient.clearSessionData(); + }, + onSuccess: async () => { + await refreshAppIframe(); + showSuccess("Preview data cleared"); + // Optionally invalidate relevant queries + }, + onError: (error) => { + showError(`Error clearing preview data: ${error}`); + }, + }); + }; + + const { mutate: clearSessionData } = useClearSessionData(); + + const handleClearSessionData = useCallback(() => { + clearSessionData(); + }, [selectedAppId, clearSessionData]); + useEffect(() => { const previousAppId = runningAppIdRef.current; @@ -214,6 +253,7 @@ export function PreviewPanel() { setPreviewMode={setPreviewMode} onRestart={handleRestart} onCleanRestart={handleCleanRestart} + onClearSessionData={handleClearSessionData} />
diff --git a/src/ipc/handlers/session_handlers.ts b/src/ipc/handlers/session_handlers.ts new file mode 100644 index 0000000..6947575 --- /dev/null +++ b/src/ipc/handlers/session_handlers.ts @@ -0,0 +1,12 @@ +import { ipcMain, session } from "electron"; + +export const registerSessionHandlers = () => { + ipcMain.handle("clear-session-data", async (_event) => { + const defaultAppSession = session.defaultSession; + + await defaultAppSession.clearStorageData({ + storages: ["cookies", "localstorage"], + }); + console.info(`[IPC] All session data cleared for default session`); + }); +}; diff --git a/src/ipc/ipc_client.ts b/src/ipc/ipc_client.ts index db98a68..89d0c77 100644 --- a/src/ipc/ipc_client.ts +++ b/src/ipc/ipc_client.ts @@ -821,4 +821,8 @@ export class IpcClient { public async renameBranch(params: RenameBranchParams): Promise { await this.ipcRenderer.invoke("rename-branch", params); } + + async clearSessionData(): Promise { + return this.ipcRenderer.invoke("clear-session-data"); + } } diff --git a/src/ipc/ipc_host.ts b/src/ipc/ipc_host.ts index b02f58c..efbffe7 100644 --- a/src/ipc/ipc_host.ts +++ b/src/ipc/ipc_host.ts @@ -17,6 +17,7 @@ import { registerVersionHandlers } from "./handlers/version_handlers"; import { registerLanguageModelHandlers } from "./handlers/language_model_handlers"; import { registerReleaseNoteHandlers } from "./handlers/release_note_handlers"; import { registerImportHandlers } from "./handlers/import_handlers"; +import { registerSessionHandlers } from "./handlers/session_handlers"; export function registerIpcHandlers() { // Register all IPC handlers by category @@ -39,4 +40,5 @@ export function registerIpcHandlers() { registerLanguageModelHandlers(); registerReleaseNoteHandlers(); registerImportHandlers(); + registerSessionHandlers(); } diff --git a/src/preload.ts b/src/preload.ts index 3e6110f..74e1226 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -74,6 +74,7 @@ const validInvokeChannels = [ "select-app-folder", "check-app-name", "rename-branch", + "clear-session-data", ] as const; // Add valid receive channels