Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
NotificationIntentRouter.cs
1using System.Threading;
2using System.Threading.Tasks;
24
26{
31 {
32 private readonly INotificationFilterRegistry filterRegistry;
33
39 {
40 this.filterRegistry = FilterRegistry;
41 }
42
44 public Task<NotificationRouteResult> RouteAsync(NotificationIntent Intent, bool FromUserInteraction, CancellationToken CancellationToken)
45 {
46 try
47 {
48 if (ServiceRef.NavigationService.CurrentPage is null)
49 return Task.FromResult(NotificationRouteResult.Deferred);
50
51 NotificationFilterDecision decision = this.filterRegistry.ShouldIgnore(Intent, FromUserInteraction, CancellationToken);
52 if (decision.IgnoreRoute)
53 return Task.FromResult(NotificationRouteResult.Ignored);
54
55 switch (Intent.Action)
56 {
57 case NotificationAction.OpenChat:
58 return this.RouteChatAsync(Intent, CancellationToken);
59 case NotificationAction.OpenProfile:
60 return this.RouteProfileAsync(Intent, CancellationToken);
61 case NotificationAction.OpenIdentity:
62 return this.RouteIdentityAsync(Intent, CancellationToken);
63 case NotificationAction.OpenContract:
64 return this.RouteContractAsync(Intent, CancellationToken);
65 case NotificationAction.OpenToken:
66 return this.RouteTokenAsync(CancellationToken);
67 case NotificationAction.OpenBalance:
68 return this.RouteBalanceAsync(CancellationToken);
69 case NotificationAction.OpenPetition:
70 return this.RoutePetitionAsync(Intent, CancellationToken);
71 case NotificationAction.OpenPresenceRequest:
72 return this.RoutePresenceAsync(Intent, CancellationToken);
73 case NotificationAction.OpenSettings:
74 return this.RouteSettingsAsync(CancellationToken);
75 default:
76 return Task.FromResult(NotificationRouteResult.NoHandler);
77 }
78 }
79 catch (Exception ex)
80 {
81 ServiceRef.LogService.LogException(ex);
82 return Task.FromResult(NotificationRouteResult.Failed);
83 }
84 }
85
86 private async Task<NotificationRouteResult> RouteChatAsync(NotificationIntent Intent, CancellationToken CancellationToken)
87 {
88 if (string.IsNullOrEmpty(Intent.EntityId))
89 return NotificationRouteResult.NoHandler;
90
91 ContactInfo? Info = await ContactInfo.FindByBareJid(Intent.EntityId);
92 string? FriendlyName = Info?.FriendlyName ?? Intent.EntityId;
93 string? LegalId = Info?.LegalId;
94
95 ChatNavigationArgs Args = new(LegalId, Intent.EntityId, FriendlyName);
96 await ServiceRef.NavigationService.GoToAsync(nameof(ChatPage), Args);
97 return NotificationRouteResult.Success;
98 }
99
100 private Task<NotificationRouteResult> RouteProfileAsync(NotificationIntent Intent, CancellationToken CancellationToken)
101 {
102 // No specific profile route mapped yet; fall back to contacts.
103 return this.RoutePresenceAsync(Intent, CancellationToken);
104 }
105
106 private async Task<NotificationRouteResult> RoutePresenceAsync(NotificationIntent Intent, CancellationToken CancellationToken)
107 {
108 await ServiceRef.NavigationService.GoToAsync(nameof(MyContactsPage));
109 return NotificationRouteResult.Deferred;
110 }
111
112 private async Task<NotificationRouteResult> RouteIdentityAsync(NotificationIntent Intent, CancellationToken CancellationToken)
113 {
114 if (string.IsNullOrEmpty(Intent.EntityId))
115 return NotificationRouteResult.NoHandler;
116
117 try
118 {
119 IdentityState? state = null;
120 if (Intent.Extras.TryGetValue("state", out string? stateString) && Enum.TryParse(stateString, out IdentityState parsed))
121 state = parsed;
122
123 KycReference? reference = null;
124 try
125 {
126 reference = await Database.FindFirstIgnoreRest<KycReference>(new FilterFieldEqualTo(nameof(KycReference.CreatedIdentityId), Intent.EntityId));
127 }
128 catch (Exception ex)
129 {
130 ServiceRef.LogService.LogException(ex);
131 }
132
133 bool isApproved = state == IdentityState.Approved || reference?.CreatedIdentityState == IdentityState.Approved;
134
135 if (reference is not null && !isApproved)
136 {
137 KycProcessNavigationArgs args = new(reference);
138 await ServiceRef.NavigationService.GoToAsync(nameof(KycProcessPage), args);
139 return NotificationRouteResult.Success;
140 }
141
142 LegalIdentity identity = await ServiceRef.XmppService.GetLegalIdentity(Intent.EntityId);
143 ViewIdentityNavigationArgs viewArgs = new(identity);
144 await ServiceRef.NavigationService.GoToAsync(nameof(ViewIdentityPage), viewArgs);
145 return NotificationRouteResult.Success;
146 }
147 catch (Exception ex)
148 {
149 ServiceRef.LogService.LogException(ex);
150 return NotificationRouteResult.Failed;
151 }
152 }
153
154 private async Task<NotificationRouteResult> RouteContractAsync(NotificationIntent Intent, CancellationToken CancellationToken)
155 {
156 if (string.IsNullOrEmpty(Intent.EntityId))
157 {
158 await ServiceRef.NavigationService.GoToAsync(nameof(MyContractsPage));
159 return NotificationRouteResult.Success;
160 }
161
162 try
163 {
164 Contract contract = await ServiceRef.XmppService.GetContract(Intent.EntityId);
165 ViewContractNavigationArgs args = new(contract, false);
166 await ServiceRef.NavigationService.GoToAsync(nameof(ViewContractPage), args);
167 return NotificationRouteResult.Success;
168 }
169 catch (Exception ex)
170 {
171 ServiceRef.LogService.LogException(ex);
172 await ServiceRef.NavigationService.GoToAsync(nameof(MyContractsPage));
173 return NotificationRouteResult.Success;
174 }
175 }
176
177 private async Task<NotificationRouteResult> RouteTokenAsync(CancellationToken CancellationToken)
178 {
179 await ServiceRef.NavigationService.GoToAsync(nameof(MyTokensPage));
180 return NotificationRouteResult.Success;
181 }
182
183 private async Task<NotificationRouteResult> RouteBalanceAsync(CancellationToken CancellationToken)
184 {
185 MainNavigationArgs args = new()
186 {
187 TargetTabKey = "wallet"
188 };
189
190 await ServiceRef.NavigationService.GoToAsync(nameof(MainPage), args);
191 return NotificationRouteResult.Success;
192 }
193
194 private async Task<NotificationRouteResult> RoutePetitionAsync(NotificationIntent Intent, CancellationToken CancellationToken)
195 {
196 try
197 {
198 if (Intent.Extras.TryGetValue("requestedIdentityId", out string? RequestedIdentityId))
199 {
200 LegalIdentity? RequestorIdentity = null;
201 if (!string.IsNullOrEmpty(Intent.EntityId))
202 {
203 ContactInfo? Info = await ContactInfo.FindByBareJid(Intent.EntityId);
204 RequestorIdentity = Info?.LegalIdentity;
205 }
206
207 (bool Succeeded, LegalIdentity? RequestedIdentity) = await ServiceRef.NetworkService.TryRequest(() => ServiceRef.XmppService.GetLegalIdentity(RequestedIdentityId));
208 if (!Succeeded || RequestedIdentity is null)
209 {
210 string Title = ServiceRef.Localizer[nameof(AppResources.ErrorTitle)];
211 string Message = "Petition has expired or is no longer available.";
212 await ServiceRef.UiService.DisplayAlert(Title, Message);
213 return NotificationRouteResult.Failed;
214 }
215 else
216 {
217 RequestorIdentity = RequestedIdentity;
218 }
219
220 string? PetitionId = Intent.Extras.TryGetValue("petitionId", out string? pid) ? pid : null;
221 PetitionIdentityNavigationArgs Args = new(RequestorIdentity, Intent.EntityId, RequestedIdentityId, PetitionId, Intent.Body);
222 await ServiceRef.NavigationService.GoToAsync(nameof(PetitionIdentityPage), Args);
223 return NotificationRouteResult.Success;
224 }
225
226 if (Intent.Extras.TryGetValue("signatoryId", out string? SignatoryIdentityId) &&
227 Intent.Extras.TryGetValue("contentToSign", out string? ContentToSignBase64) &&
228 !string.IsNullOrEmpty(SignatoryIdentityId) &&
229 !string.IsNullOrEmpty(ContentToSignBase64))
230 {
231 LegalIdentity? RequestorIdentity = null;
232 string? RequestorFullJid = Intent.EntityId;
233 if (Intent.Extras.TryGetValue("requestorIdentityId", out string? RequestorIdentityId) &&
234 !string.IsNullOrEmpty(RequestorIdentityId))
235 {
236 (bool Succeeded, LegalIdentity? LegalId) = await ServiceRef.NetworkService.TryRequest(() => ServiceRef.XmppService.GetLegalIdentity(RequestorIdentityId));
237 if (Succeeded && LegalId is not null)
238 RequestorIdentity = LegalId;
239 }
240
241 if (RequestorIdentity is null && !string.IsNullOrEmpty(RequestorFullJid))
242 {
243 ContactInfo? Info = await ContactInfo.FindByBareJid(RequestorFullJid);
244 RequestorIdentity = Info?.LegalIdentity;
245 }
246
247 if (RequestorIdentity is null || string.IsNullOrEmpty(RequestorFullJid))
248 {
249 string Title = ServiceRef.Localizer[nameof(AppResources.ErrorTitle)];
250 string Message = "Petition has expired or is no longer available.";
251 await ServiceRef.UiService.DisplayAlert(Title, Message);
252 return NotificationRouteResult.Failed;
253 }
254
255 byte[] ContentToSign;
256 try
257 {
258 ContentToSign = Convert.FromBase64String(ContentToSignBase64);
259 }
260 catch (FormatException ex)
261 {
262 ServiceRef.LogService.LogException(ex);
263 string Title = ServiceRef.Localizer[nameof(AppResources.ErrorTitle)];
264 string Message = "Petition has expired or is no longer available.";
265 await ServiceRef.UiService.DisplayAlert(Title, Message);
266 return NotificationRouteResult.Failed;
267 }
268
269 string Purpose = Intent.Extras.TryGetValue("purpose", out string? PurposeValue)
270 ? PurposeValue ?? string.Empty
271 : string.Empty;
272 string PetitionId = Intent.Extras.TryGetValue("petitionId", out string? Pid)
273 ? Pid ?? string.Empty
274 : string.Empty;
275
276 PetitionSignatureNavigationArgs Args = new(RequestorIdentity, RequestorFullJid, SignatoryIdentityId,
277 ContentToSign, PetitionId, Purpose);
278 await ServiceRef.NavigationService.GoToAsync(nameof(PetitionSignaturePage), Args);
279 return NotificationRouteResult.Success;
280 }
281
282 if (Intent.Extras.TryGetValue("contractId", out string? contractId))
283 {
284 Contract? Contract = null;
285 try
286 {
287 Contract = await ServiceRef.XmppService.GetContract(contractId);
288 }
289 catch (Exception Ex)
290 {
291 ServiceRef.LogService.LogException(Ex);
292 }
293
294 string? PetitionId = Intent.Extras.TryGetValue("petitionId", out string? Pid) ? Pid : null;
295 PetitionContractNavigationArgs Args = new(null, Intent.EntityId, Contract, PetitionId, Intent.Body);
296 await ServiceRef.NavigationService.GoToAsync(nameof(PetitionContractPage), Args);
297 return NotificationRouteResult.Success;
298 }
299
300 await ServiceRef.NavigationService.GoToAsync(nameof(MyContactsPage));
301 return NotificationRouteResult.Success;
302 }
303 catch (Exception Ex)
304 {
305 ServiceRef.LogService.LogException(Ex);
306 return NotificationRouteResult.Failed;
307 }
308 }
309
310 private async Task<NotificationRouteResult> RouteSettingsAsync(CancellationToken CancellationToken)
311 {
312 await ServiceRef.NavigationService.GoToAsync(nameof(SettingsPage));
313 return NotificationRouteResult.Success;
314 }
315 }
316}
A strongly-typed resource class, for looking up localized strings, etc.
static string ErrorTitle
Looks up a localized string similar to An error has occurred.
Contains information about a contact.
Definition: ContactInfo.cs:22
LegalIdentity? LegalIdentity
Legal Identity object.
Definition: ContactInfo.cs:82
static Task< ContactInfo > FindByBareJid(string BareJid)
Finds information about a contact, given its Bare JID.
Definition: ContactInfo.cs:221
CaseInsensitiveString LegalId
Legal ID of contact.
Definition: ContactInfo.cs:72
Contains a local reference to a KYC process.
Definition: KycReference.cs:22
IdentityState? CreatedIdentityState
Last known state of the created identity (if any), for quick status tagging offline.
Definition: KycReference.cs:81
string? CreatedIdentityId
The legal ID of the created identity (if any).
Definition: KycReference.cs:75
Represents a filter decision for notification handling.
bool IgnoreRoute
Gets a value indicating whether routing should be suppressed.
Platform-neutral intent describing how to route a notification.
string? EntityId
Gets or sets an entity identifier associated with the action.
NotificationAction Action
Gets or sets the intended action.
Default router for notification intents. Wiring to navigation can be extended here.
Task< NotificationRouteResult > RouteAsync(NotificationIntent Intent, bool FromUserInteraction, CancellationToken CancellationToken)
Routes a notification intent. Routing result.
NotificationIntentRouter(INotificationFilterRegistry FilterRegistry)
Initializes a new instance of the NotificationIntentRouter class.
Base class that references services in the app.
Definition: ServiceRef.cs:43
static ILogService LogService
Log service.
Definition: ServiceRef.cs:214
static INetworkService NetworkService
Network service.
Definition: ServiceRef.cs:226
static IUiService UiService
Service serializing and managing UI-related tasks.
Definition: ServiceRef.cs:130
static INavigationService NavigationService
The navigation service for navigating between pages.
Definition: ServiceRef.cs:178
static IReportingStringLocalizer Localizer
Localization service
Definition: ServiceRef.cs:370
static IXmppService XmppService
The XMPP service for XMPP communication.
Definition: ServiceRef.cs:190
Holds navigation parameters specific to views displaying a list of contacts.
A page that displays a list of the current user's contacts.
A page that displays a list of the current user's contacts.
A page that displays a list of the current user's contracts.
A page to display when the user wants to view an identity.
Navigation arguments for the KYC process page. Carries the KycReference to edit/continue.
Navigation arguments for the MainPage, allowing callers to target a specific tab.
Holds navigation parameters specific to views displaying a contract petition request.
A page to display when the user is asked to petition a contract.
A page to display when the user is asked to petition an identity.
Holds navigation parameters specific to views displaying a petition of a signature.
A page to display when the user is asked to petition a signature.
A page that allows the user to view its tokens.
Contains the definition of a contract
Definition: Contract.cs:22
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:21
This filter selects objects that have a named field equal to a given value.
NotificationRouteResult
Possible outcomes when routing a notification intent.
NotificationAction
Actions that can be routed from notifications.
IdentityState
Lists recognized legal identity states.