Skip to content

Commit ba1fb7a

Browse files
committed
some where in the middle
1 parent 3509741 commit ba1fb7a

5 files changed

Lines changed: 318 additions & 83 deletions

File tree

src/main/preload.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ const validChannels = {
2929
'check-for-updates',
3030
'check-for-updates-menu',
3131
'download-update',
32+
'download-and-install',
3233
'install-update',
34+
'enable-auto-install',
3335
'get-update-status',
3436
'get-app-version',
3537
],

src/main/updater.ts

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,33 @@ export class AppUpdater {
114114

115115
ipcMain.handle('download-update', async () => {
116116
try {
117-
await autoUpdater.downloadUpdate();
118-
return { success: true };
117+
log.info('[AppUpdater] Download request received');
118+
119+
// Check if already downloaded first
120+
if (this.lastStatus === 'downloaded') {
121+
log.info('[AppUpdater] Update already downloaded, notifying UI');
122+
this.sendStatusToWindow('downloaded', this.lastInfo);
123+
return { success: true, alreadyDownloaded: true };
124+
}
125+
126+
// If we have update info but no download yet, start download
127+
if (this.lastInfo && this.lastStatus === 'available') {
128+
log.info('[AppUpdater] Starting download for available update');
129+
this.sendStatusToWindow('downloading', this.lastInfo, undefined, { percent: 0, transferred: 0, total: 0 });
130+
131+
await autoUpdater.downloadUpdate();
132+
log.info('[AppUpdater] Download completed');
133+
return { success: true };
134+
}
135+
136+
// No update available
137+
log.warn('[AppUpdater] No update available to download');
138+
this.sendStatusToWindow('error', null, 'No update available to download');
139+
return { success: false, error: 'No update available to download' };
140+
119141
} catch (error) {
120142
log.error('[AppUpdater] Download failed:', error);
143+
this.sendStatusToWindow('error', null, error instanceof Error ? error.message : 'Unknown error');
121144
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
122145
}
123146
});
@@ -189,6 +212,42 @@ export class AppUpdater {
189212
this.checkPromise = null;
190213
}
191214
});
215+
216+
ipcMain.handle('enable-auto-install', () => {
217+
log.info('[AppUpdater] Enabling auto-install on next quit');
218+
autoUpdater.autoInstallOnAppQuit = true;
219+
return { success: true };
220+
});
221+
222+
ipcMain.handle('download-and-install', async () => {
223+
try {
224+
log.info('[AppUpdater] Download and install requested');
225+
226+
// Check current status
227+
if (this.lastStatus === 'downloaded') {
228+
log.info('[AppUpdater] Update already downloaded, ready to install');
229+
return { success: true, readyToInstall: true };
230+
}
231+
232+
if (this.lastStatus === 'available' && this.lastInfo) {
233+
log.info('[AppUpdater] Starting download...');
234+
this.sendStatusToWindow('downloading', this.lastInfo, undefined, { percent: 0, transferred: 0, total: 0 });
235+
236+
// Download the update
237+
await autoUpdater.downloadUpdate();
238+
239+
log.info('[AppUpdater] Download completed, ready to install');
240+
return { success: true, readyToInstall: true };
241+
}
242+
243+
return { success: false, error: 'No update available to download' };
244+
245+
} catch (error) {
246+
log.error('[AppUpdater] Download and install failed:', error);
247+
this.sendStatusToWindow('error', null, error instanceof Error ? error.message : 'Unknown error');
248+
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
249+
}
250+
});
192251
}
193252

194253
private sendStatusToWindow(status: string, info?: any, error?: string, progress?: any) {
@@ -200,7 +259,9 @@ export class AppUpdater {
200259
log.info(`[AppUpdater] Sending status to window: ${status}`, {
201260
hasMainWindow: !!this.mainWindow,
202261
isDestroyed: this.mainWindow?.isDestroyed(),
203-
info: info ? { version: info.version } : undefined
262+
info: info ? { version: info.version } : undefined,
263+
error,
264+
progress
204265
});
205266

206267
if (this.mainWindow && !this.mainWindow.isDestroyed()) {
@@ -210,20 +271,21 @@ export class AppUpdater {
210271
error,
211272
progress
212273
});
274+
log.info(`[AppUpdater] Status sent to renderer: ${status}`);
275+
} else {
276+
log.warn('[AppUpdater] Cannot send status - main window not available');
213277
}
214278
}
215279

216280
checkForUpdatesOnStartup() {
217281
if (!app.isPackaged) {
282+
log.info('[AppUpdater] Skipping startup check - not packaged');
218283
return;
219284
}
220285

221-
if (app.isPackaged) {
222-
return;
223-
}
224-
225-
// Check for updates 3 seconds after startup to avoid conflicts
286+
// Check for updates 3 seconds after startup to avoid conflicts
226287
setTimeout(() => {
288+
log.info('[AppUpdater] Starting automatic update check');
227289
this.sendStatusToWindow('checking');
228290
autoUpdater.checkForUpdatesAndNotify().catch(err => {
229291
log.error('[AppUpdater] Startup check failed:', err.message);

src/renderer/components/UpdateNotification/UpdateNotification.css

Lines changed: 121 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,24 @@
22
position: fixed;
33
top: 20px;
44
right: 20px;
5-
background-color: #2A2F35;
6-
border: 1px solid #7CA97E;
7-
border-radius: 8px;
5+
background: linear-gradient(135deg, #2A2F35 0%, #232831 100%);
6+
border: 1px solid rgba(124, 169, 126, 0.3);
7+
border-radius: 12px;
88
padding: 16px;
9-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
9+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 2px 8px rgba(124, 169, 126, 0.1);
1010
z-index: 1000;
11-
animation: slideIn 0.3s ease-out;
12-
max-width: 400px;
11+
animation: slideIn 0.4s cubic-bezier(0.16, 1, 0.3, 1);
12+
max-width: 320px;
13+
backdrop-filter: blur(12px);
1314
}
1415

1516
@keyframes slideIn {
1617
from {
17-
transform: translateX(100%);
18+
transform: translateX(100%) scale(0.95);
1819
opacity: 0;
1920
}
2021
to {
21-
transform: translateX(0);
22+
transform: translateX(0) scale(1);
2223
opacity: 1;
2324
}
2425
}
@@ -42,32 +43,49 @@
4243

4344
.update-content {
4445
display: flex;
45-
align-items: center;
46+
flex-direction: column;
4647
gap: 12px;
4748
color: #C5D8BC;
48-
flex: 1;
49+
}
50+
51+
.update-content.downloaded {
52+
gap: 16px;
53+
}
54+
55+
.update-content span:first-child {
56+
font-size: 15px;
57+
font-weight: 600;
58+
line-height: 1.3;
4959
}
5060

5161
.update-content.checking,
5262
.update-content.downloading {
63+
flex-direction: row;
64+
align-items: center;
5365
color: #8FB996;
66+
font-weight: 500;
5467
}
5568

5669
.update-content.up-to-date {
5770
color: #7CA97E;
71+
font-weight: 600;
72+
text-align: center;
73+
padding: 8px 0;
5874
}
5975

6076
.update-content.error {
61-
color: #E53935;
77+
color: #FF6B6B;
78+
font-weight: 500;
6279
}
6380

6481
.spinner {
65-
width: 16px;
66-
height: 16px;
67-
border: 2px solid #8FB996;
68-
border-top-color: transparent;
82+
width: 18px;
83+
height: 18px;
84+
border: 2.5px solid rgba(143, 185, 150, 0.2);
85+
border-top-color: #8FB996;
6986
border-radius: 50%;
7087
animation: spin 1s linear infinite;
88+
margin-right: 4px;
7189
}
7290

7391
@keyframes spin {
@@ -79,42 +97,84 @@
7997
}
8098

8199
.update-button {
82-
padding: 6px 16px;
83-
background-color: #7CA97E;
84-
color: #1E2329;
100+
padding: 12px 16px;
85101
border: none;
86-
border-radius: 4px;
102+
border-radius: 8px;
87103
cursor: pointer;
88-
font-weight: 500;
89-
transition: background-color 0.2s;
104+
font-weight: 600;
105+
font-size: 14px;
106+
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
107+
position: relative;
108+
overflow: hidden;
109+
}
110+
111+
.update-button::before {
112+
content: '';
113+
position: absolute;
114+
top: 0;
115+
left: -100%;
116+
width: 100%;
117+
height: 100%;
118+
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
119+
transition: left 0.5s;
120+
}
121+
122+
.update-button:hover::before {
123+
left: 100%;
124+
}
125+
126+
.update-button.primary {
127+
background: linear-gradient(135deg, #7CA97E 0%, #6B9A6D 100%);
128+
color: white;
129+
box-shadow: 0 4px 12px rgba(124, 169, 126, 0.3);
130+
}
131+
132+
.update-button.secondary {
133+
background: rgba(124, 169, 126, 0.1);
134+
border: 1.5px solid rgba(124, 169, 126, 0.4);
135+
color: #8FB996;
136+
backdrop-filter: blur(8px);
90137
}
91138

92-
.update-button:hover {
93-
background-color: #8FB996;
139+
.update-button.primary:hover {
140+
background: linear-gradient(135deg, #8FB996 0%, #7CA97E 100%);
141+
transform: translateY(-2px);
142+
box-shadow: 0 6px 20px rgba(124, 169, 126, 0.4);
143+
}
144+
145+
.update-button.secondary:hover {
146+
background: rgba(124, 169, 126, 0.2);
147+
border-color: rgba(143, 185, 150, 0.6);
148+
transform: translateY(-1px);
149+
box-shadow: 0 4px 12px rgba(124, 169, 126, 0.2);
94150
}
95151

96152
.dismiss-button {
97-
padding: 6px 12px;
98-
background-color: transparent;
153+
padding: 8px 12px;
154+
background: transparent;
99155
color: #8A9BA8;
100-
border: 1px solid #3A424A;
101-
border-radius: 4px;
156+
border: 1px solid rgba(138, 155, 168, 0.2);
157+
border-radius: 6px;
102158
cursor: pointer;
103-
transition: all 0.2s;
159+
font-size: 13px;
160+
font-weight: 500;
161+
transition: all 0.2s ease;
104162
}
105163

106164
.dismiss-button:hover {
107-
border-color: #8A9BA8;
165+
border-color: rgba(138, 155, 168, 0.4);
108166
color: #C5D8BC;
167+
background: rgba(138, 155, 168, 0.05);
168+
transform: translateY(-1px);
109169
}
110170

111171
.progress-bar {
112-
width: 100px;
113-
height: 6px;
114-
background-color: #3A424A;
115-
border-radius: 3px;
172+
width: 100%;
173+
height: 4px;
174+
background-color: rgba(124, 169, 126, 0.2);
175+
border-radius: 2px;
116176
overflow: hidden;
117-
margin-top: 12px;
177+
margin: 8px 0;
118178
}
119179

120180
.progress-fill {
@@ -125,7 +185,7 @@
125185

126186
.progress-text {
127187
font-size: 12px;
128-
color: #8A9BA8;
188+
color: #7CA97E;
129189
}
130190

131191
.error-detail {
@@ -151,4 +211,30 @@
151211
opacity: 0;
152212
transform: translateX(100%);
153213
}
214+
}
215+
216+
.update-actions {
217+
display: flex;
218+
flex-direction: column;
219+
gap: 8px;
220+
margin-top: 4px;
221+
}
222+
223+
/* Add subtle glow effect */
224+
.update-notification:hover {
225+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(124, 169, 126, 0.2);
226+
}
227+
228+
/* Responsive adjustments */
229+
@media (max-width: 480px) {
230+
.update-notification {
231+
right: 12px;
232+
max-width: 280px;
233+
padding: 14px;
234+
}
235+
236+
.update-button {
237+
padding: 10px 14px;
238+
font-size: 13px;
239+
}
154240
}

0 commit comments

Comments
 (0)