1using CommunityToolkit.Mvvm.ComponentModel;
2using CommunityToolkit.Mvvm.Input;
8using System.Collections.ObjectModel;
9using System.ComponentModel;
21 private readonly PhotosLoader photosLoader;
23 private string? requestorFullJid;
24 private string? signatoryIdentityId;
25 private string? petitionId;
26 private byte[]? contentToSign;
35 this.photosLoader =
new PhotosLoader(this.
Photos);
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;
52 await base.OnInitialize();
57 this.requestorIdentity =
null;
58 this.requestorFullJid =
null;
59 this.signatoryIdentityId =
null;
60 this.petitionId =
null;
62 this.contentToSign =
null;
63 this.IsPersonal =
true;
66 this.IsPersonal =
false;
68 this.AssignProperties();
74 if ((Info is not
null) &&
76 (Info.
LegalId !=
this.LegalId &&
80 Info.LegalId = this.LegalId;
88 this.CanAddContact = Info is
null;
89 this.CanRemoveContact = Info is not
null;
91 this.NotifyCommandsCanExecuteChanged();
94 ServiceRef.TagProfile.Changed += this.TagProfile_Changed;
95 ServiceRef.XmppService.LegalIdentityChanged += this.SmartContracts_LegalIdentityChanged;
101 this.photosLoader.CancelLoadPhotos();
103 ServiceRef.TagProfile.Changed -= this.TagProfile_Changed;
104 ServiceRef.XmppService.LegalIdentityChanged -= this.SmartContracts_LegalIdentityChanged;
106 this.LegalIdentity =
null;
108 await base.OnDispose();
111 private void AssignProperties()
119 if (this.requestorIdentity is not
null)
129 this.PublicKey =
string.Empty;
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))
161 this.BirthDate =
new DateTime(BirthYear, BirthMonth, BirthDay);
166 this.BirthDate =
null;
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;
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;
226 this.HasPhotos =
false;
227 this.PhoneNr =
string.Empty;
228 this.EMail =
string.Empty;
229 this.DeviceId =
string.Empty;
236 this.IsForReview = this.requestorIdentity is not
null;
237 this.ThirdParty = (this.LegalIdentity is not
null) && !this.IsPersonal;
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;
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;
269 if (this.IsConnected)
276 return MainThread.InvokeOnMainThreadAsync(async () =>
278 await base.XmppService_ConnectionStateChanged(Sender, NewState);
280 this.NotifyCommandsCanExecuteChanged();
282 if (this.IsConnected)
290 private async
void ReloadPhotos()
294 this.photosLoader.CancelLoadPhotos();
298 if (this.requestorIdentity?.Attachments is not
null)
303 if (Attachments is not
null)
305 Photo? First = await this.photosLoader.LoadPhotos(Attachments,
SignWith.LatestApprovedIdOrCurrentKeys);
307 this.FirstPhotoSource = First?.Source;
308 this.FirstPhotoRotation = First?.Rotation ?? 0;
317 private void TagProfile_Changed(
object? Sender, PropertyChangedEventArgs e)
319 MainThread.BeginInvokeOnMainThread(this.AssignProperties);
322 private Task SmartContracts_LegalIdentityChanged(
object? Sender, LegalIdentityEventArgs e)
324 MainThread.BeginInvokeOnMainThread(() =>
328 this.LegalIdentity = e.Identity;
329 this.AssignProperties();
333 return Task.CompletedTask;
341 public ObservableCollection<Photo>
Photos {
get; } = [];
352 private string? purpose;
358 private DateTime created;
364 private DateTime? updated;
370 private DateTime? expires;
376 private string? legalId;
382 private string? networkId;
388 private string? bareJid;
394 private string? publicKey;
406 private DateTime? from;
412 private DateTime? to;
418 [NotifyPropertyChangedFor(nameof(
FullName))]
419 private string? firstName;
425 [NotifyPropertyChangedFor(nameof(
FullName))]
426 private string? middleNames;
432 [NotifyPropertyChangedFor(nameof(
FullName))]
433 private string? lastNames;
439 private string? personalNumber;
445 private string? address;
451 private string? address2;
457 private string? zipCode;
463 private string? area;
469 private string? city;
475 private string? region;
481 private string? countryCode;
487 private string? nationalityCode;
493 private string? gender;
499 private DateTime? birthDate;
505 private string? orgName;
511 private string? orgNumber;
517 private string? orgDepartment;
523 private string? orgRole;
529 private string? orgAddress;
535 private string? orgAddress2;
541 private string? orgZipCode;
547 private string? orgArea;
553 private string? orgCity;
559 private string? orgRegion;
565 private string? orgCountryCode;
577 private bool hasPhotos;
583 private string? phoneNr;
589 private string? eMail;
595 private string? deviceId;
601 private bool isApproved;
607 private bool isCreated;
614 private bool isForReview;
626 private bool thirdParty;
629 private bool canAddContact =
false;
633 private bool canRemoveContact =
false;
644 private bool isPersonal;
650 private bool firstNameIsChecked;
656 private bool middleNamesIsChecked;
662 private bool lastNamesIsChecked;
668 private bool personalNumberIsChecked;
674 private bool addressIsChecked;
680 private bool address2IsChecked;
686 private bool zipCodeIsChecked;
692 private bool areaIsChecked;
698 private bool cityIsChecked;
704 private bool regionIsChecked;
710 private bool countryCodeIsChecked;
716 private bool orgNameIsChecked;
722 private bool orgDepartmentIsChecked;
728 private bool orgRoleIsChecked;
734 private bool orgNumberIsChecked;
740 private bool orgAddressIsChecked;
746 private bool orgAddress2IsChecked;
752 private bool orgZipCodeIsChecked;
758 private bool orgAreaIsChecked;
764 private bool orgCityIsChecked;
770 private bool orgRegionIsChecked;
776 private bool orgCountryCodeIsChecked;
782 private bool carefulReviewIsChecked;
788 private bool approvePiiIsChecked;
794 private bool isForReviewFirstName;
800 private bool isForReviewMiddleNames;
806 private bool isForReviewLastNames;
812 private bool isForReviewPersonalNumber;
818 private bool isForReviewAddress;
824 private bool isForReviewAddress2;
830 private bool isForReviewCity;
836 private bool isForReviewZipCode;
842 private bool isForReviewArea;
848 private bool isForReviewRegion;
854 private bool isForReviewCountry;
860 private bool isForReviewOrgName;
866 private bool isForReviewOrgDepartment;
872 private bool isForReviewOrgRole;
878 private bool isForReviewOrgNumber;
884 private bool isForReviewOrgAddress;
890 private bool isForReviewOrgAddress2;
896 private bool isForReviewOrgCity;
902 private bool isForReviewOrgZipCode;
908 private bool isForReviewOrgArea;
914 private bool isForReviewOrgRegion;
920 private bool isForReviewOrgCountry;
926 private ImageSource? firstPhotoSource;
932 private int firstPhotoRotation;
946 private void NotifyCommandsCanExecuteChanged()
948 this.AddContactCommand.NotifyCanExecuteChanged();
949 this.RemoveContactCommand.NotifyCanExecuteChanged();
950 this.ApproveCommand.NotifyCanExecuteChanged();
951 this.RejectCommand.NotifyCanExecuteChanged();
957 base.SetIsBusy(IsBusy);
958 this.NotifyCommandsCanExecuteChanged();
965 private async Task Copy(
object Item)
971 if (Item is
string Label)
973 if (Label == this.LegalId)
982 await Clipboard.SetTextAsync(Label);
1000 [RelayCommand(CanExecute = nameof(CanRemoveContact))]
1001 private async Task RemoveContact()
1013 if (Info is not
null)
1021 if (Item is not
null)
1024 this.CanAddContact =
true;
1025 this.CanRemoveContact =
false;
1026 this.NotifyCommandsCanExecuteChanged();
1028 catch (Exception ex)
1035 [RelayCommand(CanExecute = nameof(CanAddContact))]
1036 private async Task AddContact()
1061 FriendlyName = FriendlyName,
1071 Info.FriendlyName = FriendlyName;
1077 this.CanAddContact =
false;
1078 this.CanRemoveContact =
true;
1079 this.NotifyCommandsCanExecuteChanged();
1082 catch (Exception ex)
1094 private async Task Approve()
1096 if (this.requestorIdentity is
null)
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))
1130 if (!this.CarefulReviewIsChecked)
1138 if (!this.ApprovePiiIsChecked)
1158 this.signatoryIdentityId, this.contentToSign!,
Signature!,
1159 this.petitionId!, this.requestorFullJid!,
true);
1165 catch (Exception ex)
1173 private async Task Reject()
1175 if (this.requestorIdentity is
null)
1183 this.signatoryIdentityId, this.contentToSign!, [],
1184 this.petitionId!, this.requestorFullJid!,
false);
1190 catch (Exception ex)
1197 #region ILinkableView
The Application class, representing an instance of the Neuro-Access app.
static Task< bool > AuthenticateUser(AuthenticationPurpose Purpose, bool Force=false)
Authenticates the user using the configured authentication method.
static readonly TimeSpan XmppInit
XMPP Init timeout
static string CreateIdUri(string id)
Generates a IoT ID Uri form the specified id.
const string IotId
The IoT ID URI Scheme (iotid)
XMPP Protocol Properties.
const string PersonalNumber
Personal number
const string OrgAddress2
Organization Address line 2
const string DeviceId
Device ID
const string Country
Country
const string OrgArea
Organization Area
const string Region
Region
const string OrgRegion
Organization Region
const string Nationality
Nationality
const string ZipCode
Zip Code
const string BirthYear
Birth Year
const string OrgCity
Organization City
const string OrgRole
Organization Role
const string Phone
Phone number
const string EMail
e-Mail address
const string OrgZipCode
Organization Zip Code
const string MiddleNames
Middle names
const string BirthDay
Birth Day
const string OrgCountry
Organization Country
const string OrgDepartment
Organization Department
const string Address2
Address line 2
const string OrgAddress
Organization Address line 1
const string Address
Address line 1
const string LastNames
Last names
const string OrgNumber
Organization number
const string BirthMonth
Birth Month
const string FirstName
First name
const string Gender
Gender
const string OrgName
Organization name
A set of never changing property constants and helpful values.
const string NotAvailableValue
A generic "no value available" string.
Base class that references services in the app.
static ILogService LogService
Log service.
static INetworkService NetworkService
Network service.
static IUiService UiService
Service serializing and managing UI-related tasks.
static IAttachmentCacheService AttachmentCacheService
AttachmentCache service.
static ITagProfile TagProfile
TAG Profile service.
static IStringLocalizer Localizer
Localization service
static IXmppService XmppService
The XMPP service for XMPP communication.
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.
string FullName
Full name of person
override async Task OnDispose()
Method called when the view is disposed, and will not be used more. Use this method to unregister eve...
bool CanExecuteCommands
Used to find out if a command can execute
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< string > Title
Title of the current view
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.
DateTime From
From what point in time the legal identity is valid.
DateTime Updated
When the identity object was last updated
DateTime To
To what point in time the legal identity is valid.
DateTime Created
When the identity object was created
IdentityState State
Current state of identity
byte[] ClientPubKey
Client Public key
string Id
ID of the legal identity
Attachment[] Attachments
Attachments assigned to the legal identity.
Abstract base class of signatures
Maintains information about an item in the roster.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static IDatabaseProvider Provider
Registered database provider.
static async Task Update(object Object)
Updates an object in the database.
static async Task Delete(object Object)
Deletes an object in the database.
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
Task Flush()
Persists any pending changes.
class Photo(byte[] Binary, int Rotation)
Class containing information about a photo.
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.
XmppState
State of XMPP connection.