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;
9using System.Collections.ObjectModel;
10using System.ComponentModel;
11using System.Text.RegularExpressions;
18
20{
25 {
31 : base()
32 {
33 this.Uri = Args?.Uri;
34 this.Tags = [];
35
36 if (this.Uri is not null)
37 {
38 if (ServiceRef.XmppService.TryDecodeIoTDiscoClaimURI(this.Uri, out MetaDataTag[]? Tags))
39 {
40 this.RegistryJid = null;
41
42 foreach (MetaDataTag Tag in Tags)
43 {
44 this.Tags.Add(new HumanReadableTag(Tag));
45
46 if (string.Equals(Tag.Name, "R", StringComparison.OrdinalIgnoreCase))
47 this.RegistryJid = Tag.StringValue;
48 }
49
50 if (string.IsNullOrEmpty(this.RegistryJid))
51 this.RegistryJid = ServiceRef.XmppService.RegistryServiceJid;
52 }
53 }
54 }
55
57 protected override Task XmppService_ConnectionStateChanged(object? Sender, XmppState NewState)
58 {
59 MainThread.BeginInvokeOnMainThread(() =>
60 {
61 this.SetConnectionStateAndText(NewState);
62 this.ClaimThingCommand.NotifyCanExecuteChanged();
63 });
64
65 return Task.CompletedTask;
66 }
67
68 #region Properties
69
73 [ObservableProperty]
74 private string? uri;
75
79 public ObservableCollection<HumanReadableTag> Tags { get; }
80
84 [ObservableProperty]
85 private bool makePublic;
86
90 [ObservableProperty]
91 private string? registryJid;
92
93 #endregion
94
98 [RelayCommand]
99 private static Task Click(object obj)
100 {
101 if (obj is HumanReadableTag Tag)
102 return LabelClicked(Tag.Name, Tag.Value, Tag.LocalizedValue);
103 else if (obj is string s)
104 return LabelClicked(string.Empty, s, s);
105 else
106 return Task.CompletedTask;
107 }
108
115 public static async Task LabelClicked(string Name, string Value, string LocalizedValue)
116 {
117 try
118 {
119 switch (Name)
120 {
121 case "MAN":
122 if (System.Uri.TryCreate("https://" + Value, UriKind.Absolute, out Uri? Uri) && await Launcher.TryOpenAsync(Uri))
123 return;
124 break;
125
126 case "PURL":
127 if (System.Uri.TryCreate(Value, UriKind.Absolute, out Uri) && await Launcher.TryOpenAsync(Uri))
128 return;
129 break;
130
131 case "R":
132 SRV SRV;
133
134 try
135 {
136 SRV = await DnsResolver.LookupServiceEndpoint(Value, "xmpp-server", "tcp");
137 }
138 catch
139 {
140 break;
141 }
142
143 if (System.Uri.TryCreate("https://" + SRV.TargetHost, UriKind.Absolute, out Uri) && await Launcher.TryOpenAsync(Uri))
144 return;
145 break;
146
147 default:
148 if ((Value.StartsWith("http://", StringComparison.CurrentCultureIgnoreCase) ||
149 Value.StartsWith("https://", StringComparison.CurrentCultureIgnoreCase)) &&
150 System.Uri.TryCreate(Value, UriKind.Absolute, out Uri) &&
151 await Launcher.TryOpenAsync(Uri))
152 {
153 return;
154 }
155 else
156 {
157 Match M = XmppClient.BareJidRegEx.Match(Value);
158
159 if (M.Success && M.Index == 0 && M.Length == Value.Length)
160 {
161 ContactInfo Info = await ContactInfo.FindByBareJid(Value);
162 if (Info is not null)
163 {
164 await ServiceRef.UiService.GoToAsync(nameof(ChatPage), new ChatNavigationArgs(Info));
165 return;
166 }
167
168 int i = Value.IndexOf('@');
169 if (i > 0 && Guid.TryParse(Value[..i], out _))
170 {
171 if (ServiceRef.UiService.CurrentPage is not ViewIdentityPage)
172 {
173 Info = await ContactInfo.FindByLegalId(Value);
174 if (Info?.LegalIdentity is not null)
175 {
176 await ServiceRef.UiService.GoToAsync(nameof(ViewIdentityPage),
177 new ViewIdentityNavigationArgs(Info.LegalIdentity));
178 return;
179 }
180 }
181 }
182 else
183 {
184 string FriendlyName = await ContactInfo.GetFriendlyName(Value);
185 await ServiceRef.UiService.GoToAsync(nameof(ChatPage), new ChatNavigationArgs(string.Empty, Value, FriendlyName));
186 return;
187 }
188 }
189 }
190 break;
191 }
192
193 await Clipboard.SetTextAsync(LocalizedValue);
194 await ServiceRef.UiService.DisplayAlert(ServiceRef.Localizer[nameof(AppResources.SuccessTitle)],
195 ServiceRef.Localizer[nameof(AppResources.TagValueCopiedToClipboard)]);
196 }
197 catch (Exception ex)
198 {
199 ServiceRef.LogService.LogException(ex);
200 await ServiceRef.UiService.DisplayException(ex);
201 }
202 }
203
207 public static string? GetFriendlyName(IEnumerable<HumanReadableTag> Tags)
208 {
210 }
211
215 public static string? GetFriendlyName(IEnumerable<MetaDataTag> Tags)
216 {
218 }
219
223 public static string? GetFriendlyName(IEnumerable<Property> Tags)
224 {
226 }
227
231 public bool CanClaimThing
232 {
233 get { return this.IsConnected && ServiceRef.XmppService.IsOnline; }
234 }
235
237 protected override void OnPropertyChanged(PropertyChangedEventArgs e)
238 {
239 base.OnPropertyChanged(e);
240
241 switch (e.PropertyName)
242 {
243 case nameof(this.IsConnected):
244 this.ClaimThingCommand.NotifyCanExecuteChanged();
245 break;
246 }
247 }
248
252 [RelayCommand(CanExecute = nameof(CanClaimThing))]
253 private async Task ClaimThing()
254 {
255 try
256 {
257 if (string.IsNullOrEmpty(this.Uri))
258 return;
259
260 if (!await App.AuthenticateUser(AuthenticationPurpose.ClaimThing, true))
261 return;
262
263 (bool Succeeded, NodeResultEventArgs? e) = await ServiceRef.NetworkService.TryRequest(() =>
264 ServiceRef.XmppService.ClaimThing(this.Uri, this.MakePublic));
265
266 if (!Succeeded || e is null)
267 return;
268
269 if (e.Ok)
270 {
271 string? FriendlyName = GetFriendlyName(this.Tags);
272 RosterItem? Item = ServiceRef.XmppService.GetRosterItem(e.JID);
273 if (Item is null)
274 ServiceRef.XmppService.AddRosterItem(new RosterItem(e.JID, FriendlyName));
275
276 //Remove Key Tag from the list of tags
277 foreach (HumanReadableTag Tag in this.Tags)
278 {
279 if (string.Equals(Tag.Name, Constants.XmppProperties.Key, StringComparison.OrdinalIgnoreCase))
280 {
281 this.Tags.Remove(Tag);
282 break;
283 }
284 }
285 ContactInfo Info = await ContactInfo.FindByBareJid(e.JID, e.Node.SourceId, e.Node.Partition, e.Node.NodeId);
286 if (Info is null)
287 {
288 Info = new ContactInfo()
289 {
290 BareJid = e.JID,
291 LegalId = string.Empty,
292 LegalIdentity = null,
293 FriendlyName = FriendlyName ?? string.Empty,
294 IsThing = true,
295 Owner = true,
296 SourceId = e.Node.SourceId,
297 Partition = e.Node.Partition,
298 NodeId = e.Node.NodeId,
299 MetaData = ToProperties(this.Tags),
300 RegistryJid = this.RegistryJid
301 };
302
303 await Database.Insert(Info);
304 }
305 else
306 {
307 Info.FriendlyName = FriendlyName ?? string.Empty;
308
309 await Database.Update(Info);
310 }
311
312 await Database.Provider.Flush();
313
314 await ServiceRef.UiService.GoToAsync(nameof(ViewThingPage), new ViewThingNavigationArgs(Info, []), Services.UI.BackMethod.Pop2);
315 }
316 else
317 {
318 string Msg = e.ErrorText;
319 if (string.IsNullOrEmpty(Msg))
320 Msg = ServiceRef.Localizer[nameof(AppResources.UnableToClaimThing)];
321
322 await ServiceRef.UiService.DisplayAlert(ServiceRef.Localizer[nameof(AppResources.ErrorTitle)], Msg);
323 }
324 }
325 catch (Exception ex)
326 {
327 ServiceRef.LogService.LogException(ex);
328 await ServiceRef.UiService.DisplayException(ex);
329 }
330 }
331
337 public static Property[] ToProperties(IEnumerable<HumanReadableTag> Tags)
338 {
339 List<Property> Result = [];
340
341 foreach (HumanReadableTag Tag in Tags)
342 Result.Add(new Property(Tag.Name, Tag.Value));
343
344 return [.. Result];
345 }
346
352 public static Property[] ToProperties(IEnumerable<MetaDataTag> Tags)
353 {
354 List<Property> Result = [];
355
356 foreach (MetaDataTag Tag in Tags)
357 Result.Add(new Property(Tag.Name, Tag.StringValue));
358
359 return [.. Result];
360 }
361
362 }
363}
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
A set of never changing property constants and helpful values.
Definition: Constants.cs:7
Contains information about a contact.
Definition: ContactInfo.cs:21
static async Task< string > GetFriendlyName(CaseInsensitiveString RemoteId)
Gets the friendly name of a remote identity (Legal ID or Bare JID).
Definition: ContactInfo.cs:257
LegalIdentity? LegalIdentity
Legal Identity object.
Definition: ContactInfo.cs:81
static Task< ContactInfo > FindByLegalId(string LegalId)
Finds information about a contact, given its Legal ID.
Definition: ContactInfo.cs:247
static Task< ContactInfo > FindByBareJid(string BareJid)
Finds information about a contact, given its Bare JID.
Definition: ContactInfo.cs:220
Base class that references services in the app.
Definition: ServiceRef.cs:31
static ILogService LogService
Log service.
Definition: ServiceRef.cs:91
static INetworkService NetworkService
Network service.
Definition: ServiceRef.cs:103
static IUiService UiService
Service serializing and managing UI-related tasks.
Definition: ServiceRef.cs:55
static IStringLocalizer Localizer
Localization service
Definition: ServiceRef.cs:235
static IXmppService XmppService
The XMPP service for XMPP communication.
Definition: ServiceRef.cs:67
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...
Definition: DnsResolver.cs:825
Abstract base class for all meta-data tags.
Definition: MetaDataTag.cs:9
abstract string StringValue
String-representation of meta-data tag value.
Definition: MetaDataTag.cs:30
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:59
static readonly Regex BareJidRegEx
Regular expression for Bare JIDs
Definition: XmppClient.cs:188
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:19
static IDatabaseProvider Provider
Registered database provider.
Definition: Database.cs:57
static async Task Update(object Object)
Updates an object in the database.
Definition: Database.cs:626
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
Definition: Database.cs:95
Task Flush()
Persists any pending changes.
AuthenticationPurpose
Purpose for requesting the user to authenticate itself.
XmppState
State of XMPP connection.
Definition: XmppState.cs:7