kubeops 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/electron/main.js
CHANGED
|
@@ -106,14 +106,43 @@ function setupAutoUpdater() {
|
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
function setupDevUpdaterIPC() {
|
|
110
|
+
ipcMain.handle('updater:check', async () => {
|
|
111
|
+
sendUpdateStatus({ status: 'not-available', version: app.getVersion() });
|
|
112
|
+
return null;
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
ipcMain.handle('updater:download', async () => {
|
|
116
|
+
sendUpdateStatus({ status: 'error', message: 'Updates are not available in development mode' });
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
ipcMain.handle('updater:install', () => {});
|
|
120
|
+
|
|
121
|
+
ipcMain.handle('updater:get-version', () => {
|
|
122
|
+
return app.getVersion();
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
109
126
|
function setupUpdaterIPC() {
|
|
110
127
|
ipcMain.handle('updater:check', async () => {
|
|
111
|
-
|
|
112
|
-
|
|
128
|
+
try {
|
|
129
|
+
const result = await autoUpdater.checkForUpdates();
|
|
130
|
+
return result?.updateInfo;
|
|
131
|
+
} catch (err) {
|
|
132
|
+
writeErrorLog('updater:check', err);
|
|
133
|
+
sendUpdateStatus({ status: 'error', message: err.message || 'Update check failed' });
|
|
134
|
+
throw err;
|
|
135
|
+
}
|
|
113
136
|
});
|
|
114
137
|
|
|
115
138
|
ipcMain.handle('updater:download', async () => {
|
|
116
|
-
|
|
139
|
+
try {
|
|
140
|
+
await autoUpdater.downloadUpdate();
|
|
141
|
+
} catch (err) {
|
|
142
|
+
writeErrorLog('updater:download', err);
|
|
143
|
+
sendUpdateStatus({ status: 'error', message: err.message || 'Download failed' });
|
|
144
|
+
throw err;
|
|
145
|
+
}
|
|
117
146
|
});
|
|
118
147
|
|
|
119
148
|
ipcMain.handle('updater:install', () => {
|
|
@@ -398,7 +427,7 @@ app.whenReady().then(async () => {
|
|
|
398
427
|
}
|
|
399
428
|
createWindow();
|
|
400
429
|
|
|
401
|
-
// Auto-update setup
|
|
430
|
+
// Auto-update setup
|
|
402
431
|
if (!isDev) {
|
|
403
432
|
setupAutoUpdater();
|
|
404
433
|
setupUpdaterIPC();
|
|
@@ -407,6 +436,9 @@ app.whenReady().then(async () => {
|
|
|
407
436
|
writeErrorLog('updater:auto-check', err);
|
|
408
437
|
});
|
|
409
438
|
}, 5000);
|
|
439
|
+
} else {
|
|
440
|
+
// Dev mode: register IPC handlers that respond with dev-friendly messages
|
|
441
|
+
setupDevUpdaterIPC();
|
|
410
442
|
}
|
|
411
443
|
} catch (err) {
|
|
412
444
|
writeErrorLog('main:startup', err);
|
package/package.json
CHANGED
|
@@ -12,6 +12,7 @@ import { Button } from '@/components/ui/button';
|
|
|
12
12
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
|
13
13
|
import { Server, ArrowRight, Search, Settings, RefreshCw, LogIn, Loader2, CircleCheck } from 'lucide-react';
|
|
14
14
|
import { ThemeToggle } from '@/components/layout/theme-toggle';
|
|
15
|
+
import { UpdateIndicator } from '@/components/layout/header';
|
|
15
16
|
import { SettingsDialog } from '@/components/settings/settings-dialog';
|
|
16
17
|
import { toast } from 'sonner';
|
|
17
18
|
|
|
@@ -174,6 +175,7 @@ export default function ClustersPage() {
|
|
|
174
175
|
>
|
|
175
176
|
<RefreshCw className={`h-4 w-4 ${refreshing ? 'animate-spin' : ''}`} />
|
|
176
177
|
</Button>
|
|
178
|
+
<UpdateIndicator />
|
|
177
179
|
<Button
|
|
178
180
|
variant="ghost"
|
|
179
181
|
size="icon"
|
|
@@ -28,6 +28,7 @@ export function useAutoUpdate() {
|
|
|
28
28
|
apiRef.current?.getAppVersion().then(setAppVersion).catch(() => {});
|
|
29
29
|
}, []);
|
|
30
30
|
|
|
31
|
+
// Event listener for push-based status updates (download progress, auto-check at startup)
|
|
31
32
|
useEffect(() => {
|
|
32
33
|
if (!apiRef.current) return;
|
|
33
34
|
|
|
@@ -62,17 +63,46 @@ export function useAutoUpdate() {
|
|
|
62
63
|
return unsubscribe;
|
|
63
64
|
}, []);
|
|
64
65
|
|
|
66
|
+
// checkForUpdates uses IPC return value as primary, event listener as fallback
|
|
65
67
|
const checkForUpdates = useCallback(() => {
|
|
66
68
|
if (!apiRef.current) return;
|
|
67
69
|
setPhase('checking');
|
|
68
70
|
setErrorMessage(null);
|
|
69
|
-
apiRef.current.checkForUpdates()
|
|
71
|
+
apiRef.current.checkForUpdates()
|
|
72
|
+
.then((info: any) => {
|
|
73
|
+
if (!info) {
|
|
74
|
+
// No update info returned — treat as up-to-date
|
|
75
|
+
setPhase((prev) => {
|
|
76
|
+
if (prev === 'checking') {
|
|
77
|
+
setTimeout(() => setPhase('idle'), 3000);
|
|
78
|
+
return 'not-available';
|
|
79
|
+
}
|
|
80
|
+
return prev;
|
|
81
|
+
});
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// IPC returned updateInfo — update is available
|
|
85
|
+
setPhase((prev) => {
|
|
86
|
+
// Only update if event listener hasn't already handled it
|
|
87
|
+
if (prev === 'checking') return 'available';
|
|
88
|
+
return prev;
|
|
89
|
+
});
|
|
90
|
+
if (info.version) setVersion(info.version);
|
|
91
|
+
})
|
|
92
|
+
.catch((err: any) => {
|
|
93
|
+
setPhase('error');
|
|
94
|
+
setErrorMessage(err?.message || 'Update check failed');
|
|
95
|
+
});
|
|
70
96
|
}, []);
|
|
71
97
|
|
|
72
98
|
const downloadUpdate = useCallback(() => {
|
|
73
99
|
if (!apiRef.current) return;
|
|
74
100
|
setPercent(0);
|
|
75
|
-
|
|
101
|
+
setPhase('downloading');
|
|
102
|
+
apiRef.current.downloadUpdate().catch((err: any) => {
|
|
103
|
+
setPhase('error');
|
|
104
|
+
setErrorMessage(err?.message || 'Download failed');
|
|
105
|
+
});
|
|
76
106
|
}, []);
|
|
77
107
|
|
|
78
108
|
const quitAndInstall = useCallback(() => {
|