4
4
using System . Reactive ;
5
5
using System . Reactive . Concurrency ;
6
6
using System . Reactive . Linq ;
7
+ using System . Reflection ;
7
8
using System . Threading . Tasks ;
8
9
using K8sFileBrowser . Models ;
9
10
using K8sFileBrowser . Services ;
11
+ using Microsoft . IdentityModel . Tokens ;
10
12
using ReactiveUI ;
11
13
using ReactiveUI . Fody . Helpers ;
14
+ using Serilog ;
12
15
13
16
namespace K8sFileBrowser . ViewModels ;
14
17
15
18
public class MainWindowViewModel : ViewModelBase
16
19
{
20
+
21
+ #region Properties
22
+
23
+ [ Reactive ]
24
+ public string ? Version { get ; set ; } = null ! ;
25
+
17
26
[ Reactive ]
18
27
public IEnumerable < ClusterContext > ClusterContexts { get ; set ; } = null ! ;
19
28
@@ -49,20 +58,25 @@ public class MainWindowViewModel : ViewModelBase
49
58
50
59
[ Reactive ]
51
60
public Message Message { get ; set ; } = null ! ;
61
+
62
+ #endregion Properties
52
63
64
+ #region Commands
65
+
53
66
public ReactiveCommand < Unit , Unit > DownloadCommand { get ; private set ; } = null ! ;
54
67
public ReactiveCommand < Unit , Unit > DownloadLogCommand { get ; private set ; } = null ! ;
55
68
public ReactiveCommand < Unit , Unit > ParentCommand { get ; private set ; } = null ! ;
56
69
public ReactiveCommand < Unit , Unit > OpenCommand { get ; private set ; } = null ! ;
57
-
58
70
private ReactiveCommand < Namespace , IEnumerable < Pod > > GetPodsForNamespace { get ; set ; } = null ! ;
59
71
72
+ #endregion Commands
60
73
61
74
public MainWindowViewModel ( )
62
75
{
63
- //TODO: use dependency injection to get the kubernetes service
64
76
IKubernetesService kubernetesService = new KubernetesService ( ) ;
65
77
78
+ Version = Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version ? . ToString ( ) ;
79
+
66
80
// commands
67
81
ConfigureOpenDirectoryCommand ( ) ;
68
82
ConfigureDownloadFileCommand ( kubernetesService ) ;
@@ -81,6 +95,8 @@ public MainWindowViewModel()
81
95
InitiallyLoadContexts ( kubernetesService ) ;
82
96
}
83
97
98
+ #region Property Subscriptions
99
+
84
100
private void InitiallyLoadContexts ( IKubernetesService kubernetesService )
85
101
{
86
102
// load the cluster contexts when the view model is created
@@ -91,97 +107,99 @@ private void InitiallyLoadContexts(IKubernetesService kubernetesService)
91
107
. ObserveOn ( RxApp . MainThreadScheduler )
92
108
. Subscribe ( x =>
93
109
{
110
+ ResetNamespaces ( ) ;
94
111
ClusterContexts = x ;
112
+
95
113
// select the current cluster context
96
114
SelectedClusterContext = ClusterContexts
97
- . FirstOrDefault ( x => x . Name == kubernetesService . GetCurrentContext ( ) ) ;
115
+ . FirstOrDefault ( c => c . Name == kubernetesService . GetCurrentContext ( ) ) ;
98
116
} ) ;
99
117
}
100
-
101
- private void RegisterResetPath ( )
118
+
119
+ private void RegisterReadNamespaces ( IKubernetesService kubernetesService )
102
120
{
103
- // reset the path when the pod or namespace changes
104
- this . WhenAnyValue ( c => c . SelectedContainer )
121
+ // read the cluster contexts
122
+ this
123
+ . WhenAnyValue ( c => c . SelectedClusterContext )
105
124
. Throttle ( new TimeSpan ( 10 ) )
106
- . ObserveOn ( RxApp . TaskpoolScheduler )
107
- . Subscribe ( _ => SelectedPath = "/" ) ;
125
+ . SelectMany ( context => GetClusterContextAsync ( context , kubernetesService ) )
126
+ . ObserveOn ( RxApp . MainThreadScheduler )
127
+ . Subscribe ( ns =>
128
+ {
129
+ ResetPods ( ) ;
130
+ Namespaces = ns ;
131
+ } ) ;
108
132
}
109
-
133
+
134
+ private void RegisterReadPods ( )
135
+ {
136
+ // read the pods when the namespace changes
137
+ this
138
+ . WhenAnyValue ( c => c . SelectedNamespace )
139
+ . Throttle ( new TimeSpan ( 10 ) )
140
+ . Where ( x => x != null )
141
+ . SelectMany ( ns => GetPodsForNamespace . Execute ( ns ! ) )
142
+ . ObserveOn ( RxApp . MainThreadScheduler )
143
+ . Subscribe ( x =>
144
+ {
145
+ ResetContainers ( ) ;
146
+ Pods = x ;
147
+ } ) ;
148
+ }
149
+
110
150
private void RegisterReadContainers ( )
111
151
{
112
152
// read the file information when the path changes
113
153
this
114
154
. WhenAnyValue ( c => c . SelectedPod )
115
155
. Throttle ( new TimeSpan ( 10 ) )
116
- . Select ( x => x == null
117
- ? new List < Container > ( )
118
- : x . Containers . Select ( c => new Container { Name = c } ) )
156
+ . Where ( x => x != null )
157
+ . Select ( x => x ! . Containers . Select ( c => new Container { Name = c } ) )
119
158
. ObserveOn ( RxApp . MainThreadScheduler )
120
159
. Subscribe ( x =>
121
160
{
161
+ ResetPath ( ) ;
122
162
Containers = x ;
123
- FileInformation = new List < FileInformation > ( ) ;
124
163
} ) ;
125
164
126
165
this . WhenAnyValue ( x => x . Containers )
127
166
. Throttle ( new TimeSpan ( 10 ) )
167
+ . Where ( x => ! x . IsNullOrEmpty ( ) )
128
168
. ObserveOn ( RxApp . MainThreadScheduler )
129
169
. Subscribe ( x => SelectedContainer = x ? . FirstOrDefault ( ) ) ;
130
- }
131
-
132
- private void RegisterReadFiles ( IKubernetesService kubernetesService )
133
- {
134
- // read the file information when the path changes
135
- this
136
- . WhenAnyValue ( c => c . SelectedContainer , c => c . SelectedPath )
137
- . Throttle ( new TimeSpan ( 10 ) )
138
- . Select ( x => x . Item1 == null || x . Item2 == null
139
- ? new List < FileInformation > ( )
140
- : GetFileInformation ( kubernetesService , x . Item2 , SelectedPod ! , SelectedNamespace ! , x . Item1 ) )
141
- . ObserveOn ( RxApp . MainThreadScheduler )
142
- . Subscribe ( x => FileInformation = x ) ;
143
170
}
144
171
145
- private void RegisterReadPods ( )
172
+ private void RegisterResetPath ( )
146
173
{
147
- // read the pods when the namespace changes
148
- this
149
- . WhenAnyValue ( c => c . SelectedNamespace )
174
+ // reset the path when the pod or namespace changes
175
+ this . WhenAnyValue ( c => c . SelectedContainer )
150
176
. Throttle ( new TimeSpan ( 10 ) )
151
- . SelectMany ( ns => GetPodsForNamespace . Execute ( ns ! ) )
177
+ . Where ( x => x != null )
152
178
. ObserveOn ( RxApp . MainThreadScheduler )
153
- . Subscribe ( x =>
154
- {
155
- Pods = x ;
156
- Containers = null ;
157
- FileInformation = new List < FileInformation > ( ) ;
158
- } ) ;
179
+ . Subscribe ( _ => SelectedPath = "/" ) ;
159
180
}
160
181
161
- private void RegisterReadNamespaces ( IKubernetesService kubernetesService )
182
+ private void RegisterReadFiles ( IKubernetesService kubernetesService )
162
183
{
163
- // read the cluster contexts
184
+ // read the file information when the path changes
164
185
this
165
- . WhenAnyValue ( c => c . SelectedClusterContext )
186
+ . WhenAnyValue ( c => c . SelectedContainer , c => c . SelectedPath )
166
187
. Throttle ( new TimeSpan ( 10 ) )
167
- . SelectMany ( context => GetClusterContextAsync ( context , kubernetesService ) )
188
+ . Where ( x => x is { Item1 : not null , Item2 : not null } )
189
+ . Select ( x => GetFileInformation ( kubernetesService , x . Item2 ! , SelectedPod ! , SelectedNamespace ! , x . Item1 ! ) )
168
190
. ObserveOn ( RxApp . MainThreadScheduler )
169
- . Subscribe ( ns =>
170
- {
171
- Namespaces = ns ;
172
- Pods = new List < Pod > ( ) ;
173
- Containers = null ;
174
- FileInformation = new List < FileInformation > ( ) ;
175
- } ) ;
191
+ . Subscribe ( x => FileInformation = x ) ;
176
192
}
193
+ #endregion Property Subscriptions
177
194
195
+ #region Configure Commands
178
196
private void ConfigureGetPodsForNamespaceCommand ( IKubernetesService kubernetesService )
179
197
{
180
198
GetPodsForNamespace = ReactiveCommand . CreateFromObservable < Namespace , IEnumerable < Pod > > ( ns =>
181
199
Observable . StartAsync ( _ => PodsAsync ( ns , kubernetesService ) , RxApp . TaskpoolScheduler ) ) ;
182
200
183
201
GetPodsForNamespace . ThrownExceptions . ObserveOn ( RxApp . MainThreadScheduler )
184
- . Subscribe ( ex => ShowErrorMessage ( ex . Message ) . ConfigureAwait ( false ) . GetAwaiter ( ) . GetResult ( ) ) ;
202
+ . Subscribe ( ShowErrorMessage ) ;
185
203
}
186
204
187
205
private void ConfigureParentDirectoryCommand ( )
@@ -200,7 +218,7 @@ private void ConfigureParentDirectoryCommand()
200
218
} , isNotRoot , RxApp . MainThreadScheduler ) ;
201
219
202
220
ParentCommand . ThrownExceptions . ObserveOn ( RxApp . MainThreadScheduler )
203
- . Subscribe ( ex => ShowErrorMessage ( ex . Message ) . ConfigureAwait ( false ) . GetAwaiter ( ) . GetResult ( ) ) ;
221
+ . Subscribe ( ShowErrorMessage ) ;
204
222
}
205
223
206
224
private void ConfigureDownloadLogCommand ( IKubernetesService kubernetesService )
@@ -225,7 +243,7 @@ await Observable.StartAsync(async () =>
225
243
} , isSelectedPod , RxApp . MainThreadScheduler ) ;
226
244
227
245
DownloadLogCommand . ThrownExceptions . ObserveOn ( RxApp . MainThreadScheduler )
228
- . Subscribe ( ex => ShowErrorMessage ( ex . Message ) . ConfigureAwait ( false ) . GetAwaiter ( ) . GetResult ( ) ) ;
246
+ . Subscribe ( ShowErrorMessage ) ;
229
247
}
230
248
231
249
private void ConfigureDownloadFileCommand ( IKubernetesService kubernetesService )
@@ -251,7 +269,7 @@ await Observable.StartAsync(async () =>
251
269
} , isFile , RxApp . MainThreadScheduler ) ;
252
270
253
271
DownloadCommand . ThrownExceptions . ObserveOn ( RxApp . MainThreadScheduler )
254
- . Subscribe ( ex => ShowErrorMessage ( ex . Message ) . ConfigureAwait ( false ) . GetAwaiter ( ) . GetResult ( ) ) ;
272
+ . Subscribe ( ShowErrorMessage ) ;
255
273
}
256
274
257
275
private void ConfigureOpenDirectoryCommand ( )
@@ -270,9 +288,13 @@ private void ConfigureOpenDirectoryCommand()
270
288
isDirectory , RxApp . MainThreadScheduler ) ;
271
289
272
290
OpenCommand . ThrownExceptions . ObserveOn ( RxApp . MainThreadScheduler )
273
- . Subscribe ( ex => ShowErrorMessage ( ex . Message ) . ConfigureAwait ( false ) . GetAwaiter ( ) . GetResult ( ) ) ;
291
+ . Subscribe ( ShowErrorMessage ) ;
274
292
}
293
+
294
+ #endregion Configure Commands
275
295
296
+ #region Get Data
297
+
276
298
private static async Task < IEnumerable < Pod > > PodsAsync ( Namespace ? ns , IKubernetesService kubernetesService )
277
299
{
278
300
if ( ns == null )
@@ -296,10 +318,8 @@ private async Task<IEnumerable<Namespace>> GetClusterContextAsync(ClusterContext
296
318
}
297
319
catch ( Exception e )
298
320
{
299
- RxApp . MainThreadScheduler . Schedule ( Action ) ;
321
+ ShowErrorMessage ( e ) ;
300
322
return new List < Namespace > ( ) ;
301
-
302
- async void Action ( ) => await ShowErrorMessage ( e . Message ) ;
303
323
}
304
324
}
305
325
@@ -326,7 +346,45 @@ private IList<FileInformation> GetFileInformation(IKubernetesService kubernetesS
326
346
Parent = parent
327
347
} ) . ToList ( ) ;
328
348
}
349
+
350
+ #endregion Get Data
351
+
352
+ #region Reset Data
353
+
354
+ private void ResetPath ( )
355
+ {
356
+ FileInformation = new List < FileInformation > ( ) ;
357
+ SelectedPath = null ;
358
+ SelectedContainer = null ;
359
+ }
360
+
361
+ private void ResetContainers ( )
362
+ {
363
+ ResetPath ( ) ;
364
+ Containers = new List < Container > ( ) ;
365
+ SelectedPod = null ;
366
+
367
+ }
368
+
369
+ private void ResetPods ( )
370
+ {
371
+ ResetContainers ( ) ;
372
+ SelectedNamespace = null ;
373
+ Pods = new List < Pod > ( ) ;
329
374
375
+ }
376
+
377
+ private void ResetNamespaces ( )
378
+ {
379
+ ResetPods ( ) ;
380
+ Namespaces = new List < Namespace > ( ) ;
381
+ SelectedClusterContext = null ;
382
+ }
383
+
384
+ #endregion Reset Data
385
+
386
+ #region show messages
387
+
330
388
private void ShowWorkingMessage ( string message )
331
389
{
332
390
Message = new Message
@@ -337,25 +395,34 @@ private void ShowWorkingMessage(string message)
337
395
} ;
338
396
}
339
397
340
- private async Task ShowErrorMessage ( string message )
398
+ private void ShowErrorMessage ( string message )
341
399
{
342
- Message = new Message
400
+ async void Action ( )
343
401
{
344
- IsVisible = true ,
345
- Text = message ,
346
- IsError = true
347
- } ;
348
- await Task . Delay ( 7000 ) ;
349
- HideWorkingMessage ( ) ;
402
+ Message = new Message { IsVisible = true , Text = message , IsError = true } ;
403
+ await Task . Delay ( 7000 ) ;
404
+ HideWorkingMessage ( ) ;
405
+ }
406
+
407
+ RxApp . MainThreadScheduler . Schedule ( Action ) ;
408
+ }
409
+
410
+ private void ShowErrorMessage ( Exception exception )
411
+ {
412
+ // ReSharper disable once TemplateIsNotCompileTimeConstantProblem
413
+ Log . Error ( exception , exception . Message ) ;
414
+ ShowErrorMessage ( exception . Message ) ;
350
415
}
351
416
352
417
private void HideWorkingMessage ( )
353
418
{
354
- Message = new Message
419
+ RxApp . MainThreadScheduler . Schedule ( ( ) => Message = new Message
355
420
{
356
421
IsVisible = false ,
357
422
Text = "" ,
358
423
IsError = false
359
- } ;
424
+ } ) ;
360
425
}
426
+
427
+ #endregion show messages
361
428
}
0 commit comments