11/**
22 * Update Notification Component
33 *
4- * Componente per mostrare notifiche di aggiornamento nell'interfaccia utente
4+ * Component for showing update notifications in the user interface
55 */
66
77import { updateManager } from '../managers/update-manager.js' ;
@@ -11,41 +11,47 @@ export class UpdateNotification {
1111 this . container = null ;
1212 this . isVisible = false ;
1313 this . animationDuration = 300 ;
14+ this . currentVersion = null ;
1415
1516 this . createNotificationContainer ( ) ;
1617 this . bindEvents ( ) ;
1718 }
1819
1920 /**
20- * Crea il container per le notifiche di aggiornamento
21+ * Creates the container for update notifications
2122 */
2223 createNotificationContainer ( ) {
2324 this . container = document . createElement ( 'div' ) ;
2425 this . container . className = 'update-notification-container' ;
26+
27+ // Add desktop class if running in Tauri desktop app
28+ if ( window . __TAURI__ && window . __TAURI__ . core ) {
29+ this . container . classList . add ( 'desktop' ) ;
30+ }
2531 this . container . innerHTML = `
2632 <div class="update-notification">
2733 <div class="update-content">
2834 <div class="update-icon">
2935 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
30- <path d="M12 2L13.09 8.26L19 7L17.74 13.26L22 12L20.74 18.26L24 17L22.74 23.26L12 22L10.91 15.74L5 17L6.26 10.74L2 12L3.26 5.74L0 7L1.26 0.74L12 2Z " fill="currentColor"/>
36+ <path d="M11 2.05C11 1.47 11.47 1 12.05 1C16.05 1 19.05 4.47 19.05 8.47C19.05 9.53 18.05 10.53 17 10.53H15V12.53C15 13.58 14 14.58 13 14.58H11V16.58C11 17.63 10 18.63 9 18.63H7V20.63C7 21.68 6 22.68 5 22.68H3C2.45 22.68 2 22.23 2 21.68V19.68C2 19.13 2.45 18.68 3 18.68H5V16.63C5 16.08 5.45 15.63 6 15.63H9V13.58C9 13.03 9.45 12.58 10 12.58H13V10.53H17C19.21 10.53 21.05 8.69 21.05 6.47C21.05 3.35 18.7 1 15.58 1C11.47 1 11 2.05 11 2.05ZM17 8.53C17 9.58 16 10.58 15 10.58C14 10.58 13 9.58 13 8.53C13 7.48 14 6.48 15 6.48C16 6.48 17 7.48 17 8.53Z " fill="currentColor"/>
3137 </svg>
3238 </div>
33- <span class="update-message">Aggiornamento disponibile </span>
39+ <span class="update-message">Update available </span>
3440 <span class="update-version"></span>
3541 <div class="update-actions">
3642 <button class="update-btn update-btn-primary" data-action="download">
37- Aggiorna
43+ Update via Homebrew
3844 </button>
3945 <button class="update-btn update-btn-secondary" data-action="dismiss">
40- Ignora
46+ Skip this release
4147 </button>
4248 </div>
4349 </div>
4450 <div class="update-progress-container" style="display: none;">
4551 <div class="update-progress-icon">
4652 <div class="spinner"></div>
4753 </div>
48- <span class="update-progress-message">Download in corso ...</span>
54+ <span class="update-progress-message">Installing update ...</span>
4955 <div class="update-progress-bar">
5056 <div class="update-progress-fill"></div>
5157 <span class="update-progress-text">0%</span>
@@ -59,19 +65,19 @@ export class UpdateNotification {
5965 </div>
6066 ` ;
6167
62- // Aggiungi gli stili
68+ // Inject styles
6369 this . injectStyles ( ) ;
6470
65- // Aggiungi al DOM ma nascosto
71+ // Add to DOM but hidden
6672 this . container . style . display = 'none' ;
6773 document . body . appendChild ( this . container ) ;
6874
69- // Bind degli eventi sui pulsanti
75+ // Bind button events
7076 this . bindButtonEvents ( ) ;
7177 }
7278
7379 /**
74- * Inietta gli stili CSS per la notifica
80+ * Injects CSS styles for the notification
7581 */
7682 injectStyles ( ) {
7783 if ( document . getElementById ( 'update-notification-styles' ) ) {
@@ -83,13 +89,17 @@ export class UpdateNotification {
8389 styles . textContent = `
8490 .update-notification-container {
8591 position: fixed;
86- top: 0 ;
92+ top: 40px ;
8793 left: 0;
8894 right: 0;
8995 z-index: 10000;
9096 transform: translateY(-100%);
9197 transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
9298 }
99+
100+ .update-notification-container.desktop {
101+ left: 80px;
102+ }
93103
94104 .update-notification-container.visible {
95105 transform: translateY(0);
@@ -256,26 +266,46 @@ export class UpdateNotification {
256266 /* Responsive */
257267 @media (max-width: 768px) {
258268 .update-notification-container {
259- left: 0;
269+ left: 0 !important;
270+ top: 20px;
260271 }
261272
262273 .update-notification {
263- padding: 6px 12px;
264- font-size: 13px;
274+ padding: 4px 8px;
275+ font-size: 12px;
276+ gap: 6px;
265277 }
266278
267- .update-btn {
268- padding: 3px 8px;
279+ .update-content {
280+ gap: 6px;
281+ }
282+
283+ .update-message {
269284 font-size: 12px;
270285 }
271286
287+ .update-actions {
288+ gap: 4px;
289+ }
290+
291+ .update-btn {
292+ padding: 2px 6px;
293+ font-size: 11px;
294+ border-radius: 3px;
295+ }
296+
272297 .update-version {
273298 display: none;
274299 }
275300
276301 .update-progress-bar {
277- min-width: 80px;
278- margin: 0 8px;
302+ min-width: 60px;
303+ margin: 0 6px;
304+ }
305+
306+ .update-close {
307+ padding: 2px;
308+ margin-left: 4px;
279309 }
280310 }
281311
@@ -298,7 +328,7 @@ export class UpdateNotification {
298328 }
299329
300330 /**
301- * Associa gli eventi ai pulsanti
331+ * Binds events to buttons
302332 */
303333 bindButtonEvents ( ) {
304334 const buttons = this . container . querySelectorAll ( '[data-action]' ) ;
@@ -311,15 +341,15 @@ export class UpdateNotification {
311341 }
312342
313343 /**
314- * Gestisce le azioni dei pulsanti
344+ * Handles button actions
315345 */
316346 handleAction ( action ) {
317347 switch ( action ) {
318348 case 'download' :
319349 this . startDownload ( ) ;
320350 break ;
321351 case 'dismiss' :
322- this . hide ( ) ;
352+ this . skipVersion ( ) ;
323353 break ;
324354 case 'close' :
325355 this . hide ( ) ;
@@ -328,24 +358,84 @@ export class UpdateNotification {
328358 }
329359
330360 /**
331- * Avvia il download dell'aggiornamento
361+ * Saves skipped version to localStorage
362+ */
363+ skipVersion ( ) {
364+ if ( this . currentVersion ) {
365+ try {
366+ const skippedVersions = this . getSkippedVersions ( ) ;
367+ if ( ! skippedVersions . includes ( this . currentVersion ) ) {
368+ skippedVersions . push ( this . currentVersion ) ;
369+ localStorage . setItem ( 'presto-skipped-versions' , JSON . stringify ( skippedVersions ) ) ;
370+ console . log ( `Skipped version ${ this . currentVersion } ` ) ;
371+ }
372+ } catch ( err ) {
373+ console . error ( 'Could not save skipped version:' , err ) ;
374+ }
375+ }
376+ this . hide ( ) ;
377+ }
378+
379+ /**
380+ * Gets list of skipped versions from localStorage
381+ */
382+ getSkippedVersions ( ) {
383+ try {
384+ const stored = localStorage . getItem ( 'presto-skipped-versions' ) ;
385+ return stored ? JSON . parse ( stored ) : [ ] ;
386+ } catch ( err ) {
387+ console . error ( 'Could not load skipped versions:' , err ) ;
388+ return [ ] ;
389+ }
390+ }
391+
392+ /**
393+ * Checks if a version has been skipped
394+ */
395+ isVersionSkipped ( version ) {
396+ const skippedVersions = this . getSkippedVersions ( ) ;
397+ return skippedVersions . includes ( version ) ;
398+ }
399+
400+ /**
401+ * Shows brew install command to user
332402 */
333403 async startDownload ( ) {
334- // Mostra la sezione di progresso
335- const content = this . container . querySelector ( '.update-content' ) ;
336- const progressContainer = this . container . querySelector ( '.update-progress-container' ) ;
404+ // Show brew install command instead of Tauri updater
405+ const brewCommand = 'brew install murdercode/presto/presto --cask' ;
337406
338- content . style . display = 'none' ;
339- progressContainer . style . display = 'block' ;
407+ // Copy command to clipboard if available
408+ if ( navigator . clipboard && navigator . clipboard . writeText ) {
409+ try {
410+ await navigator . clipboard . writeText ( brewCommand ) ;
411+ console . log ( 'Brew command copied to clipboard' ) ;
412+ } catch ( err ) {
413+ console . log ( 'Could not copy to clipboard:' , err ) ;
414+ }
415+ }
416+
417+ // Show alert with the command
418+ const message = `To update Presto, run this command in your terminal:\n\n${ brewCommand } \n\n${ navigator . clipboard ? 'The command has been copied to your clipboard.' : 'Please copy this command manually.' } ` ;
419+
420+ if ( window . __TAURI__ && window . __TAURI__ . dialog ) {
421+ // Use Tauri dialog if available
422+ await window . __TAURI__ . dialog . message ( message , {
423+ title : 'Update Presto via Homebrew' ,
424+ type : 'info'
425+ } ) ;
426+ } else {
427+ // Fallback to browser alert
428+ alert ( message ) ;
429+ }
340430
341- // Avvia il download tramite il manager
342- await updateManager . downloadAndInstall ( ) ;
431+ // Hide the notification after showing the command
432+ this . hide ( ) ;
343433 }
344434
345435 /**
346- * Aggiorna il progresso del download
436+ * Updates download progress
347437 */
348- updateProgress ( progress , chunkLength = 0 , contentLength = 0 ) {
438+ updateProgress ( progress ) {
349439 const progressFill = this . container . querySelector ( '.update-progress-fill' ) ;
350440 const progressText = this . container . querySelector ( '.update-progress-text' ) ;
351441
@@ -356,7 +446,7 @@ export class UpdateNotification {
356446 }
357447
358448 /**
359- * Associa gli eventi del manager degli aggiornamenti
449+ * Binds update manager events
360450 */
361451 bindEvents ( ) {
362452 updateManager . on ( 'updateAvailable' , ( event ) => {
@@ -378,51 +468,63 @@ export class UpdateNotification {
378468 }
379469
380470 /**
381- * Mostra la notifica di aggiornamento disponibile
471+ * Shows update available notification
382472 */
383473 showUpdateAvailable ( updateInfo ) {
474+ if ( ! updateInfo || ! updateInfo . version ) {
475+ return ;
476+ }
477+
478+ // Don't show if this version has been skipped
479+ if ( this . isVersionSkipped ( updateInfo . version ) ) {
480+ console . log ( `Version ${ updateInfo . version } was skipped, not showing notification` ) ;
481+ return ;
482+ }
483+
484+ this . currentVersion = updateInfo . version ;
485+
384486 const versionElement = this . container . querySelector ( '.update-version' ) ;
385- if ( versionElement && updateInfo ) {
386- versionElement . textContent = `Versione ${ updateInfo . version } ` ;
487+ if ( versionElement ) {
488+ versionElement . textContent = `Version ${ updateInfo . version } ` ;
387489 }
388490
389491 this . show ( ) ;
390492 }
391493
392494 /**
393- * Mostra lo stato di installazione
495+ * Shows installation status
394496 */
395497 showInstalling ( ) {
396498 const message = this . container . querySelector ( '.update-progress-message' ) ;
397499
398- if ( message ) message . textContent = 'Installazione in corso ...' ;
500+ if ( message ) message . textContent = 'Installing update ...' ;
399501
400502 this . updateProgress ( 100 ) ;
401503 }
402504
403505 /**
404- * Mostra un errore
506+ * Shows an error
405507 */
406508 showError ( ) {
407509 const message = this . container . querySelector ( '.update-progress-message' ) ;
408510
409- if ( message ) message . textContent = 'Errore aggiornamento ' ;
511+ if ( message ) message . textContent = 'Update error ' ;
410512
411- // Nascondi dopo 5 secondi
513+ // Hide after 5 seconds
412514 setTimeout ( ( ) => {
413515 this . hide ( ) ;
414516 } , 5000 ) ;
415517 }
416518
417519 /**
418- * Mostra la notifica
520+ * Shows the notification
419521 */
420522 show ( ) {
421523 if ( this . isVisible ) return ;
422524
423525 this . container . style . display = 'block' ;
424526
425- // Forza un reflow prima di aggiungere la classe
527+ // Force reflow before adding class
426528 this . container . offsetHeight ;
427529
428530 requestAnimationFrame ( ( ) => {
@@ -433,7 +535,7 @@ export class UpdateNotification {
433535 }
434536
435537 /**
436- * Nasconde la notifica
538+ * Hides the notification
437539 */
438540 hide ( ) {
439541 if ( ! this . isVisible ) return ;
@@ -449,7 +551,7 @@ export class UpdateNotification {
449551 }
450552
451553 /**
452- * Resetta la notifica allo stato iniziale
554+ * Resets notification to initial state
453555 */
454556 resetToInitialState ( ) {
455557 const content = this . container . querySelector ( '.update-content' ) ;
@@ -462,7 +564,7 @@ export class UpdateNotification {
462564 }
463565
464566 /**
465- * Distrugge il componente
567+ * Destroys the component
466568 */
467569 destroy ( ) {
468570 if ( this . container && this . container . parentNode ) {
@@ -473,5 +575,5 @@ export class UpdateNotification {
473575 }
474576}
475577
476- // Esporta un'istanza singleton
578+ // Export singleton instance
477579export const updateNotification = new UpdateNotification ( ) ;
0 commit comments