Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ApplicationsViewModel.cs
1using CommunityToolkit.Mvvm.ComponentModel;
2using CommunityToolkit.Mvvm.Input;
3using EDaler;
17using NeuroFeatures;
21
23{
27 public partial class ApplicationsViewModel : XmppViewModel
28 {
33 : base()
34 {
35 }
36
37 protected override async Task OnInitialize()
38 {
39 if (ServiceRef.TagProfile.IdentityApplication is not null)
40 {
41 if (ServiceRef.TagProfile.IdentityApplication.IsDiscarded())
42 await ServiceRef.TagProfile.SetIdentityApplication(null, true);
43 }
44
45 this.IdentityApplicationSent = ServiceRef.TagProfile.IdentityApplication is not null;
46
47 this.HasWallet = ServiceRef.TagProfile.HasWallet;
48 this.HasLegalIdentity = ServiceRef.TagProfile.LegalIdentity is not null &&
49 ServiceRef.TagProfile.LegalIdentity.State == IdentityState.Approved;
50
51 ServiceRef.XmppService.IdentityApplicationChanged += this.XmppService_IdentityApplicationChanged;
52 ServiceRef.XmppService.LegalIdentityChanged += this.XmppService_LegalIdentityChanged;
53 ServiceRef.TagProfile.OnPropertiesChanged += this.TagProfile_OnPropertiesChanged;
54
55 await base.OnInitialize();
56 this.NotifyCommandsCanExecuteChanged();
57 }
58
59 protected override Task OnDispose()
60 {
61 ServiceRef.XmppService.IdentityApplicationChanged -= this.XmppService_IdentityApplicationChanged;
62 ServiceRef.XmppService.LegalIdentityChanged -= this.XmppService_LegalIdentityChanged;
63 ServiceRef.TagProfile.OnPropertiesChanged -= this.TagProfile_OnPropertiesChanged;
64
65 return base.OnDispose();
66 }
67
68 private Task XmppService_IdentityApplicationChanged(object? Sender, LegalIdentityEventArgs e)
69 {
70 MainThread.BeginInvokeOnMainThread(() =>
71 {
72 this.IdentityApplicationSent = ServiceRef.TagProfile.IdentityApplication is not null;
73 });
74
75 return Task.CompletedTask;
76 }
77
78 private Task XmppService_LegalIdentityChanged(object Sender, LegalIdentityEventArgs e)
79 {
80 MainThread.BeginInvokeOnMainThread(() =>
81 {
82 this.HasLegalIdentity = ServiceRef.TagProfile.LegalIdentity is not null &&
83 ServiceRef.TagProfile.LegalIdentity.State == IdentityState.Approved;
84 });
85
86 return Task.CompletedTask;
87 }
88
89 private void TagProfile_OnPropertiesChanged(object? sender, EventArgs e)
90 {
91 MainThread.BeginInvokeOnMainThread(() =>
92 {
93 this.HasWallet = ServiceRef.TagProfile.HasWallet;
94 });
95 }
96
97 protected override async Task OnAppearing()
98 {
99 await base.OnAppearing();
100
101 // Page is not correctly updated if changes has happened when viewing a sub-view. Fix by resending notification.
102
103 bool IdApplicationSent = ServiceRef.TagProfile.IdentityApplication is not null;
104 if (this.IdentityApplicationSent != IdApplicationSent)
105 this.IdentityApplicationSent = IdApplicationSent;
106 else
107 this.OnPropertyChanged(nameof(this.IdentityApplicationSent));
108 }
109
111 protected override Task XmppService_ConnectionStateChanged(object? Sender, XmppState NewState)
112 {
113 return MainThread.InvokeOnMainThreadAsync(async () =>
114 {
115 await base.XmppService_ConnectionStateChanged(Sender, NewState);
116
117 this.NotifyCommandsCanExecuteChanged();
118 });
119 }
120
122 public override void SetIsBusy(bool IsBusy)
123 {
124 base.SetIsBusy(IsBusy);
125 this.NotifyCommandsCanExecuteChanged();
126 }
127
128 private void NotifyCommandsCanExecuteChanged()
129 {
130 this.ApplyPersonalIdCommand.NotifyCanExecuteChanged();
131 this.ApplyOrganizationalIdCommand.NotifyCanExecuteChanged();
132 this.BuyEDalerCommand.NotifyCanExecuteChanged();
133 }
134
135 #region Properties
136
140 public bool CanExecuteCommands => !this.IsBusy;
141
145 [ObservableProperty]
146 private bool identityApplicationSent;
147
151 [ObservableProperty]
152 private bool hasLegalIdentity;
153
157 [ObservableProperty]
158 private bool hasWallet;
159
160 #endregion
161
162 #region Commands
163
164 [RelayCommand(CanExecute = nameof(CanExecuteCommands))]
165 private async Task ViewIdApplication()
166 {
167 try
168 {
169 if (ServiceRef.TagProfile.IdentityApplication is null)
170 return;
171
172 if (!await App.AuthenticateUser(AuthenticationPurpose.ViewId))
173 return;
174
176 }
177 catch (Exception ex)
178 {
179 ServiceRef.LogService.LogException(ex);
181 }
182 }
183
184 [RelayCommand(CanExecute = nameof(CanExecuteCommands))]
185 private async Task ApplyPersonalId()
186 {
187 try
188 {
189 if (!await App.AuthenticateUser(AuthenticationPurpose.ApplyForPersonalId))
190 return;
191
192 await ServiceRef.UiService.GoToAsync(nameof(ApplyIdPage), new ApplyIdNavigationArgs(true, false));
193 }
194 catch (Exception ex)
195 {
196 ServiceRef.LogService.LogException(ex);
198 }
199 }
200
201 [RelayCommand(CanExecute = nameof(CanExecuteCommands))]
202 private async Task ApplyOrganizationalId()
203 {
204 try
205 {
206 if (!await App.AuthenticateUser(AuthenticationPurpose.ApplyForOrganizationalId))
207 return;
208
209 await ServiceRef.UiService.GoToAsync(nameof(ApplyIdPage), new ApplyIdNavigationArgs(false, false));
210 }
211 catch (Exception ex)
212 {
213 ServiceRef.LogService.LogException(ex);
215 }
216 }
217
218 [RelayCommand(CanExecute = nameof(CanExecuteCommands))]
219 private async Task BuyEDaler()
220 {
221 try
222 {
223 IBuyEDalerServiceProvider[] ServiceProviders = await ServiceRef.XmppService.GetServiceProvidersForBuyingEDalerAsync();
224 Balance Balance = await ServiceRef.XmppService.GetEDalerBalance();
225
226 if (ServiceProviders.Length == 0)
227 {
229 await ServiceRef.UiService.GoToAsync(nameof(RequestPaymentPage), Args, BackMethod.CurrentPage);
230 }
231 else
232 {
233 List<IBuyEDalerServiceProvider> ServiceProviders2 = [];
234
235 ServiceProviders2.AddRange(ServiceProviders);
236 ServiceProviders2.Add(new EmptyBuyEDalerServiceProvider());
237
238 ServiceProvidersNavigationArgs e = new(ServiceProviders2.ToArray(),
239 ServiceRef.Localizer[nameof(AppResources.BuyEDaler)],
240 ServiceRef.Localizer[nameof(AppResources.SelectServiceProviderBuyEDaler)]);
241
243 if (e.ServiceProvider is null)
244 return;
245
246 IBuyEDalerServiceProvider? ServiceProvider = (IBuyEDalerServiceProvider?)(await e.ServiceProvider.Task);
247 if (ServiceProvider is null)
248 return;
249
250 if (!await App.AuthenticateUser(AuthenticationPurpose.ApplyForOrganizationalId))
251 return;
252
253 if (string.IsNullOrEmpty(ServiceProvider.Id))
254 {
256 await ServiceRef.UiService.GoToAsync(nameof(RequestPaymentPage), Args, BackMethod.CurrentPage);
257 }
258 else if (string.IsNullOrEmpty(ServiceProvider.BuyEDalerTemplateContractId))
259 {
260 TaskCompletionSource<decimal?> Result = new();
261 BuyEDalerNavigationArgs Args = new(Balance?.Currency, Result);
262
263 await ServiceRef.UiService.GoToAsync(nameof(BuyEDalerPage), Args, BackMethod.CurrentPage);
264
265 decimal? Amount = await Result.Task;
266 if (!Amount.HasValue)
267 return;
268
269 if (Amount.Value > 0)
270 {
272 Amount.Value, Balance?.Currency);
273
274 Amount = await Transaction.Wait();
275
276 if (Amount.HasValue && Amount.Value > 0)
277 {
278 ServiceRef.TagProfile.HasWallet = true;
279 await this.OpenWallet();
280 }
281 }
282 }
283 else
284 {
285 CreationAttributesEventArgs e2 = await ServiceRef.XmppService.GetNeuroFeatureCreationAttributes();
286 Dictionary<CaseInsensitiveString, object> Parameters = new()
287 {
288 { "Visibility", "CreatorAndParts" },
289 { "Role", "Buyer" },
290 { "Currency", Balance?.Currency ?? e2.Currency },
291 { "TrustProvider", e2.TrustProviderId }
292 };
293
294 await ServiceRef.ContractOrchestratorService.OpenContract(ServiceProvider.BuyEDalerTemplateContractId,
295 ServiceRef.Localizer[nameof(AppResources.BuyEDaler)], Parameters);
296
298 IDictionary<CaseInsensitiveString, object>[] Options = await OptionsTransaction.Wait();
299
300 if (ServiceRef.UiService.CurrentPage is IContractOptionsPage ContractOptionsPage)
301 MainThread.BeginInvokeOnMainThread(async () => await ContractOptionsPage.ShowContractOptions(Options));
302 }
303 }
304 }
305 catch (Exception ex)
306 {
307 ServiceRef.LogService.LogException(ex);
309 }
310 }
311
312 [RelayCommand(CanExecute = nameof(CanExecuteCommands))]
313 private Task OpenWallet()
314 {
315 return AppShellViewModel.ShowWallet();
316 }
317
318 #endregion
319 }
320}
Contains information about a balance.
Definition: Balance.cs:11
CaseInsensitiveString Currency
Currency of amount.
Definition: Balance.cs:54
Represents a transaction in the eDaler network.
Definition: Transaction.cs:36
The Application class, representing an instance of the Neuro-Access app.
Definition: App.xaml.cs:69
static Task< bool > AuthenticateUser(AuthenticationPurpose Purpose, bool Force=false)
Authenticates the user using the configured authentication method.
Definition: App.xaml.cs:981
Base class that references services in the app.
Definition: ServiceRef.cs:31
static ILogService LogService
Log service.
Definition: ServiceRef.cs:91
static IUiService UiService
Service serializing and managing UI-related tasks.
Definition: ServiceRef.cs:55
static ITagProfile TagProfile
TAG Profile service.
Definition: ServiceRef.cs:79
static IStringLocalizer Localizer
Localization service
Definition: ServiceRef.cs:235
static IContractOrchestratorService ContractOrchestratorService
Contract orchestrator service.
Definition: ServiceRef.cs:115
static IXmppService XmppService
The XMPP service for XMPP communication.
Definition: ServiceRef.cs:67
The view model to bind to for when displaying the applications page.
override async Task OnInitialize()
Method called when view is initialized for the first time. Use this method to implement registration ...
override async Task OnAppearing()
Method called when view is appearing on the screen.
override Task XmppService_ConnectionStateChanged(object? Sender, XmppState NewState)
Listens to connection state changes from the XMPP server.
ApplicationsViewModel()
Creates an instance of the ApplicationsViewModel class.
override Task OnDispose()
Method called when the view is disposed, and will not be used more. Use this method to unregister eve...
Page allowing the user to apply for a Personal ID.
Holds navigation parameters specific to buying eDaler.
A page that allows the user to buy eDaler.
Holds navigation parameters specific to an eDaler balance event.
A page that displays information about eDaler received.
A view model that holds the XMPP state.
Contains information about a service provider.
Interface for information about a service provider that users can use to buy eDaler.
Task DisplayException(Exception Exception, string? Title=null)
Displays an alert/message box to the user.
Task GoToAsync(string Route, BackMethod BackMethod=BackMethod.Inherited, string? UniqueId=null)
Navigates the AppShell to the specified route, with page arguments to match.
Interface for pages that can receive contract options from an asynchronous process.
BackMethod
Navigation Back Method
Definition: BackMethod.cs:7
class OptionsTransaction(string TransactionId)
Maintains the status of an ongoing retrieval of payment options.
class PaymentTransaction(string TransactionId, string Currency)
Maintains the status of an ongoing payment transaction.
class ApplyIdNavigationArgs(bool Personal, bool ReusePhoto)
Navigation arguments for the ApplyIdPage and ApplyIdViewModel.
AuthenticationPurpose
Purpose for requesting the user to authenticate itself.
IdentityState
Lists recognized legal identity states.
XmppState
State of XMPP connection.
Definition: XmppState.cs:7