44using System . Diagnostics ;
55using System . IO ;
66using System . Linq ;
7- using System . Text ;
87using System . Text . RegularExpressions ;
98using System . Threading ;
109using System . Threading . Tasks ;
1110using Flow . Launcher . Plugin ;
1211using Microsoft . Win32 ;
13-
12+ using System . Windows . Controls ;
13+ using System . Windows ;
1414namespace Flow . Launcher . Plugin . AppUpgrader
1515{
16- public class AppUpgrader : IAsyncPlugin
16+ public class AppUpgrader : IAsyncPlugin , ISettingProvider
1717 {
18+ private SettingsPage settingsPage ;
1819 internal PluginInitContext Context ;
1920 private ConcurrentBag < UpgradableApp > upgradableApps ;
2021 private ConcurrentDictionary < string , string > appIconPaths ;
@@ -33,11 +34,20 @@ public class AppUpgrader : IAsyncPlugin
3334 TimeSpan . FromMilliseconds ( 500 )
3435 ) ;
3536
36- public Task InitAsync ( PluginInitContext context )
37+ public async Task InitAsync ( PluginInitContext context )
3738 {
3839 Context = context ;
3940 appIconPaths = new ConcurrentDictionary < string , string > ( ) ;
4041
42+ Application . Current . Dispatcher . Invoke ( ( ) =>
43+ {
44+ settingsPage = new SettingsPage ( Context ) ;
45+ settingsPage . SettingLoaded += async ( s , e ) =>
46+ {
47+ settingsPage . ExcludedApps . CollectionChanged += ExcludedApps_CollectionChanged ;
48+ RemoveExcludedAppsFromUpgradableList ( ) ;
49+ } ;
50+ } ) ;
4151 Task . Run ( async ( ) =>
4252 {
4353 try
@@ -48,7 +58,36 @@ public Task InitAsync(PluginInitContext context)
4858 } ) ;
4959
5060 ThreadPool . SetMinThreads ( Environment . ProcessorCount * 2 , Environment . ProcessorCount * 2 ) ;
51- return Task . CompletedTask ;
61+ await Task . CompletedTask ;
62+ }
63+
64+
65+ private void RemoveExcludedAppsFromUpgradableList ( )
66+ {
67+ var excludedApps = settingsPage . ExcludedApps ;
68+
69+ if ( excludedApps == null || ! excludedApps . Any ( ) )
70+ {
71+ return ;
72+ }
73+
74+ var updatedApps = upgradableApps
75+ . Where ( app => ! excludedApps . Any ( excludedApp =>
76+ app . Name . Contains ( excludedApp , StringComparison . OrdinalIgnoreCase ) ||
77+ app . Id . Contains ( excludedApp , StringComparison . OrdinalIgnoreCase ) ) )
78+ . ToList ( ) ;
79+
80+ upgradableApps = new ConcurrentBag < UpgradableApp > ( updatedApps ) ;
81+ }
82+
83+ private void ExcludedApps_CollectionChanged ( object sender , System . Collections . Specialized . NotifyCollectionChangedEventArgs e )
84+ {
85+
86+ if ( e . Action == System . Collections . Specialized . NotifyCollectionChangedAction . Add ||
87+ e . Action == System . Collections . Specialized . NotifyCollectionChangedAction . Remove )
88+ {
89+ RemoveExcludedAppsFromUpgradableList ( ) ;
90+ }
5291 }
5392
5493 public async Task < List < Result > > QueryAsync ( Query query , CancellationToken token )
@@ -61,18 +100,44 @@ public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
61100 if ( upgradableApps == null || ! upgradableApps . Any ( ) )
62101 {
63102 return new List < Result >
64- {
65- new Result
66- {
67- Title = "No updates available" ,
68- SubTitle = "All applications are up-to-date." ,
69- IcoPath = "Images\\ app.png"
70- }
71- } ;
103+ {
104+ new Result
105+ {
106+ Title = "No updates available" ,
107+ SubTitle = "All applications are up-to-date." ,
108+ IcoPath = "Images\\ app.png"
109+ }
110+ } ;
72111 }
73112
74113 string filterTerm = query . Search ? . Trim ( ) . ToLower ( ) ;
75114
115+ var results = new List < Result > ( ) ;
116+
117+ if ( settingsPage . EnableUpgradeAll )
118+ {
119+ results . Add ( new Result
120+ {
121+ Title = "Upgrade All Applications" ,
122+ SubTitle = "Upgrade all apps listed below." ,
123+ IcoPath = "Images\\ app.png" ,
124+ Action = context =>
125+ {
126+ Task . Run ( async ( ) =>
127+ {
128+ try
129+ {
130+ foreach ( var app in upgradableApps )
131+ {
132+ await PerformUpgradeAsync ( app ) ;
133+ }
134+ }
135+ catch ( Exception ex ) { }
136+ } ) ;
137+ return true ;
138+ }
139+ } ) ;
140+ }
76141 var tasks = upgradableApps . AsParallel ( )
77142 . WithDegreeOfParallelism ( Environment . ProcessorCount )
78143 . Where ( app => string . IsNullOrEmpty ( filterTerm ) ||
@@ -99,9 +164,12 @@ public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
99164 }
100165 } ) ;
101166
102- return ( await Task . WhenAll ( tasks ) ) . ToList ( ) ;
167+ results . AddRange ( await Task . WhenAll ( tasks ) ) ;
168+
169+ return results ;
103170 }
104171
172+
105173 private async Task < string > GetAppIconPath ( string appId , string appName )
106174 {
107175 if ( appIconPaths . TryGetValue ( appId , out string cachedPath ) )
@@ -263,14 +331,16 @@ private async Task RefreshUpgradableAppsAsync()
263331 if ( ! ShouldRefreshCache ( ) )
264332 return ;
265333
266- var apps = await GetUpgradableAppsAsync ( ) ;
267- upgradableApps = new ConcurrentBag < UpgradableApp > ( apps ) ;
268- _lastRefreshTime = DateTime . UtcNow ;
334+ var apps = await GetUpgradableAppsAsync ( ) ;
335+ upgradableApps = new ConcurrentBag < UpgradableApp > ( apps ) ;
336+ RemoveExcludedAppsFromUpgradableList ( ) ;
337+
338+ _lastRefreshTime = DateTime . UtcNow ;
269339 }
270340 catch ( Exception ex ) { }
271341 finally
272342 {
273- _refreshSemaphore . Release ( ) ;
343+ _refreshSemaphore . Release ( ) ;
274344 }
275345 }
276346
@@ -288,6 +358,12 @@ private async Task PerformUpgradeAsync(UpgradableApp app)
288358 await RefreshUpgradableAppsAsync ( ) ;
289359 }
290360
361+ public Control CreateSettingPanel ( )
362+ {
363+
364+ return settingsPage ;
365+ }
366+
291367 private async Task < List < UpgradableApp > > GetUpgradableAppsAsync ( )
292368 {
293369 using var cts = new CancellationTokenSource ( TimeSpan . FromSeconds ( COMMAND_TIMEOUT_SECONDS ) ) ;
0 commit comments