diff --git a/dashboard/src/app/extensions/plugins/page.tsx b/dashboard/src/app/extensions/plugins/page.tsx index 4a678f9..b20c3dc 100644 --- a/dashboard/src/app/extensions/plugins/page.tsx +++ b/dashboard/src/app/extensions/plugins/page.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState, useMemo, useEffect } from 'react'; +import { useState, useMemo, useEffect, useRef } from 'react'; import useSWR from 'swr'; import { toast } from '@/components/toast'; import { type Plugin, getInstalledPlugins, updatePlugin, type InstalledPluginInfo } from '@/lib/api'; @@ -585,6 +585,16 @@ function InstalledPluginsSection() { const [updating, setUpdating] = useState(null); const [updateProgress, setUpdateProgress] = useState(null); + const cleanupRef = useRef<(() => void) | null>(null); + + // Cleanup EventSource on unmount + useEffect(() => { + return () => { + if (cleanupRef.current) { + cleanupRef.current(); + } + }; + }, []); const handleUpdate = (packageName: string) => { setUpdating(packageName); @@ -597,16 +607,17 @@ function InstalledPluginsSection() { toast.success(event.message); setUpdating(null); setUpdateProgress(null); + cleanupRef.current = null; mutate(); // Refresh the list } else if (event.event_type === 'error') { toast.error(event.message); setUpdating(null); setUpdateProgress(null); + cleanupRef.current = null; } }); - // Cleanup on unmount - return cleanup; + cleanupRef.current = cleanup; }; if (isLoading) { diff --git a/dashboard/src/lib/api.ts b/dashboard/src/lib/api.ts index 76e28b0..bf76532 100644 --- a/dashboard/src/lib/api.ts +++ b/dashboard/src/lib/api.ts @@ -1669,6 +1669,11 @@ export function updatePlugin( eventSource.onerror = () => { eventSource.close(); + onEvent({ + event_type: "error", + message: "Connection error: failed to connect to server", + progress: null, + }); }; return () => eventSource.close(); diff --git a/src/api/system.rs b/src/api/system.rs index 3843ca7..ef67f74 100644 --- a/src/api/system.rs +++ b/src/api/system.rs @@ -1069,7 +1069,8 @@ fn stream_plugin_update(package: String) -> impl Stream