Skip to content

Commit 3509741

Browse files
committed
kinda working
1 parent d00827d commit 3509741

3 files changed

Lines changed: 132 additions & 17 deletions

File tree

src/main/preload.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ const validChannels = {
2727
'report-error',
2828
'refresh-mcp-connections',
2929
'check-for-updates',
30+
'check-for-updates-menu',
3031
'download-update',
3132
'install-update',
3233
'get-update-status',
33-
'get-app-version', // Add this
34+
'get-app-version',
3435
],
3536
on: [
3637
'message-response',

src/main/updater.ts

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ export class AppUpdater {
9898

9999
try {
100100
this.isCheckingUpdate = true;
101-
this.checkPromise = autoUpdater.checkForUpdatesAndNotify();
101+
// Use checkForUpdates() instead of checkForUpdatesAndNotify()
102+
this.checkPromise = autoUpdater.checkForUpdates();
102103
const result = await this.checkPromise;
103104
return { success: true, updateInfo: result?.updateInfo };
104105
} catch (error) {
@@ -144,16 +145,49 @@ export class AppUpdater {
144145
}
145146
});
146147

147-
ipcMain.handle('check-for-updates-menu', () => {
148-
if (this.mainWindow && !this.mainWindow.isDestroyed()) {
149-
this.mainWindow.webContents.send('update-status', {
150-
status: this.isCheckingUpdate ? 'checking' : this.lastStatus || 'idle',
151-
info: this.lastInfo,
152-
error: this.lastError,
153-
progress: this.lastProgress,
154-
});
148+
ipcMain.handle('check-for-updates-menu', async () => {
149+
if (!app.isPackaged) {
150+
this.sendStatusToWindow('not-available', { version: app.getVersion() });
151+
return {
152+
success: true,
153+
updateInfo: null,
154+
message: 'Updates only available in packaged app'
155+
};
156+
}
157+
158+
// If already checking, just send current status
159+
if (this.isCheckingUpdate && this.checkPromise) {
160+
if (this.mainWindow && !this.mainWindow.isDestroyed()) {
161+
this.mainWindow.webContents.send('update-status', {
162+
status: 'checking',
163+
info: this.lastInfo,
164+
error: this.lastError,
165+
progress: this.lastProgress,
166+
});
167+
}
168+
try {
169+
const result = await this.checkPromise;
170+
return { success: true, updateInfo: result?.updateInfo };
171+
} catch (error) {
172+
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
173+
}
174+
}
175+
176+
try {
177+
this.isCheckingUpdate = true;
178+
this.sendStatusToWindow('checking');
179+
// Use checkForUpdates() instead of checkForUpdatesAndNotify()
180+
this.checkPromise = autoUpdater.checkForUpdates();
181+
const result = await this.checkPromise;
182+
return { success: true, updateInfo: result?.updateInfo };
183+
} catch (error) {
184+
log.error('[AppUpdater] Menu check failed:', error);
185+
this.sendStatusToWindow('error', null, error instanceof Error ? error.message : 'Unknown error');
186+
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
187+
} finally {
188+
this.isCheckingUpdate = false;
189+
this.checkPromise = null;
155190
}
156-
return { success: true };
157191
});
158192
}
159193

@@ -162,6 +196,13 @@ export class AppUpdater {
162196
this.lastInfo = info;
163197
this.lastError = error;
164198
this.lastProgress = progress;
199+
200+
log.info(`[AppUpdater] Sending status to window: ${status}`, {
201+
hasMainWindow: !!this.mainWindow,
202+
isDestroyed: this.mainWindow?.isDestroyed(),
203+
info: info ? { version: info.version } : undefined
204+
});
205+
165206
if (this.mainWindow && !this.mainWindow.isDestroyed()) {
166207
this.mainWindow.webContents.send('update-status', {
167208
status,
@@ -177,6 +218,10 @@ export class AppUpdater {
177218
return;
178219
}
179220

221+
if (app.isPackaged) {
222+
return;
223+
}
224+
180225
// Check for updates 3 seconds after startup to avoid conflicts
181226
setTimeout(() => {
182227
this.sendStatusToWindow('checking');

src/renderer/components/UpdateNotification/UpdateNotification.tsx

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ function UpdateNotification() {
3030
useEffect(() => {
3131
mounted.current = true;
3232

33+
// Add logging to confirm listener setup
34+
log.info('[UpdateNotification] Setting up event listeners');
35+
3336
// Get current version
3437
window.electron.ipcRenderer.invoke('get-app-version').then((version) => {
3538
if (mounted.current) {
@@ -63,6 +66,14 @@ function UpdateNotification() {
6366

6467
// Listen for update status changes
6568
const handleUpdateStatus = (_event: any, data: any) => {
69+
log.info(`[UpdateNotification] Received update status: ${data.status}`, {
70+
info: data.info ? { version: data.info.version } : undefined,
71+
error: data.error,
72+
mounted: mounted.current,
73+
userDismissed,
74+
currentUpdateVersion: updateStatus.info?.version
75+
});
76+
6677
if (!mounted.current) return;
6778

6879
// Clear any existing hide timeout
@@ -74,6 +85,7 @@ function UpdateNotification() {
7485
// Don't show notification if user dismissed and it's the same update
7586
if (userDismissed && data.status === 'available' &&
7687
updateStatus.info?.version === data.info?.version) {
88+
log.info('[UpdateNotification] Skipping notification - user dismissed this version');
7789
return;
7890
}
7991

@@ -84,8 +96,12 @@ function UpdateNotification() {
8496
progress: data.progress
8597
});
8698

87-
// Show notification for all statuses except idle
88-
if (data.status !== 'idle') {
99+
// Always show notification for important statuses
100+
if (data.status === 'available' || data.status === 'downloading' ||
101+
data.status === 'downloaded' || data.status === 'error') {
102+
log.info(`[UpdateNotification] Showing notification for status: ${data.status}`);
103+
setShowNotification(true);
104+
} else if (data.status !== 'idle') {
89105
setShowNotification(true);
90106

91107
// Auto-hide "not-available" after 3 seconds
@@ -100,32 +116,85 @@ function UpdateNotification() {
100116
};
101117

102118
// Listen for menu-triggered update checks
103-
const handleCheckForUpdatesMenu = () => {
119+
const handleCheckForUpdatesMenu = async () => {
104120
if (!mounted.current) return;
105121

122+
log.info('Received check-for-updates-menu event');
106123
setUserDismissed(false);
107124

125+
// Clear any existing hide timeout
126+
if (hideTimeoutRef.current) {
127+
clearTimeout(hideTimeoutRef.current);
128+
hideTimeoutRef.current = null;
129+
}
130+
108131
// Show checking status immediately
109132
setUpdateStatus({ status: 'checking' });
110133
setShowNotification(true);
111134

112-
// Then invoke the check (status will be updated via 'update-status' event)
113-
window.electron.ipcRenderer.invoke('check-for-updates');
135+
// Actually invoke the check-for-updates-menu handler
136+
try {
137+
const result = await window.electron.ipcRenderer.invoke('check-for-updates-menu');
138+
log.info('[UpdateNotification] check-for-updates-menu result:', result);
139+
140+
// Handle the result directly since IPC events aren't working
141+
if (result.success && result.updateInfo) {
142+
// Update available
143+
setUpdateStatus({
144+
status: 'available',
145+
info: {
146+
version: result.updateInfo.version,
147+
releaseNotes: result.updateInfo.releaseNotes,
148+
releaseDate: result.updateInfo.releaseDate
149+
}
150+
});
151+
setShowNotification(true);
152+
log.info(`[UpdateNotification] Showing notification for available update: ${result.updateInfo.version}`);
153+
} else if (result.success && !result.updateInfo) {
154+
// No update available
155+
setUpdateStatus({ status: 'not-available' });
156+
setShowNotification(true);
157+
// Auto-hide after 3 seconds
158+
hideTimeoutRef.current = setTimeout(() => {
159+
if (mounted.current) {
160+
setShowNotification(false);
161+
}
162+
}, 3000);
163+
} else {
164+
// Error
165+
setUpdateStatus({ status: 'error', error: result.error || 'Unknown error' });
166+
setShowNotification(true);
167+
}
168+
} catch (error) {
169+
log.error('Failed to check for updates:', error);
170+
setUpdateStatus({ status: 'error', error: error instanceof Error ? error.message : 'Unknown error' });
171+
setShowNotification(true);
172+
}
173+
};
174+
175+
// Test listener to verify IPC communication
176+
const testHandler = (data: any) => {
177+
log.info('[UpdateNotification] TEST: Received any update-status event:', data);
114178
};
115179

116180
// Use the existing IPC pattern
181+
log.info('[UpdateNotification] Adding update-status listener');
117182
window.electron.ipcRenderer.on('update-status', handleUpdateStatus);
183+
window.electron.ipcRenderer.on('update-status', testHandler);
184+
log.info('[UpdateNotification] Adding check-for-updates-menu listener');
118185
window.electron.ipcRenderer.on('check-for-updates-menu', handleCheckForUpdatesMenu);
119186

120187
return () => {
121188
mounted.current = false;
122189
if (hideTimeoutRef.current) {
123190
clearTimeout(hideTimeoutRef.current);
124191
}
192+
log.info('[UpdateNotification] Removing listeners');
125193
window.electron.ipcRenderer.removeListener('update-status', handleUpdateStatus);
194+
window.electron.ipcRenderer.removeListener('update-status', testHandler);
126195
window.electron.ipcRenderer.removeListener('check-for-updates-menu', handleCheckForUpdatesMenu);
127196
};
128-
}, [userDismissed, updateStatus.info?.version]);
197+
}, []);
129198

130199
const handleDownload = async () => {
131200
const result = await window.electron.ipcRenderer.invoke('download-update');

0 commit comments

Comments
 (0)