11using System ;
22using System . Collections . ObjectModel ;
3+ using System . Diagnostics ;
34using System . Threading . Tasks ;
45using System . Windows . Input ;
6+ using System . Windows ;
7+ using System . Reflection ;
58using CommunityToolkit . Mvvm . ComponentModel ;
69using CommunityToolkit . Mvvm . Input ;
710using Microsoft . Extensions . Logging ;
@@ -37,12 +40,15 @@ public partial class SettingsViewModel : BaseViewModel
3740 [ ObservableProperty ]
3841 private ObservableCollection < PowerPlanModel > availablePowerPlans = new ( ) ;
3942
43+ public string ApplicationVersion { get ; }
44+
4045 public ICommand SaveSettingsCommand { get ; }
4146 public ICommand ResetToDefaultsCommand { get ; }
4247 public ICommand ExportSettingsCommand { get ; }
4348 public ICommand ImportSettingsCommand { get ; }
4449 public ICommand TestNotificationCommand { get ; }
4550 public ICommand RefreshPowerPlansCommand { get ; }
51+ public ICommand CheckUpdatesCommand { get ; }
4652
4753 public SettingsViewModel (
4854 ILogger < SettingsViewModel > logger ,
@@ -60,6 +66,12 @@ public SettingsViewModel(
6066 _powerPlanService = powerPlanService ?? throw new ArgumentNullException ( nameof ( powerPlanService ) ) ;
6167 _processMonitorManagerService = processMonitorManagerService ?? throw new ArgumentNullException ( nameof ( processMonitorManagerService ) ) ;
6268
69+ ApplicationVersion = typeof ( App ) . Assembly
70+ . GetCustomAttribute < AssemblyInformationalVersionAttribute > ( ) ?
71+ . InformationalVersion
72+ ?? typeof ( App ) . Assembly . GetName ( ) . Version ? . ToString ( )
73+ ?? "0.0.0" ;
74+
6375 // Initialize with current settings
6476 settings = ( ApplicationSettingsModel ) _settingsService . Settings . Clone ( ) ;
6577
@@ -70,6 +82,7 @@ public SettingsViewModel(
7082 ImportSettingsCommand = new AsyncRelayCommand ( ImportSettingsAsync ) ;
7183 TestNotificationCommand = new AsyncRelayCommand ( TestNotificationAsync ) ;
7284 RefreshPowerPlansCommand = new AsyncRelayCommand ( RefreshPowerPlansAsync ) ;
85+ CheckUpdatesCommand = new AsyncRelayCommand ( CheckUpdatesAsync ) ;
7386
7487 // Subscribe to property changes to track unsaved changes
7588 Settings . PropertyChanged += OnSettingsPropertyChanged ;
@@ -332,5 +345,88 @@ private async Task RefreshPowerPlansAsync()
332345 Logger . LogError ( ex , "Failed to refresh power plans" ) ;
333346 }
334347 }
348+
349+ private async Task CheckUpdatesAsync ( )
350+ {
351+ try
352+ {
353+ IsLoading = true ;
354+ StatusMessage = "Checking for updates..." ;
355+
356+ var currentVersion = ParseVersion ( ApplicationVersion ) ;
357+ var ( latest , releaseUrl ) = await GitHubUpdateChecker . GetLatestVersionAsync ( "PrimeBuild-pc" , "ThreadPilot" ) ;
358+
359+ if ( latest is null )
360+ {
361+ StatusMessage = "Unable to determine the latest version." ;
362+ await _notificationService . ShowErrorNotificationAsync (
363+ "Update Check" ,
364+ "Unable to retrieve latest release information." ) ;
365+ return ;
366+ }
367+
368+ if ( latest > currentVersion )
369+ {
370+ StatusMessage = $ "New version available: { latest } ";
371+
372+ var result = System . Windows . MessageBox . Show (
373+ $ "Update available\n Installed version: { ApplicationVersion } \n New version: { latest } \n \n Do you want to open the download page?",
374+ "Update available" ,
375+ MessageBoxButton . YesNo ,
376+ MessageBoxImage . Information ) ;
377+
378+ if ( result == MessageBoxResult . Yes )
379+ {
380+ var url = releaseUrl ?? "https://github.com/PrimeBuild-pc/ThreadPilot/releases/latest" ;
381+ Process . Start ( new ProcessStartInfo
382+ {
383+ FileName = url ,
384+ UseShellExecute = true
385+ } ) ;
386+ }
387+ }
388+ else
389+ {
390+ StatusMessage = $ "Application is up to date. Installed version: { ApplicationVersion } ";
391+ await _notificationService . ShowSuccessNotificationAsync (
392+ "Application up to date" ,
393+ $ "Installed version: { ApplicationVersion } ") ;
394+ }
395+ }
396+ catch ( Exception ex )
397+ {
398+ StatusMessage = $ "Error while checking updates: { ex . Message } ";
399+ Logger . LogError ( ex , "Error checking for updates" ) ;
400+
401+ await _notificationService . ShowErrorNotificationAsync (
402+ "Update check error" ,
403+ "Unable to verify updates" ,
404+ ex ) ;
405+ }
406+ finally
407+ {
408+ IsLoading = false ;
409+ }
410+ }
411+
412+ private static Version ParseVersion ( string versionString )
413+ {
414+ if ( string . IsNullOrWhiteSpace ( versionString ) )
415+ {
416+ return new Version ( 0 , 0 , 0 ) ;
417+ }
418+
419+ var sanitized = versionString . Trim ( ) ;
420+ if ( sanitized . StartsWith ( "v" , StringComparison . OrdinalIgnoreCase ) )
421+ {
422+ sanitized = sanitized [ 1 ..] ;
423+ }
424+
425+ sanitized = sanitized . Split ( '-' , '+' ) [ 0 ] ;
426+
427+ return Version . TryParse ( sanitized , out var parsed )
428+ ? parsed
429+ : new Version ( 0 , 0 , 0 ) ;
430+ }
335431 }
336432}
0 commit comments