Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ViewIdentityViewModel.cs
1using CommunityToolkit.Mvvm.ComponentModel;
2using CommunityToolkit.Mvvm.Input;
8using System.Collections.ObjectModel;
9using System.ComponentModel;
13
15{
20 {
21 private readonly PhotosLoader photosLoader;
22 private LegalIdentity? requestorIdentity;
23 private string? requestorFullJid;
24 private string? signatoryIdentityId;
25 private string? petitionId;
26 private byte[]? contentToSign;
27
32 public ViewIdentityViewModel(ViewIdentityNavigationArgs? Args)
33 : base()
34 {
35 this.photosLoader = new PhotosLoader(this.Photos);
36
37 if (Args is not null)
38 {
39 this.LegalIdentity = Args.Identity ?? ServiceRef.TagProfile.LegalIdentity;
40 this.requestorIdentity = Args.RequestorIdentity;
41 this.requestorFullJid = Args.RequestorFullJid;
42 this.signatoryIdentityId = Args.SignatoryIdentityId;
43 this.petitionId = Args.PetitionId;
44 this.Purpose = Args.Purpose;
45 this.contentToSign = Args.ContentToSign;
46 }
47 }
48
50 protected override async Task OnInitialize()
51 {
52 await base.OnInitialize();
53
54 if (this.LegalIdentity is null)
55 {
56 this.LegalIdentity = ServiceRef.TagProfile.LegalIdentity;
57 this.requestorIdentity = null;
58 this.requestorFullJid = null;
59 this.signatoryIdentityId = null;
60 this.petitionId = null;
61 this.Purpose = null;
62 this.contentToSign = null;
63 this.IsPersonal = true;
64 }
65 else
66 this.IsPersonal = false;
67
68 this.AssignProperties();
69
70 if (this.ThirdParty)
71 {
72 ContactInfo? Info = this.BareJid is null ? null : await ContactInfo.FindByBareJid(this.BareJid);
73
74 if ((Info is not null) &&
75 (Info.LegalIdentity is null ||
76 (Info.LegalId != this.LegalId &&
77 Info.LegalIdentity.Created < this.LegalIdentity!.Created &&
78 this.LegalIdentity.State == IdentityState.Approved)))
79 {
80 Info.LegalId = this.LegalId;
81 Info.LegalIdentity = this.LegalIdentity;
82 Info.FriendlyName = ContactInfo.GetFriendlyName(this.LegalIdentity);
83
84 await Database.Update(Info);
85 await Database.Provider.Flush();
86 }
87
88 this.CanAddContact = Info is null;
89 this.CanRemoveContact = Info is not null;
90
91 this.NotifyCommandsCanExecuteChanged();
92 }
93
94 ServiceRef.TagProfile.Changed += this.TagProfile_Changed;
95 ServiceRef.XmppService.LegalIdentityChanged += this.SmartContracts_LegalIdentityChanged;
96 }
97
99 protected override async Task OnDispose()
100 {
101 this.photosLoader.CancelLoadPhotos();
102
103 ServiceRef.TagProfile.Changed -= this.TagProfile_Changed;
104 ServiceRef.XmppService.LegalIdentityChanged -= this.SmartContracts_LegalIdentityChanged;
105
106 this.LegalIdentity = null;
107
108 await base.OnDispose();
109 }
110
111 private void AssignProperties()
112 {
113 this.Created = this.LegalIdentity?.Created ?? DateTime.MinValue;
114 this.Updated = this.LegalIdentity?.Updated.GetDateOrNullIfMinValue();
115 this.Expires = this.LegalIdentity?.To.GetDateOrNullIfMinValue();
116 this.LegalId = this.LegalIdentity?.Id;
117 this.NetworkId = this.LegalIdentity?.GetJid();
118
119 if (this.requestorIdentity is not null)
120 this.BareJid = this.requestorIdentity.GetJid(Constants.NotAvailableValue);
121 else if (this.LegalIdentity is not null)
122 this.BareJid = this.LegalIdentity.GetJid(Constants.NotAvailableValue);
123 else
124 this.BareJid = Constants.NotAvailableValue;
125
126 if (this.LegalIdentity?.ClientPubKey is not null)
127 this.PublicKey = Convert.ToBase64String(this.LegalIdentity.ClientPubKey);
128 else
129 this.PublicKey = string.Empty;
130
131 this.State = this.LegalIdentity?.State ?? IdentityState.Rejected;
132 this.From = this.LegalIdentity?.From.GetDateOrNullIfMinValue();
133 this.To = this.LegalIdentity?.To.GetDateOrNullIfMinValue();
134
135 if (this.LegalIdentity is not null)
136 {
137 this.FirstName = this.LegalIdentity[Constants.XmppProperties.FirstName];
138 this.MiddleNames = this.LegalIdentity[Constants.XmppProperties.MiddleNames];
139 this.LastNames = this.LegalIdentity[Constants.XmppProperties.LastNames];
140 this.PersonalNumber = this.LegalIdentity[Constants.XmppProperties.PersonalNumber];
141 this.Address = this.LegalIdentity[Constants.XmppProperties.Address];
142 this.Address2 = this.LegalIdentity[Constants.XmppProperties.Address2];
143 this.ZipCode = this.LegalIdentity[Constants.XmppProperties.ZipCode];
144 this.Area = this.LegalIdentity[Constants.XmppProperties.Area];
145 this.City = this.LegalIdentity[Constants.XmppProperties.City];
146 this.Region = this.LegalIdentity[Constants.XmppProperties.Region];
147 this.CountryCode = this.LegalIdentity[Constants.XmppProperties.Country];
148 this.NationalityCode = this.LegalIdentity[Constants.XmppProperties.Nationality];
149 this.Gender = this.LegalIdentity[Constants.XmppProperties.Gender];
150
151 string BirthDayStr = this.LegalIdentity[Constants.XmppProperties.BirthDay];
152 string BirthMonthStr = this.LegalIdentity[Constants.XmppProperties.BirthMonth];
153 string BirthYearStr = this.LegalIdentity[Constants.XmppProperties.BirthYear];
154
155 if (!string.IsNullOrEmpty(BirthDayStr) && int.TryParse(BirthDayStr, out int BirthDay) &&
156 !string.IsNullOrEmpty(BirthMonthStr) && int.TryParse(BirthMonthStr, out int BirthMonth) &&
157 !string.IsNullOrEmpty(BirthYearStr) && int.TryParse(BirthYearStr, out int BirthYear))
158 {
159 try
160 {
161 this.BirthDate = new DateTime(BirthYear, BirthMonth, BirthDay);
162 }
163 catch (Exception ex)
164 {
165 ServiceRef.LogService.LogException(ex);
166 this.BirthDate = null;
167 }
168 }
169
170 this.OrgName = this.LegalIdentity[Constants.XmppProperties.OrgName];
171 this.OrgNumber = this.LegalIdentity[Constants.XmppProperties.OrgNumber];
172 this.OrgDepartment = this.LegalIdentity[Constants.XmppProperties.OrgDepartment];
173 this.OrgRole = this.LegalIdentity[Constants.XmppProperties.OrgRole];
174 this.OrgAddress = this.LegalIdentity[Constants.XmppProperties.OrgAddress];
175 this.OrgAddress2 = this.LegalIdentity[Constants.XmppProperties.OrgAddress2];
176 this.OrgZipCode = this.LegalIdentity[Constants.XmppProperties.OrgZipCode];
177 this.OrgArea = this.LegalIdentity[Constants.XmppProperties.OrgArea];
178 this.OrgCity = this.LegalIdentity[Constants.XmppProperties.OrgCity];
179 this.OrgRegion = this.LegalIdentity[Constants.XmppProperties.OrgRegion];
180 this.OrgCountryCode = this.LegalIdentity[Constants.XmppProperties.OrgCountry];
181 this.HasOrg =
182 !string.IsNullOrEmpty(this.OrgName) ||
183 !string.IsNullOrEmpty(this.OrgNumber) ||
184 !string.IsNullOrEmpty(this.OrgDepartment) ||
185 !string.IsNullOrEmpty(this.OrgRole) ||
186 !string.IsNullOrEmpty(this.OrgAddress) ||
187 !string.IsNullOrEmpty(this.OrgAddress2) ||
188 !string.IsNullOrEmpty(this.OrgZipCode) ||
189 !string.IsNullOrEmpty(this.OrgArea) ||
190 !string.IsNullOrEmpty(this.OrgCity) ||
191 !string.IsNullOrEmpty(this.OrgRegion) ||
192 !string.IsNullOrEmpty(this.OrgCountryCode);
193 this.HasPhotos = this.Photos.Count > 0;
194 this.PhoneNr = this.LegalIdentity[Constants.XmppProperties.Phone];
195 this.EMail = this.LegalIdentity[Constants.XmppProperties.EMail];
196 this.DeviceId = this.LegalIdentity[Constants.XmppProperties.DeviceId];
197 }
198 else
199 {
200 this.FirstName = string.Empty;
201 this.MiddleNames = string.Empty;
202 this.LastNames = string.Empty;
203 this.PersonalNumber = string.Empty;
204 this.Address = string.Empty;
205 this.Address2 = string.Empty;
206 this.ZipCode = string.Empty;
207 this.Area = string.Empty;
208 this.City = string.Empty;
209 this.Region = string.Empty;
210 this.CountryCode = string.Empty;
211 this.NationalityCode = string.Empty;
212 this.Gender = string.Empty;
213 this.BirthDate = null;
214 this.OrgName = Constants.NotAvailableValue;
215 this.OrgNumber = Constants.NotAvailableValue;
216 this.OrgDepartment = Constants.NotAvailableValue;
217 this.OrgRole = Constants.NotAvailableValue;
218 this.OrgAddress = Constants.NotAvailableValue;
219 this.OrgAddress2 = Constants.NotAvailableValue;
220 this.OrgZipCode = Constants.NotAvailableValue;
221 this.OrgArea = Constants.NotAvailableValue;
222 this.OrgCity = Constants.NotAvailableValue;
223 this.OrgRegion = Constants.NotAvailableValue;
224 this.OrgCountryCode = Constants.NotAvailableValue;
225 this.HasOrg = false;
226 this.HasPhotos = false;
227 this.PhoneNr = string.Empty;
228 this.EMail = string.Empty;
229 this.DeviceId = string.Empty;
230 this.NetworkId = Constants.NotAvailableValue;
231 }
232
233 this.IsApproved = this.LegalIdentity?.State == IdentityState.Approved;
234 this.IsCreated = this.LegalIdentity?.State == IdentityState.Created;
235
236 this.IsForReview = this.requestorIdentity is not null;
237 this.ThirdParty = (this.LegalIdentity is not null) && !this.IsPersonal;
238
239 this.IsForReviewFirstName = !string.IsNullOrWhiteSpace(this.FirstName) && this.IsForReview;
240 this.IsForReviewMiddleNames = !string.IsNullOrWhiteSpace(this.MiddleNames) && this.IsForReview;
241 this.IsForReviewLastNames = !string.IsNullOrWhiteSpace(this.LastNames) && this.IsForReview;
242 this.IsForReviewPersonalNumber = !string.IsNullOrWhiteSpace(this.PersonalNumber) && this.IsForReview;
243 this.IsForReviewAddress = !string.IsNullOrWhiteSpace(this.Address) && this.IsForReview;
244 this.IsForReviewAddress2 = !string.IsNullOrWhiteSpace(this.Address2) && this.IsForReview;
245 this.IsForReviewCity = !string.IsNullOrWhiteSpace(this.City) && this.IsForReview;
246 this.IsForReviewZipCode = !string.IsNullOrWhiteSpace(this.ZipCode) && this.IsForReview;
247 this.IsForReviewArea = !string.IsNullOrWhiteSpace(this.Area) && this.IsForReview;
248 this.IsForReviewRegion = !string.IsNullOrWhiteSpace(this.Region) && this.IsForReview;
249 this.IsForReviewCountry = !string.IsNullOrWhiteSpace(this.CountryCode) && this.IsForReview;
250
251 this.IsForReviewOrgName = !string.IsNullOrWhiteSpace(this.OrgName) && this.IsForReview;
252 this.IsForReviewOrgNumber = !string.IsNullOrWhiteSpace(this.OrgNumber) && this.IsForReview;
253 this.IsForReviewOrgDepartment = !string.IsNullOrWhiteSpace(this.OrgDepartment) && this.IsForReview;
254 this.IsForReviewOrgRole = !string.IsNullOrWhiteSpace(this.OrgRole) && this.IsForReview;
255 this.IsForReviewOrgAddress = !string.IsNullOrWhiteSpace(this.OrgAddress) && this.IsForReview;
256 this.IsForReviewOrgAddress2 = !string.IsNullOrWhiteSpace(this.OrgAddress2) && this.IsForReview;
257 this.IsForReviewOrgCity = !string.IsNullOrWhiteSpace(this.OrgCity) && this.IsForReview;
258 this.IsForReviewOrgZipCode = !string.IsNullOrWhiteSpace(this.OrgZipCode) && this.IsForReview;
259 this.IsForReviewOrgArea = !string.IsNullOrWhiteSpace(this.OrgArea) && this.IsForReview;
260 this.IsForReviewOrgRegion = !string.IsNullOrWhiteSpace(this.OrgRegion) && this.IsForReview;
261 this.IsForReviewOrgCountry = !string.IsNullOrWhiteSpace(this.OrgCountryCode) && this.IsForReview;
262
263 // QR
264 if (this.LegalIdentity is null)
265 this.RemoveQrCode();
266 else
267 this.GenerateQrCode(Constants.UriSchemes.CreateIdUri(this.LegalIdentity.Id));
268
269 if (this.IsConnected)
270 this.ReloadPhotos();
271 }
272
274 protected override Task XmppService_ConnectionStateChanged(object? Sender, XmppState NewState)
275 {
276 return MainThread.InvokeOnMainThreadAsync(async () =>
277 {
278 await base.XmppService_ConnectionStateChanged(Sender, NewState);
279
280 this.NotifyCommandsCanExecuteChanged();
281
282 if (this.IsConnected)
283 {
284 await Task.Delay(Constants.Timeouts.XmppInit);
285 this.ReloadPhotos();
286 }
287 });
288 }
289
290 private async void ReloadPhotos()
291 {
292 try
293 {
294 this.photosLoader.CancelLoadPhotos();
295
296 Attachment[]? Attachments;
297
298 if (this.requestorIdentity?.Attachments is not null)
299 Attachments = this.requestorIdentity.Attachments;
300 else
301 Attachments = this.LegalIdentity?.Attachments;
302
303 if (Attachments is not null)
304 {
305 Photo? First = await this.photosLoader.LoadPhotos(Attachments, SignWith.LatestApprovedIdOrCurrentKeys);
306
307 this.FirstPhotoSource = First?.Source;
308 this.FirstPhotoRotation = First?.Rotation ?? 0;
309 }
310 }
311 catch (Exception ex)
312 {
313 ServiceRef.LogService.LogException(ex);
314 }
315 }
316
317 private void TagProfile_Changed(object? Sender, PropertyChangedEventArgs e)
318 {
319 MainThread.BeginInvokeOnMainThread(this.AssignProperties);
320 }
321
322 private Task SmartContracts_LegalIdentityChanged(object? Sender, LegalIdentityEventArgs e)
323 {
324 MainThread.BeginInvokeOnMainThread(() =>
325 {
326 if (this.LegalIdentity?.Id == e.Identity.Id)
327 {
328 this.LegalIdentity = e.Identity;
329 this.AssignProperties();
330 }
331 });
332
333 return Task.CompletedTask;
334 }
335
336 #region Properties
337
341 public ObservableCollection<Photo> Photos { get; } = [];
342
346 public LegalIdentity? LegalIdentity { get; private set; }
347
351 [ObservableProperty]
352 private string? purpose;
353
357 [ObservableProperty]
358 private DateTime created;
359
363 [ObservableProperty]
364 private DateTime? updated;
365
369 [ObservableProperty]
370 private DateTime? expires;
371
375 [ObservableProperty]
376 private string? legalId;
377
381 [ObservableProperty]
382 private string? networkId;
383
387 [ObservableProperty]
388 private string? bareJid;
389
393 [ObservableProperty]
394 private string? publicKey;
395
399 [ObservableProperty]
400 private IdentityState? state;
401
405 [ObservableProperty]
406 private DateTime? from;
407
411 [ObservableProperty]
412 private DateTime? to;
413
417 [ObservableProperty]
418 [NotifyPropertyChangedFor(nameof(FullName))]
419 private string? firstName;
420
424 [ObservableProperty]
425 [NotifyPropertyChangedFor(nameof(FullName))]
426 private string? middleNames;
427
431 [ObservableProperty]
432 [NotifyPropertyChangedFor(nameof(FullName))]
433 private string? lastNames;
434
438 [ObservableProperty]
439 private string? personalNumber;
440
444 [ObservableProperty]
445 private string? address;
446
450 [ObservableProperty]
451 private string? address2;
452
456 [ObservableProperty]
457 private string? zipCode;
458
462 [ObservableProperty]
463 private string? area;
464
468 [ObservableProperty]
469 private string? city;
470
474 [ObservableProperty]
475 private string? region;
476
480 [ObservableProperty]
481 private string? countryCode;
482
486 [ObservableProperty]
487 private string? nationalityCode;
488
492 [ObservableProperty]
493 private string? gender;
494
498 [ObservableProperty]
499 private DateTime? birthDate;
500
504 [ObservableProperty]
505 private string? orgName;
506
510 [ObservableProperty]
511 private string? orgNumber;
512
516 [ObservableProperty]
517 private string? orgDepartment;
518
522 [ObservableProperty]
523 private string? orgRole;
524
528 [ObservableProperty]
529 private string? orgAddress;
530
534 [ObservableProperty]
535 private string? orgAddress2;
536
540 [ObservableProperty]
541 private string? orgZipCode;
542
546 [ObservableProperty]
547 private string? orgArea;
548
552 [ObservableProperty]
553 private string? orgCity;
554
558 [ObservableProperty]
559 private string? orgRegion;
560
564 [ObservableProperty]
565 private string? orgCountryCode;
566
570 [ObservableProperty]
571 private bool hasOrg;
572
576 [ObservableProperty]
577 private bool hasPhotos;
578
582 [ObservableProperty]
583 private string? phoneNr;
584
588 [ObservableProperty]
589 private string? eMail;
590
594 [ObservableProperty]
595 private string? deviceId;
596
600 [ObservableProperty]
601 private bool isApproved;
602
606 [ObservableProperty]
607 private bool isCreated;
608
612 [ObservableProperty]
613 [NotifyPropertyChangedFor(nameof(IsNotForReview))]
614 private bool isForReview;
615
619 public bool IsNotForReview => !this.IsForReview;
620
624 [ObservableProperty]
625 [NotifyPropertyChangedFor(nameof(IsThirdPartyAndNotForReview))]
626 private bool thirdParty;
627
628 [ObservableProperty]
629 private bool canAddContact = false;
630
631 [ObservableProperty]
632
633 private bool canRemoveContact = false;
634
638 public bool IsThirdPartyAndNotForReview => this.ThirdParty && !this.IsForReview;
639
643 [ObservableProperty]
644 private bool isPersonal;
645
649 [ObservableProperty]
650 private bool firstNameIsChecked;
651
655 [ObservableProperty]
656 private bool middleNamesIsChecked;
657
661 [ObservableProperty]
662 private bool lastNamesIsChecked;
663
667 [ObservableProperty]
668 private bool personalNumberIsChecked;
669
673 [ObservableProperty]
674 private bool addressIsChecked;
675
679 [ObservableProperty]
680 private bool address2IsChecked;
681
685 [ObservableProperty]
686 private bool zipCodeIsChecked;
687
691 [ObservableProperty]
692 private bool areaIsChecked;
693
697 [ObservableProperty]
698 private bool cityIsChecked;
699
703 [ObservableProperty]
704 private bool regionIsChecked;
705
709 [ObservableProperty]
710 private bool countryCodeIsChecked;
711
715 [ObservableProperty]
716 private bool orgNameIsChecked;
717
721 [ObservableProperty]
722 private bool orgDepartmentIsChecked;
723
727 [ObservableProperty]
728 private bool orgRoleIsChecked;
729
733 [ObservableProperty]
734 private bool orgNumberIsChecked;
735
739 [ObservableProperty]
740 private bool orgAddressIsChecked;
741
745 [ObservableProperty]
746 private bool orgAddress2IsChecked;
747
751 [ObservableProperty]
752 private bool orgZipCodeIsChecked;
753
757 [ObservableProperty]
758 private bool orgAreaIsChecked;
759
763 [ObservableProperty]
764 private bool orgCityIsChecked;
765
769 [ObservableProperty]
770 private bool orgRegionIsChecked;
771
775 [ObservableProperty]
776 private bool orgCountryCodeIsChecked;
777
781 [ObservableProperty]
782 private bool carefulReviewIsChecked;
783
787 [ObservableProperty]
788 private bool approvePiiIsChecked;
789
793 [ObservableProperty]
794 private bool isForReviewFirstName;
795
799 [ObservableProperty]
800 private bool isForReviewMiddleNames;
801
805 [ObservableProperty]
806 private bool isForReviewLastNames;
807
811 [ObservableProperty]
812 private bool isForReviewPersonalNumber;
813
817 [ObservableProperty]
818 private bool isForReviewAddress;
819
823 [ObservableProperty]
824 private bool isForReviewAddress2;
825
829 [ObservableProperty]
830 private bool isForReviewCity;
831
835 [ObservableProperty]
836 private bool isForReviewZipCode;
837
841 [ObservableProperty]
842 private bool isForReviewArea;
843
847 [ObservableProperty]
848 private bool isForReviewRegion;
849
853 [ObservableProperty]
854 private bool isForReviewCountry;
855
859 [ObservableProperty]
860 private bool isForReviewOrgName;
861
865 [ObservableProperty]
866 private bool isForReviewOrgDepartment;
867
871 [ObservableProperty]
872 private bool isForReviewOrgRole;
873
877 [ObservableProperty]
878 private bool isForReviewOrgNumber;
879
883 [ObservableProperty]
884 private bool isForReviewOrgAddress;
885
889 [ObservableProperty]
890 private bool isForReviewOrgAddress2;
891
895 [ObservableProperty]
896 private bool isForReviewOrgCity;
897
901 [ObservableProperty]
902 private bool isForReviewOrgZipCode;
903
907 [ObservableProperty]
908 private bool isForReviewOrgArea;
909
913 [ObservableProperty]
914 private bool isForReviewOrgRegion;
915
919 [ObservableProperty]
920 private bool isForReviewOrgCountry;
921
925 [ObservableProperty]
926 private ImageSource? firstPhotoSource;
927
931 [ObservableProperty]
932 private int firstPhotoRotation;
933
937 public bool CanExecuteCommands => !this.IsBusy && this.IsConnected;
938
942 public string FullName => ContactInfo.GetFullName(this.FirstName, this.MiddleNames, this.LastNames);
943
944 #endregion
945
946 private void NotifyCommandsCanExecuteChanged()
947 {
948 this.AddContactCommand.NotifyCanExecuteChanged();
949 this.RemoveContactCommand.NotifyCanExecuteChanged();
950 this.ApproveCommand.NotifyCanExecuteChanged();
951 this.RejectCommand.NotifyCanExecuteChanged();
952 }
953
955 public override void SetIsBusy(bool IsBusy)
956 {
957 base.SetIsBusy(IsBusy);
958 this.NotifyCommandsCanExecuteChanged();
959 }
960
964 [RelayCommand]
965 private async Task Copy(object Item)
966 {
967 try
968 {
969 this.SetIsBusy(true);
970
971 if (Item is string Label)
972 {
973 if (Label == this.LegalId)
974 {
975 await Clipboard.SetTextAsync(Constants.UriSchemes.IotId + ":" + this.LegalId);
976 await ServiceRef.UiService.DisplayAlert(
977 ServiceRef.Localizer[nameof(AppResources.SuccessTitle)],
978 ServiceRef.Localizer[nameof(AppResources.IdCopiedSuccessfully)]);
979 }
980 else
981 {
982 await Clipboard.SetTextAsync(Label);
983 await ServiceRef.UiService.DisplayAlert(
984 ServiceRef.Localizer[nameof(AppResources.SuccessTitle)],
985 ServiceRef.Localizer[nameof(AppResources.TagValueCopiedToClipboard)]);
986 }
987 }
988 }
989 catch (Exception ex)
990 {
991 ServiceRef.LogService.LogException(ex);
992 await ServiceRef.UiService.DisplayException(ex);
993 }
994 finally
995 {
996 this.SetIsBusy(false);
997 }
998 }
999
1000 [RelayCommand(CanExecute = nameof(CanRemoveContact))]
1001 private async Task RemoveContact()
1002 {
1003 if (this.LegalIdentity is null)
1004 return;
1005 try
1006 {
1007 if (!await ServiceRef.UiService.DisplayAlert(ServiceRef.Localizer["Confirm"], ServiceRef.Localizer["AreYouSureYouWantToRemoveContact"], ServiceRef.Localizer["Yes"], ServiceRef.Localizer["Cancel"]))
1008 return;
1009
1010 string BareJid = this.LegalIdentity.GetJid();
1011
1012 ContactInfo Info = await ContactInfo.FindByBareJid(BareJid);
1013 if (Info is not null)
1014 {
1015 await Database.Delete(Info);
1016 await ServiceRef.AttachmentCacheService.MakeTemporary(Info.LegalId);
1017 await Database.Provider.Flush();
1018 }
1019
1020 RosterItem? Item = ServiceRef.XmppService.GetRosterItem(BareJid);
1021 if (Item is not null)
1022 ServiceRef.XmppService.RemoveRosterItem(BareJid);
1023
1024 this.CanAddContact = true;
1025 this.CanRemoveContact = false;
1026 this.NotifyCommandsCanExecuteChanged();
1027 }
1028 catch (Exception ex)
1029 {
1030 ServiceRef.LogService.LogException(ex);
1031 await ServiceRef.UiService.DisplayException(ex);
1032 }
1033 }
1034
1035 [RelayCommand(CanExecute = nameof(CanAddContact))]
1036 private async Task AddContact()
1037 {
1038 if (this.LegalIdentity is null)
1039 return;
1040
1041
1042 try
1043 {
1044 this.SetIsBusy(true);
1045
1046 string FriendlyName = ContactInfo.GetFriendlyName(this.LegalIdentity);
1047 string BareJid = this.LegalIdentity.GetJid();
1048
1049 RosterItem? Item = ServiceRef.XmppService.GetRosterItem(BareJid);
1050 if (Item is null)
1051 ServiceRef.XmppService.AddRosterItem(new RosterItem(BareJid, FriendlyName));
1052
1053 ContactInfo Info = await ContactInfo.FindByBareJid(BareJid);
1054 if (Info is null)
1055 {
1056 Info = new ContactInfo()
1057 {
1058 BareJid = BareJid,
1059 LegalId = this.LegalIdentity.Id,
1061 FriendlyName = FriendlyName,
1062 IsThing = false
1063 };
1064
1065 await Database.Insert(Info);
1066 }
1067 else
1068 {
1069 Info.LegalId = this.LegalIdentity.Id;
1070 Info.LegalIdentity = this.LegalIdentity;
1071 Info.FriendlyName = FriendlyName;
1072
1073 await Database.Update(Info);
1074 }
1075 await ServiceRef.AttachmentCacheService.MakePermanent(this.LegalId!);
1076 await Database.Provider.Flush();
1077 this.CanAddContact = false;
1078 this.CanRemoveContact = true;
1079 this.NotifyCommandsCanExecuteChanged();
1080
1081 }
1082 catch (Exception ex)
1083 {
1084 ServiceRef.LogService.LogException(ex);
1085 await ServiceRef.UiService.DisplayException(ex);
1086 }
1087 finally
1088 {
1089 this.SetIsBusy(false);
1090 }
1091 }
1092
1093 [RelayCommand(CanExecute = nameof(CanExecuteCommands))]
1094 private async Task Approve()
1095 {
1096 if (this.requestorIdentity is null)
1097 return;
1098
1099 try
1100 {
1101 if ((!string.IsNullOrEmpty(this.FirstName) && !this.FirstNameIsChecked) ||
1102 (!string.IsNullOrEmpty(this.MiddleNames) && !this.MiddleNamesIsChecked) ||
1103 (!string.IsNullOrEmpty(this.LastNames) && !this.LastNamesIsChecked) ||
1104 (!string.IsNullOrEmpty(this.PersonalNumber) && !this.PersonalNumberIsChecked) ||
1105 (!string.IsNullOrEmpty(this.Address) && !this.AddressIsChecked) ||
1106 (!string.IsNullOrEmpty(this.Address2) && !this.Address2IsChecked) ||
1107 (!string.IsNullOrEmpty(this.ZipCode) && !this.ZipCodeIsChecked) ||
1108 (!string.IsNullOrEmpty(this.Area) && !this.AreaIsChecked) ||
1109 (!string.IsNullOrEmpty(this.City) && !this.CityIsChecked) ||
1110 (!string.IsNullOrEmpty(this.Region) && !this.RegionIsChecked) ||
1111 (!string.IsNullOrEmpty(this.CountryCode) && !this.CountryCodeIsChecked) ||
1112 (!string.IsNullOrEmpty(this.OrgName) && !this.OrgNameIsChecked) ||
1113 (!string.IsNullOrEmpty(this.OrgDepartment) && !this.OrgDepartmentIsChecked) ||
1114 (!string.IsNullOrEmpty(this.OrgRole) && !this.OrgRoleIsChecked) ||
1115 (!string.IsNullOrEmpty(this.OrgNumber) && !this.OrgNumberIsChecked) ||
1116 (!string.IsNullOrEmpty(this.OrgAddress) && !this.OrgAddressIsChecked) ||
1117 (!string.IsNullOrEmpty(this.OrgAddress2) && !this.OrgAddress2IsChecked) ||
1118 (!string.IsNullOrEmpty(this.OrgZipCode) && !this.OrgZipCodeIsChecked) ||
1119 (!string.IsNullOrEmpty(this.OrgArea) && !this.OrgAreaIsChecked) ||
1120 (!string.IsNullOrEmpty(this.OrgCity) && !this.OrgCityIsChecked) ||
1121 (!string.IsNullOrEmpty(this.OrgRegion) && !this.OrgRegionIsChecked) ||
1122 (!string.IsNullOrEmpty(this.OrgCountryCode) && !this.OrgCountryCodeIsChecked))
1123 {
1124 await ServiceRef.UiService.DisplayAlert(
1125 ServiceRef.Localizer[nameof(AppResources.Incomplete)],
1126 ServiceRef.Localizer[nameof(AppResources.PleaseReviewAndCheckAllCheckboxes)]);
1127 return;
1128 }
1129
1130 if (!this.CarefulReviewIsChecked)
1131 {
1132 await ServiceRef.UiService.DisplayAlert(
1133 ServiceRef.Localizer[nameof(AppResources.Incomplete)],
1134 ServiceRef.Localizer[nameof(AppResources.YouNeedToCheckCarefullyReviewed)]);
1135 return;
1136 }
1137
1138 if (!this.ApprovePiiIsChecked)
1139 {
1140 await ServiceRef.UiService.DisplayAlert(
1141 ServiceRef.Localizer[nameof(AppResources.Incomplete)],
1142 ServiceRef.Localizer[nameof(AppResources.YouNeedToApproveToAssociate)]);
1143 return;
1144 }
1145
1146 if (!await App.AuthenticateUser(AuthenticationPurpose.SignPetition, true))
1147 return;
1148
1149 (bool Succeeded1, byte[]? Signature) = await ServiceRef.NetworkService.TryRequest(
1150 () => ServiceRef.XmppService.Sign(this.contentToSign!, SignWith.LatestApprovedId));
1151
1152 if (!Succeeded1)
1153 return;
1154
1155 bool Succeeded2 = await ServiceRef.NetworkService.TryRequest(() =>
1156 {
1157 return ServiceRef.XmppService.SendPetitionSignatureResponse(
1158 this.signatoryIdentityId, this.contentToSign!, Signature!,
1159 this.petitionId!, this.requestorFullJid!, true);
1160 });
1161
1162 if (Succeeded2)
1163 await this.GoBack();
1164 }
1165 catch (Exception ex)
1166 {
1167 ServiceRef.LogService.LogException(ex);
1168 await ServiceRef.UiService.DisplayException(ex);
1169 }
1170 }
1171
1172 [RelayCommand(CanExecute = nameof(CanExecuteCommands))]
1173 private async Task Reject()
1174 {
1175 if (this.requestorIdentity is null)
1176 return;
1177
1178 try
1179 {
1180 bool Succeeded = await ServiceRef.NetworkService.TryRequest(() =>
1181 {
1182 return ServiceRef.XmppService.SendPetitionSignatureResponse(
1183 this.signatoryIdentityId, this.contentToSign!, [],
1184 this.petitionId!, this.requestorFullJid!, false);
1185 });
1186
1187 if (Succeeded)
1188 await this.GoBack();
1189 }
1190 catch (Exception ex)
1191 {
1192 ServiceRef.LogService.LogException(ex);
1193 await ServiceRef.UiService.DisplayException(ex);
1194 }
1195 }
1196
1197 #region ILinkableView
1198
1202 public override Task<string> Title => Task.FromResult<string>(ContactInfo.GetFriendlyName(this.LegalIdentity!));
1203
1204 #endregion
1205
1206
1207 }
1208}
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
static readonly TimeSpan XmppInit
XMPP Init timeout
Definition: Constants.cs:576
static string CreateIdUri(string id)
Generates a IoT ID Uri form the specified id.
Definition: Constants.cs:198
const string IotId
The IoT ID URI Scheme (iotid)
Definition: Constants.cs:99
const string PersonalNumber
Personal number
Definition: Constants.cs:284
const string OrgAddress2
Organization Address line 2
Definition: Constants.cs:364
const string OrgArea
Organization Area
Definition: Constants.cs:369
const string OrgRegion
Organization Region
Definition: Constants.cs:384
const string Nationality
Nationality
Definition: Constants.cs:324
const string BirthYear
Birth Year
Definition: Constants.cs:344
const string OrgCity
Organization City
Definition: Constants.cs:374
const string OrgRole
Organization Role
Definition: Constants.cs:399
const string Phone
Phone number
Definition: Constants.cs:414
const string EMail
e-Mail address
Definition: Constants.cs:419
const string OrgZipCode
Organization Zip Code
Definition: Constants.cs:379
const string MiddleNames
Middle names
Definition: Constants.cs:274
const string OrgCountry
Organization Country
Definition: Constants.cs:389
const string OrgDepartment
Organization Department
Definition: Constants.cs:394
const string Address2
Address line 2
Definition: Constants.cs:294
const string OrgAddress
Organization Address line 1
Definition: Constants.cs:359
const string Address
Address line 1
Definition: Constants.cs:289
const string LastNames
Last names
Definition: Constants.cs:279
const string OrgNumber
Organization number
Definition: Constants.cs:354
const string BirthMonth
Birth Month
Definition: Constants.cs:339
const string FirstName
First name
Definition: Constants.cs:269
const string OrgName
Organization name
Definition: Constants.cs:349
A set of never changing property constants and helpful values.
Definition: Constants.cs:7
const string NotAvailableValue
A generic "no value available" string.
Definition: Constants.cs:11
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 string GetFullName(LegalIdentity? Identity)
Gets the full name of a person.
Definition: ContactInfo.cs:577
static Task< ContactInfo > FindByBareJid(string BareJid)
Finds information about a contact, given its Bare JID.
Definition: ContactInfo.cs:220
CaseInsensitiveString LegalId
Legal ID of contact.
Definition: ContactInfo.cs:71
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 IAttachmentCacheService AttachmentCacheService
AttachmentCache service.
Definition: ServiceRef.cs:151
static ITagProfile TagProfile
TAG Profile service.
Definition: ServiceRef.cs:79
static IStringLocalizer Localizer
Localization service
Definition: ServiceRef.cs:235
static IXmppService XmppService
The XMPP service for XMPP communication.
Definition: ServiceRef.cs:67
virtual async Task GoBack()
Method called when user wants to navigate to the previous screen.
The view model to bind to for when displaying identities.
override async Task OnDispose()
Method called when the view is disposed, and will not be used more. Use this method to unregister eve...
LegalIdentity? LegalIdentity
The full legal identity of the identity
override async Task OnInitialize()
Method called when view is initialized for the first time. Use this method to implement registration ...
ObservableCollection< Photo > Photos
Holds a list of photos associated with this identity.
override Task XmppService_ConnectionStateChanged(object? Sender, XmppState NewState)
Listens to connection state changes from the XMPP server.
bool IsNotForReview
Gets or sets whether the identity is for review or not. This property has its inverse in IsForReview.
bool IsThirdPartyAndNotForReview
Gets wheter the identity is a third party and not for review.
ViewIdentityViewModel(ViewIdentityNavigationArgs? Args)
Creates an instance of the ViewIdentityViewModel class.
override void SetIsBusy(bool IsBusy)
Sets the IsBusy property.
A view model that holds the XMPP state.
void RemoveQrCode()
Removes the QR-code
void GenerateQrCode(string Uri)
Generates a QR-code
Contains a reference to an attachment assigned to a legal object.
Definition: Attachment.cs:9
Abstract base class of signatures
Definition: Signature.cs:10
Maintains information about an item in the roster.
Definition: RosterItem.cs:75
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 Delete(object Object)
Deletes an object in the database.
Definition: Database.cs:717
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.
class Photo(byte[] Binary, int Rotation)
Class containing information about a photo.
Definition: Photo.cs:8
AuthenticationPurpose
Purpose for requesting the user to authenticate itself.
IdentityState
Lists recognized legal identity states.
SignWith
Options on what keys to use when signing data.
Definition: Enumerations.cs:84
XmppState
State of XMPP connection.
Definition: XmppState.cs:7