Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ViewClaimThingViewModel.cs
1using CommunityToolkit.Mvvm.ComponentModel;
2using CommunityToolkit.Mvvm.Input;
10using System.Collections.ObjectModel;
11using System.ComponentModel;
12using System.Text.RegularExpressions;
20
22{
27 {
28 private readonly IAuthenticationService authenticationService = ServiceRef.Provider.GetRequiredService<IAuthenticationService>();
29
35 : base()
36 {
37 this.Uri = Args?.Uri;
38 this.Tags = [];
39
40 if (this.Uri is not null)
41 {
42 if (ServiceRef.XmppService.TryDecodeIoTDiscoClaimURI(this.Uri, out MetaDataTag[]? Tags))
43 {
44 this.RegistryJid = null;
45
46 foreach (MetaDataTag Tag in Tags)
47 {
48 this.Tags.Add(new HumanReadableTag(Tag));
49
50 if (string.Equals(Tag.Name, "R", StringComparison.OrdinalIgnoreCase))
51 this.RegistryJid = Tag.StringValue;
52 }
53
54 if (string.IsNullOrEmpty(this.RegistryJid))
55 this.RegistryJid = ServiceRef.XmppService.RegistryServiceJid;
56 }
57 }
58 }
59
61 protected override Task XmppService_ConnectionStateChanged(object? Sender, XmppState NewState)
62 {
63 MainThread.BeginInvokeOnMainThread(() =>
64 {
65 this.SetConnectionStateAndText(NewState);
66 this.ClaimThingCommand.NotifyCanExecuteChanged();
67 });
68
69 return Task.CompletedTask;
70 }
71
72 #region Properties
73
77 [ObservableProperty]
78 private string? uri;
79
83 public ObservableCollection<HumanReadableTag> Tags { get; }
84
88 [ObservableProperty]
89 private bool makePublic;
90
94 [ObservableProperty]
95 private string? registryJid;
96
97 #endregion
98
102 [RelayCommand]
103 private static Task Click(object obj)
104 {
105 if (obj is HumanReadableTag Tag)
106 return LabelClicked(Tag.Name, Tag.Value, Tag.LocalizedValue);
107 else if (obj is string s)
108 return LabelClicked(string.Empty, s, s);
109 else
110 return Task.CompletedTask;
111 }
112
119 public static async Task LabelClicked(string Name, string Value, string LocalizedValue)
120 {
121 try
122 {
123 switch (Name)
124 {
125 case "MAN":
126 if (System.Uri.TryCreate("https://" + Value, UriKind.Absolute, out Uri? Uri) && await Launcher.TryOpenAsync(Uri))
127 return;
128 break;
129
130 case "PURL":
131 if (System.Uri.TryCreate(Value, UriKind.Absolute, out Uri) && await Launcher.TryOpenAsync(Uri))
132 return;
133 break;
134
135 case "R":
136 SRV SRV;
137
138 try
139 {
140 SRV = await DnsResolver.LookupServiceEndpoint(Value, "xmpp-server", "tcp");
141 }
142 catch
143 {
144 break;
145 }
146
147 if (System.Uri.TryCreate("https://" + SRV.TargetHost, UriKind.Absolute, out Uri) && await Launcher.TryOpenAsync(Uri))
148 return;
149 break;
150
151 default:
152 if ((Value.StartsWith("http://", StringComparison.CurrentCultureIgnoreCase) ||
153 Value.StartsWith("https://", StringComparison.CurrentCultureIgnoreCase)) &&
154 System.Uri.TryCreate(Value, UriKind.Absolute, out Uri) &&
155 await Launcher.TryOpenAsync(Uri))
156 {
157 return;
158 }
159 else
160 {
161 Match M = XmppClient.BareJidRegEx.Match(Value);
162
163 if (M.Success && M.Index == 0 && M.Length == Value.Length)
164 {
165 ContactInfo Info = await ContactInfo.FindByBareJid(Value);
166 if (Info is not null)
167 {
168 await ServiceRef.NavigationService.GoToAsync(nameof(ChatPage), new ChatNavigationArgs(Info));
169 return;
170 }
171
172 int i = Value.IndexOf('@');
173 if (i > 0 && Guid.TryParse(Value[..i], out _))
174 {
175 if (ServiceRef.NavigationService.CurrentPage is not ViewIdentityPage)
176 {
177 Info = await ContactInfo.FindByLegalId(Value);
178 if (Info?.LegalIdentity is not null)
179 {
180 await ServiceRef.NavigationService.GoToAsync(nameof(ViewIdentityPage),
181 new ViewIdentityNavigationArgs(Info.LegalIdentity));
182 return;
183 }
184 }
185 }
186 else
187 {
188 string FriendlyName = await ContactInfo.GetFriendlyName(Value);
189 await ServiceRef.NavigationService.GoToAsync(nameof(ChatPage), new ChatNavigationArgs(string.Empty, Value, FriendlyName));
190 return;
191 }
192 }
193 }
194 break;
195 }
196
197 await Clipboard.SetTextAsync(LocalizedValue);
200 }
201 catch (Exception ex)
202 {
203 ServiceRef.LogService.LogException(ex);
204 await ServiceRef.UiService.DisplayException(ex);
205 }
206 }
207
211 public static string? GetFriendlyName(IEnumerable<HumanReadableTag> Tags)
212 {
214 }
215
219 public static string? GetFriendlyName(IEnumerable<MetaDataTag> Tags)
220 {
222 }
223
227 public static string? GetFriendlyName(IEnumerable<Property> Tags)
228 {
230 }
231
235 public bool CanClaimThing
236 {
237 get { return this.IsConnected && ServiceRef.XmppService.IsOnline; }
238 }
239
241 protected override void OnPropertyChanged(PropertyChangedEventArgs e)
242 {
243 base.OnPropertyChanged(e);
244
245 switch (e.PropertyName)
246 {
247 case nameof(this.IsConnected):
248 this.ClaimThingCommand.NotifyCanExecuteChanged();
249 break;
250 }
251 }
252
256 [RelayCommand(CanExecute = nameof(CanClaimThing))]
257 private async Task ClaimThing()
258 {
259 try
260 {
261 if (string.IsNullOrEmpty(this.Uri))
262 return;
263
264 if (!await this.authenticationService.AuthenticateUserAsync(AuthenticationPurpose.ClaimThing, true))
265 return;
266
267 (bool Succeeded, NodeResultEventArgs? e) = await ServiceRef.NetworkService.TryRequest(() =>
268 ServiceRef.XmppService.ClaimThing(this.Uri, this.MakePublic));
269
270 if (!Succeeded || e is null)
271 return;
272
273 if (e.Ok)
274 {
275 string? FriendlyName = GetFriendlyName(this.Tags);
276 RosterItem? Item = ServiceRef.XmppService.GetRosterItem(e.JID);
277 if (Item is null)
278 ServiceRef.XmppService.AddRosterItem(new RosterItem(e.JID, FriendlyName));
279
280 //Remove Key Tag from the list of tags
281 foreach (HumanReadableTag Tag in this.Tags)
282 {
283 if (string.Equals(Tag.Name, Constants.XmppProperties.Key, StringComparison.OrdinalIgnoreCase))
284 {
285 this.Tags.Remove(Tag);
286 break;
287 }
288 }
289
290 ContactInfo Info = await ContactInfo.FindByBareJid(e.JID, e.Node.SourceId, e.Node.Partition, e.Node.NodeId);
291 if (Info is null)
292 {
293 Info = new ContactInfo()
294 {
295 BareJid = e.JID,
296 LegalId = string.Empty,
297 LegalIdentity = null,
298 FriendlyName = FriendlyName ?? string.Empty,
299 IsThing = true,
300 Owner = true,
301 SourceId = e.Node.SourceId,
302 Partition = e.Node.Partition,
303 NodeId = e.Node.NodeId,
304 MetaData = ToProperties(this.Tags),
305 RegistryJid = this.RegistryJid
306 };
307
308 await Database.Insert(Info);
309 }
310 else
311 {
312 Info.FriendlyName = FriendlyName ?? string.Empty;
313
314 await Database.Update(Info);
315 }
316
317 await Database.Provider.Flush();
318
319 ServiceRef.XmppService.RequestPresenceSubscription(Info.BareJid);
320
321 await ServiceRef.NavigationService.GoToAsync(nameof(ViewThingPage), new ViewThingNavigationArgs(Info, []), Services.UI.BackMethod.Pop2);
322 }
323 else
324 {
325 string Msg = e.ErrorText;
326 if (string.IsNullOrEmpty(Msg))
328
329 await ServiceRef.UiService.DisplayAlert(ServiceRef.Localizer[nameof(AppResources.ErrorTitle)], Msg);
330 }
331 }
332 catch (Exception ex)
333 {
334 ServiceRef.LogService.LogException(ex);
335 await ServiceRef.UiService.DisplayException(ex);
336 }
337 }
338
344 public static Property[] ToProperties(IEnumerable<HumanReadableTag> Tags)
345 {
346 List<Property> Result = [];
347
348 foreach (HumanReadableTag Tag in Tags)
349 Result.Add(new Property(Tag.Name, Tag.Value));
350
351 return [.. Result];
352 }
353
359 public static Property[] ToProperties(IEnumerable<MetaDataTag> Tags)
360 {
361 List<Property> Result = [];
362
363 foreach (MetaDataTag Tag in Tags)
364 Result.Add(new Property(Tag.Name, Tag.StringValue));
365
366 return [.. Result];
367 }
368
369 }
370}
A set of never changing property constants and helpful values.
Definition: Constants.cs:24
A strongly-typed resource class, for looking up localized strings, etc.
static string TagValueCopiedToClipboard
Looks up a localized string similar to Tag value copied to clipboard.
static string SuccessTitle
Looks up a localized string similar to Success.
static string UnableToClaimThing
Looks up a localized string similar to Unable to claim thing.
static string ErrorTitle
Looks up a localized string similar to An error has occurred.
Contains information about a contact.
Definition: ContactInfo.cs:22
static async Task< string > GetFriendlyName(CaseInsensitiveString RemoteId)
Gets the friendly name of a remote identity (Legal ID or Bare JID).
Definition: ContactInfo.cs:258
static async Task< ContactInfo?> FindByLegalId(string LegalId)
Finds information about a contact, given its Legal ID.
Definition: ContactInfo.cs:248
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 BareJid
Bare JID of contact.
Definition: ContactInfo.cs:63
Base class that references services in the app.
Definition: ServiceRef.cs:43
static IServiceProvider Provider
The service provider for the app. This is set before the app is started, and will be used to resolve ...
Definition: ServiceRef.cs:48
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 to display when the user wants to view an identity.
Class used to present a meta-data tag in a human interface.
The view model to bind to for when displaying thing claim information.
ViewClaimThingViewModel(ViewClaimThingNavigationArgs? Args)
Creates an instance of the ViewClaimThingViewModel class.
bool CanClaimThing
Gets or sets whether a user can claim a thing.
static ? string GetFriendlyName(IEnumerable< Property > Tags)
Get Friendly name of thing
static ? string GetFriendlyName(IEnumerable< HumanReadableTag > Tags)
Get Friendly name of thing
override Task XmppService_ConnectionStateChanged(object? Sender, XmppState NewState)
Listens to connection state changes from the XMPP server.
static Property[] ToProperties(IEnumerable< HumanReadableTag > Tags)
Converts an enumerable set of HumanReadableTag to an enumerable set of Property.
static async Task LabelClicked(string Name, string Value, string LocalizedValue)
Processes the click of a localized meta-data label.
static ? string GetFriendlyName(IEnumerable< MetaDataTag > Tags)
Get Friendly name of thing
ObservableCollection< HumanReadableTag > Tags
Holds a list of meta-data tags associated with a thing.
static Property[] ToProperties(IEnumerable< MetaDataTag > Tags)
Converts an enumerable set of MetaDataTag to an enumerable set of Property.
Holds navigation parameters specific to viewing things.
A page that displays information about a thing and allows the user to interact with it.
A view model that holds the XMPP state.
virtual void SetConnectionStateAndText(XmppState State)
Sets both the connection state and connection text to the appropriate value.
DNS resolver, as defined in:
Definition: DnsResolver.cs:32
static Task< SRV > LookupServiceEndpoint(string DomainName, string ServiceName, string Protocol)
Looks up a service endpoint for a domain. If multiple are available, an appropriate one is selected a...
Abstract base class for all meta-data tags.
Definition: MetaDataTag.cs:10
abstract string StringValue
String-representation of meta-data tag value.
Definition: MetaDataTag.cs:31
Maintains information about an item in the roster.
Definition: RosterItem.cs:75
Manages an XMPP client connection. Implements XMPP, as defined in https://tools.ietf....
Definition: XmppClient.cs:58
static readonly Regex BareJidRegEx
Regular expression for Bare JIDs
Definition: XmppClient.cs:187
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:21
static IDatabaseProvider Provider
Registered database provider.
Definition: Database.cs:59
static async Task Update(object Object)
Updates an object in the database.
Definition: Database.cs:1211
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
Definition: Database.cs:97
Task Flush()
Persists any pending changes.
Definition: ImplTypes.g.cs:58
AuthenticationPurpose
Purpose for requesting the user to authenticate itself.
XmppState
State of XMPP connection.
Definition: XmppState.cs:7