@@ -19,6 +19,21 @@ internal class PluginsManager
19
19
20
20
private Settings Settings { get ; set ; }
21
21
22
+ private bool shouldHideWindow = true ;
23
+ private bool ShouldHideWindow
24
+ {
25
+ set { shouldHideWindow = value ; }
26
+ get
27
+ {
28
+ var setValue = shouldHideWindow ;
29
+ // Default value for hide main window is true. Revert after get call.
30
+ // This ensures when set by another method to false, it is only used once.
31
+ shouldHideWindow = true ;
32
+
33
+ return setValue ;
34
+ }
35
+ }
36
+
22
37
private readonly string icoPath = "Images\\ pluginsmanager.png" ;
23
38
24
39
internal PluginsManager ( PluginInitContext context , Settings settings )
@@ -31,7 +46,22 @@ internal void InstallOrUpdate(UserPlugin plugin)
31
46
{
32
47
if ( PluginExists ( plugin . ID ) )
33
48
{
34
- Context . API . ShowMsg ( "Plugin already installed" ) ;
49
+ if ( Context . API . GetAllPlugins ( ) . Any ( x => x . Metadata . ID == plugin . ID && x . Metadata . Version != plugin . Version ) )
50
+ {
51
+ if ( MessageBox . Show ( Context . API . GetTranslation ( "plugin_pluginsmanager_update_exists" ) ,
52
+ Context . API . GetTranslation ( "plugin_pluginsmanager_update_title" ) ,
53
+ MessageBoxButton . YesNo ) == MessageBoxResult . Yes )
54
+ Context
55
+ . API
56
+ . ChangeQuery ( $ "{ Context . CurrentPluginMetadata . ActionKeywords . FirstOrDefault ( ) } { Settings . HotkeyUpdate } { plugin . Name } ") ;
57
+
58
+ Application . Current . MainWindow . Show ( ) ;
59
+ shouldHideWindow = false ;
60
+
61
+ return ;
62
+ }
63
+
64
+ Context . API . ShowMsg ( Context . API . GetTranslation ( "plugin_pluginsmanager_update_alreadyexists" ) ) ;
35
65
return ;
36
66
}
37
67
@@ -42,7 +72,7 @@ internal void InstallOrUpdate(UserPlugin plugin)
42
72
if ( MessageBox . Show ( message , Context . API . GetTranslation ( "plugin_pluginsmanager_install_title" ) , MessageBoxButton . YesNo ) == MessageBoxResult . No )
43
73
return ;
44
74
45
- var filePath = Path . Combine ( DataLocation . PluginsDirectory , $ "{ plugin . Name } { plugin . ID } .zip") ;
75
+ var filePath = Path . Combine ( DataLocation . PluginsDirectory , $ "{ plugin . Name } - { plugin . Version } .zip") ;
46
76
47
77
try
48
78
{
@@ -62,29 +92,92 @@ internal void InstallOrUpdate(UserPlugin plugin)
62
92
Log . Exception ( "PluginsManager" , "An error occured while downloading plugin" , e , "PluginDownload" ) ;
63
93
}
64
94
65
- Application . Current . Dispatcher . Invoke ( ( ) => Install ( plugin , filePath ) ) ;
95
+ Application . Current . Dispatcher . Invoke ( ( ) => { Install ( plugin , filePath ) ; Context . API . RestartApp ( ) ; } ) ;
66
96
}
67
97
68
- internal void Update ( )
98
+ internal List < Result > RequestUpdate ( string search )
69
99
{
70
- throw new NotImplementedException ( ) ;
100
+ var autocompletedResults = AutoCompleteReturnAllResults ( search ,
101
+ Settings . HotkeyUpdate ,
102
+ "Update" ,
103
+ "Select a plugin to update" ) ;
104
+
105
+ if ( autocompletedResults . Any ( ) )
106
+ return autocompletedResults ;
107
+
108
+ var uninstallSearch = search . Replace ( Settings . HotkeyUpdate , string . Empty ) . TrimStart ( ) ;
109
+
110
+
111
+ var resultsForUpdate =
112
+ from existingPlugin in Context . API . GetAllPlugins ( )
113
+ join pluginFromManifest in pluginsManifest . UserPlugins
114
+ on existingPlugin . Metadata . ID equals pluginFromManifest . ID
115
+ where existingPlugin . Metadata . Version != pluginFromManifest . Version
116
+ select
117
+ new
118
+ {
119
+ pluginFromManifest . Name ,
120
+ pluginFromManifest . Author ,
121
+ CurrentVersion = existingPlugin . Metadata . Version ,
122
+ NewVersion = pluginFromManifest . Version ,
123
+ existingPlugin . Metadata . IcoPath ,
124
+ PluginExistingMetadata = existingPlugin . Metadata ,
125
+ PluginNewUserPlugin = pluginFromManifest
126
+ } ;
127
+
128
+ if ( ! resultsForUpdate . Any ( ) )
129
+ return new List < Result > {
130
+ new Result
131
+ {
132
+ Title = Context . API . GetTranslation ( "plugin_pluginsmanager_update_noresult_title" ) ,
133
+ SubTitle = Context . API . GetTranslation ( "plugin_pluginsmanager_update_noresult_subtitle" ) ,
134
+ IcoPath = icoPath
135
+ } } ;
136
+
137
+
138
+ var results = resultsForUpdate
139
+ . Select ( x =>
140
+ new Result
141
+ {
142
+ Title = $ "{ x . Name } by { x . Author } ",
143
+ SubTitle = $ "Update from version { x . CurrentVersion } to { x . NewVersion } ",
144
+ IcoPath = x . IcoPath ,
145
+ Action = e =>
146
+ {
147
+ string message = string . Format ( Context . API . GetTranslation ( "plugin_pluginsmanager_update_prompt" ) ,
148
+ x . Name , x . Author ,
149
+ Environment . NewLine , Environment . NewLine ) ;
150
+
151
+ if ( MessageBox . Show ( message , Context . API . GetTranslation ( "plugin_pluginsmanager_update_title" ) ,
152
+ MessageBoxButton . YesNo ) == MessageBoxResult . Yes )
153
+ {
154
+ Uninstall ( x . PluginExistingMetadata ) ;
155
+
156
+ var downloadToFilePath = Path . Combine ( DataLocation . PluginsDirectory , $ "{ x . Name } -{ x . NewVersion } .zip") ;
157
+ Http . Download ( x . PluginNewUserPlugin . UrlDownload , downloadToFilePath ) ;
158
+ Install ( x . PluginNewUserPlugin , downloadToFilePath ) ;
159
+
160
+ Context . API . RestartApp ( ) ;
161
+
162
+ return true ;
163
+ }
164
+
165
+ return false ;
166
+ }
167
+ } ) ;
168
+
169
+ return Search ( results , uninstallSearch ) ;
71
170
}
72
171
73
172
internal bool PluginExists ( string id )
74
173
{
75
174
return Context . API . GetAllPlugins ( ) . Any ( x => x . Metadata . ID == id ) ;
76
175
}
77
176
78
- internal void PluginsManifestSiteOpen ( )
79
- {
80
- //Open from context menu https://git.vcmq.workers.dev/Flow-Launcher/Flow.Launcher.PluginsManifest
81
- throw new NotImplementedException ( ) ;
82
- }
83
-
84
- internal List < Result > Search ( List < Result > results , string searchName )
177
+ internal List < Result > Search ( IEnumerable < Result > results , string searchName )
85
178
{
86
179
if ( string . IsNullOrEmpty ( searchName ) )
87
- return results ;
180
+ return results . ToList ( ) ;
88
181
89
182
return results
90
183
. Where ( x =>
@@ -114,11 +207,10 @@ internal List<Result> RequestInstallOrUpdate(string searchName)
114
207
Application . Current . MainWindow . Hide ( ) ;
115
208
InstallOrUpdate ( x ) ;
116
209
117
- return true ;
210
+ return ShouldHideWindow ;
118
211
} ,
119
212
ContextData = x
120
- } )
121
- . ToList ( ) ;
213
+ } ) ;
122
214
123
215
return Search ( results , searchName ) ;
124
216
}
@@ -154,42 +246,24 @@ private void Install(UserPlugin plugin, string downloadedFilePath)
154
246
return ;
155
247
}
156
248
157
- string newPluginPath = Path . Combine ( DataLocation . PluginsDirectory , $ "{ plugin . Name } { plugin . ID } ") ;
249
+ string newPluginPath = Path . Combine ( DataLocation . PluginsDirectory , $ "{ plugin . Name } - { plugin . Version } ") ;
158
250
159
251
Directory . Move ( pluginFolderPath , newPluginPath ) ;
160
-
161
- Context . API . RestartApp ( ) ;
162
252
}
163
253
164
254
internal List < Result > RequestUninstall ( string search )
165
255
{
166
- if ( ! string . IsNullOrEmpty ( search )
167
- && Settings . UninstallHotkey . StartsWith ( search )
168
- && ( Settings . UninstallHotkey != search || ! search . StartsWith ( Settings . UninstallHotkey ) ) )
169
- {
170
- return
171
- new List < Result >
172
- {
173
- new Result
174
- {
175
- Title = "Uninstall" ,
176
- IcoPath = icoPath ,
177
- SubTitle = "Select a plugin to uninstall" ,
178
- Action = e =>
179
- {
180
- Context
181
- . API
182
- . ChangeQuery ( $ "{ Context . CurrentPluginMetadata . ActionKeywords . FirstOrDefault ( ) } { Settings . UninstallHotkey } ") ;
256
+ var autocompletedResults = AutoCompleteReturnAllResults ( search ,
257
+ Settings . HotkeyUninstall ,
258
+ "Uninstall" ,
259
+ "Select a plugin to uninstall" ) ;
183
260
184
- return false ;
185
- }
186
- }
187
- } ;
188
- }
261
+ if ( autocompletedResults . Any ( ) )
262
+ return autocompletedResults ;
189
263
190
- var uninstallSearch = search . Replace ( Settings . UninstallHotkey , string . Empty ) . TrimStart ( ) ;
264
+ var uninstallSearch = search . Replace ( Settings . HotkeyUninstall , string . Empty ) . TrimStart ( ) ;
191
265
192
- var results = Context . API
266
+ var results = Context . API
193
267
. GetAllPlugins ( )
194
268
. Select ( x =>
195
269
new Result
@@ -199,30 +273,60 @@ internal List<Result> RequestUninstall(string search)
199
273
IcoPath = x . Metadata . IcoPath ,
200
274
Action = e =>
201
275
{
202
- Application . Current . MainWindow . Hide ( ) ;
203
- Uninstall ( x . Metadata ) ;
276
+ string message = string . Format ( Context . API . GetTranslation ( "plugin_pluginsmanager_uninstall_prompt" ) ,
277
+ x . Metadata . Name , x . Metadata . Author ,
278
+ Environment . NewLine , Environment . NewLine ) ;
204
279
205
- return true ;
280
+ if ( MessageBox . Show ( message , Context . API . GetTranslation ( "plugin_pluginsmanager_uninstall_title" ) ,
281
+ MessageBoxButton . YesNo ) == MessageBoxResult . Yes )
282
+ {
283
+ Application . Current . MainWindow . Hide ( ) ;
284
+ Uninstall ( x . Metadata ) ;
285
+ Context . API . RestartApp ( ) ;
286
+
287
+ return true ;
288
+ }
289
+
290
+ return false ;
206
291
}
207
- } )
208
- . ToList ( ) ;
292
+ } ) ;
209
293
210
294
return Search ( results , uninstallSearch ) ;
211
295
}
212
296
213
297
private void Uninstall ( PluginMetadata plugin )
214
298
{
215
- string message = string . Format ( Context . API . GetTranslation ( "plugin_pluginsmanager_uninstall_prompt" ) ,
216
- plugin . Name , plugin . Author ,
217
- Environment . NewLine , Environment . NewLine ) ;
299
+ // Marked for deletion. Will be deleted on next start up
300
+ using var _ = File . CreateText ( Path . Combine ( plugin . PluginDirectory , "NeedDelete.txt" ) ) ;
301
+ }
218
302
219
- if ( MessageBox . Show ( message , Context . API . GetTranslation ( "plugin_pluginsmanager_uninstall_title" ) ,
220
- MessageBoxButton . YesNo ) == MessageBoxResult . Yes )
303
+ private List < Result > AutoCompleteReturnAllResults ( string search , string hotkey , string title , string subtitle )
304
+ {
305
+ if ( ! string . IsNullOrEmpty ( search )
306
+ && hotkey . StartsWith ( search )
307
+ && ( hotkey != search || ! search . StartsWith ( hotkey ) ) )
221
308
{
222
- using var _ = File . CreateText ( Path . Combine ( plugin . PluginDirectory , "NeedDelete.txt" ) ) ;
223
-
224
- Context . API . RestartApp ( ) ;
309
+ return
310
+ new List < Result >
311
+ {
312
+ new Result
313
+ {
314
+ Title = title ,
315
+ IcoPath = icoPath ,
316
+ SubTitle = subtitle ,
317
+ Action = e =>
318
+ {
319
+ Context
320
+ . API
321
+ . ChangeQuery ( $ "{ Context . CurrentPluginMetadata . ActionKeywords . FirstOrDefault ( ) } { hotkey } ") ;
322
+
323
+ return false ;
324
+ }
325
+ }
326
+ } ;
225
327
}
328
+
329
+ return new List < Result > ( ) ;
226
330
}
227
331
}
228
332
}
0 commit comments