Skip to content

Commit 6d03c88

Browse files
committed
reworked the whole reactive property handling
1 parent a696152 commit 6d03c88

File tree

4 files changed

+139
-73
lines changed

4 files changed

+139
-73
lines changed

.nuke/build.schema.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@
7575
"Clean",
7676
"Publish",
7777
"PublishLinux",
78-
"PublishWin",
79-
"Restore"
78+
"PublishWin"
8079
]
8180
}
8281
},
@@ -89,8 +88,7 @@
8988
"Clean",
9089
"Publish",
9190
"PublishLinux",
92-
"PublishWin",
93-
"Restore"
91+
"PublishWin"
9492
]
9593
}
9694
},

K8sFileBrowser/App.axaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
Accent="#677696"
2121
RegionColor="#282c34"
2222
ErrorText="Red"
23-
AltHigh="#282c34"
23+
AltHigh="#343a45"
2424
AltMediumLow="#2c313c"
2525
ListLow="#21252b"
2626
ListMedium="#2c313c"

K8sFileBrowser/ViewModels/MainWindowViewModel.cs

Lines changed: 134 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,25 @@
44
using System.Reactive;
55
using System.Reactive.Concurrency;
66
using System.Reactive.Linq;
7+
using System.Reflection;
78
using System.Threading.Tasks;
89
using K8sFileBrowser.Models;
910
using K8sFileBrowser.Services;
11+
using Microsoft.IdentityModel.Tokens;
1012
using ReactiveUI;
1113
using ReactiveUI.Fody.Helpers;
14+
using Serilog;
1215

1316
namespace K8sFileBrowser.ViewModels;
1417

1518
public class MainWindowViewModel : ViewModelBase
1619
{
20+
21+
#region Properties
22+
23+
[Reactive]
24+
public string? Version { get; set; } = null!;
25+
1726
[Reactive]
1827
public IEnumerable<ClusterContext> ClusterContexts { get; set; } = null!;
1928

@@ -49,20 +58,25 @@ public class MainWindowViewModel : ViewModelBase
4958

5059
[Reactive]
5160
public Message Message { get; set; } = null!;
61+
62+
#endregion Properties
5263

64+
#region Commands
65+
5366
public ReactiveCommand<Unit, Unit> DownloadCommand { get; private set; } = null!;
5467
public ReactiveCommand<Unit, Unit> DownloadLogCommand { get; private set; } = null!;
5568
public ReactiveCommand<Unit, Unit> ParentCommand { get; private set; } = null!;
5669
public ReactiveCommand<Unit, Unit> OpenCommand { get; private set; } = null!;
57-
5870
private ReactiveCommand<Namespace, IEnumerable<Pod>> GetPodsForNamespace { get; set; } = null!;
5971

72+
#endregion Commands
6073

6174
public MainWindowViewModel()
6275
{
63-
//TODO: use dependency injection to get the kubernetes service
6476
IKubernetesService kubernetesService = new KubernetesService();
6577

78+
Version = Assembly.GetExecutingAssembly().GetName().Version?.ToString();
79+
6680
// commands
6781
ConfigureOpenDirectoryCommand();
6882
ConfigureDownloadFileCommand(kubernetesService);
@@ -81,6 +95,8 @@ public MainWindowViewModel()
8195
InitiallyLoadContexts(kubernetesService);
8296
}
8397

98+
#region Property Subscriptions
99+
84100
private void InitiallyLoadContexts(IKubernetesService kubernetesService)
85101
{
86102
// load the cluster contexts when the view model is created
@@ -91,97 +107,99 @@ private void InitiallyLoadContexts(IKubernetesService kubernetesService)
91107
.ObserveOn(RxApp.MainThreadScheduler)
92108
.Subscribe(x =>
93109
{
110+
ResetNamespaces();
94111
ClusterContexts = x;
112+
95113
// select the current cluster context
96114
SelectedClusterContext = ClusterContexts
97-
.FirstOrDefault(x => x.Name == kubernetesService.GetCurrentContext());
115+
.FirstOrDefault(c => c.Name == kubernetesService.GetCurrentContext());
98116
});
99117
}
100-
101-
private void RegisterResetPath()
118+
119+
private void RegisterReadNamespaces(IKubernetesService kubernetesService)
102120
{
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)
105124
.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+
});
108132
}
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+
110150
private void RegisterReadContainers()
111151
{
112152
// read the file information when the path changes
113153
this
114154
.WhenAnyValue(c => c.SelectedPod)
115155
.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}))
119158
.ObserveOn(RxApp.MainThreadScheduler)
120159
.Subscribe( x =>
121160
{
161+
ResetPath();
122162
Containers = x;
123-
FileInformation = new List<FileInformation>();
124163
});
125164

126165
this.WhenAnyValue(x => x.Containers)
127166
.Throttle(new TimeSpan(10))
167+
.Where(x => !x.IsNullOrEmpty())
128168
.ObserveOn(RxApp.MainThreadScheduler)
129169
.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);
143170
}
144171

145-
private void RegisterReadPods()
172+
private void RegisterResetPath()
146173
{
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)
150176
.Throttle(new TimeSpan(10))
151-
.SelectMany(ns => GetPodsForNamespace.Execute(ns!))
177+
.Where(x => x != null)
152178
.ObserveOn(RxApp.MainThreadScheduler)
153-
.Subscribe(x =>
154-
{
155-
Pods = x;
156-
Containers = null;
157-
FileInformation = new List<FileInformation>();
158-
});
179+
.Subscribe(_ => SelectedPath = "/");
159180
}
160181

161-
private void RegisterReadNamespaces(IKubernetesService kubernetesService)
182+
private void RegisterReadFiles(IKubernetesService kubernetesService)
162183
{
163-
// read the cluster contexts
184+
// read the file information when the path changes
164185
this
165-
.WhenAnyValue(c => c.SelectedClusterContext)
186+
.WhenAnyValue(c => c.SelectedContainer, c => c.SelectedPath)
166187
.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!))
168190
.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);
176192
}
193+
#endregion Property Subscriptions
177194

195+
#region Configure Commands
178196
private void ConfigureGetPodsForNamespaceCommand(IKubernetesService kubernetesService)
179197
{
180198
GetPodsForNamespace = ReactiveCommand.CreateFromObservable<Namespace, IEnumerable<Pod>>(ns =>
181199
Observable.StartAsync(_ => PodsAsync(ns, kubernetesService), RxApp.TaskpoolScheduler));
182200

183201
GetPodsForNamespace.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
184-
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult());
202+
.Subscribe(ShowErrorMessage);
185203
}
186204

187205
private void ConfigureParentDirectoryCommand()
@@ -200,7 +218,7 @@ private void ConfigureParentDirectoryCommand()
200218
}, isNotRoot, RxApp.MainThreadScheduler);
201219

202220
ParentCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
203-
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult());
221+
.Subscribe(ShowErrorMessage);
204222
}
205223

206224
private void ConfigureDownloadLogCommand(IKubernetesService kubernetesService)
@@ -225,7 +243,7 @@ await Observable.StartAsync(async () =>
225243
}, isSelectedPod, RxApp.MainThreadScheduler);
226244

227245
DownloadLogCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
228-
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult());
246+
.Subscribe(ShowErrorMessage);
229247
}
230248

231249
private void ConfigureDownloadFileCommand(IKubernetesService kubernetesService)
@@ -251,7 +269,7 @@ await Observable.StartAsync(async () =>
251269
}, isFile, RxApp.MainThreadScheduler);
252270

253271
DownloadCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
254-
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult());
272+
.Subscribe(ShowErrorMessage);
255273
}
256274

257275
private void ConfigureOpenDirectoryCommand()
@@ -270,9 +288,13 @@ private void ConfigureOpenDirectoryCommand()
270288
isDirectory, RxApp.MainThreadScheduler);
271289

272290
OpenCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
273-
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult());
291+
.Subscribe(ShowErrorMessage);
274292
}
293+
294+
#endregion Configure Commands
275295

296+
#region Get Data
297+
276298
private static async Task<IEnumerable<Pod>> PodsAsync(Namespace? ns, IKubernetesService kubernetesService)
277299
{
278300
if (ns == null)
@@ -296,10 +318,8 @@ private async Task<IEnumerable<Namespace>> GetClusterContextAsync(ClusterContext
296318
}
297319
catch (Exception e)
298320
{
299-
RxApp.MainThreadScheduler.Schedule(Action);
321+
ShowErrorMessage(e);
300322
return new List<Namespace>();
301-
302-
async void Action() => await ShowErrorMessage(e.Message);
303323
}
304324
}
305325

@@ -326,7 +346,45 @@ private IList<FileInformation> GetFileInformation(IKubernetesService kubernetesS
326346
Parent = parent
327347
}).ToList();
328348
}
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>();
329374

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+
330388
private void ShowWorkingMessage(string message)
331389
{
332390
Message = new Message
@@ -337,25 +395,34 @@ private void ShowWorkingMessage(string message)
337395
};
338396
}
339397

340-
private async Task ShowErrorMessage(string message)
398+
private void ShowErrorMessage(string message)
341399
{
342-
Message = new Message
400+
async void Action()
343401
{
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);
350415
}
351416

352417
private void HideWorkingMessage()
353418
{
354-
Message = new Message
419+
RxApp.MainThreadScheduler.Schedule(() => Message = new Message
355420
{
356421
IsVisible = false,
357422
Text = "",
358423
IsError = false
359-
};
424+
});
360425
}
426+
427+
#endregion show messages
361428
}

0 commit comments

Comments
 (0)