1using System.ComponentModel;
2using System.Globalization;
3using CommunityToolkit.Mvvm.ComponentModel;
4using CommunityToolkit.Mvvm.Input;
28 await base.OnInitialize();
30 LocalizationManager.Current.PropertyChanged += this.LocalizationManagerEventHandler;
34 this.CountDownTimer =
App.
Current.Dispatcher.CreateTimer();
35 this.CountDownTimer.Interval = TimeSpan.FromMilliseconds(1000);
36 this.CountDownTimer.Tick += this.CountDownEventHandler;
45 new KeyValuePair<string, string>(
"Accept",
"application/json"));
47 if ((Result is Dictionary<string, object> Response) &&
48 Response.TryGetValue(
"CountryCode", out
object? cc) &&
49 (cc is
string CountryCode))
52 this.SelectedCountry = Country;
65 LocalizationManager.Current.PropertyChanged -= this.LocalizationManagerEventHandler;
67 if (this.CountDownTimer is not
null)
69 this.CountDownTimer.Stop();
70 this.CountDownTimer.Tick -= this.CountDownEventHandler;
71 this.CountDownTimer =
null;
74 await base.OnDispose();
80 await base.DoAssignProperties();
84 if (
string.IsNullOrEmpty(PhoneNumber))
90 new KeyValuePair<string, string>(
"Accept",
"application/json"));
92 if ((Result is Dictionary<string, object> Response) &&
93 Response.TryGetValue(
"CountryCode", out
object? cc) &&
94 (cc is
string CountryCode))
97 this.SelectedCountry = Country;
111 this.SelectedCountry = Country;
112 this.PhoneNumber = PhoneNumber[(Country.DialCode.Length + 1)..];
113 this.SendCodeCommand.NotifyCanExecuteChanged();
118 protected override void OnPropertyChanged(PropertyChangedEventArgs e)
120 base.OnPropertyChanged(e);
122 if (e.PropertyName == nameof(this.IsBusy))
123 this.SendCodeCommand.NotifyCanExecuteChanged();
126 public void LocalizationManagerEventHandler(
object? sender, PropertyChangedEventArgs e)
128 this.OnPropertyChanged(nameof(this.LocalizedSendCodeText));
129 this.OnPropertyChanged(nameof(this.LocalizedValidationError));
136 [NotifyCanExecuteChangedFor(nameof(SendCodeCommand))]
140 [NotifyPropertyChangedFor(nameof(LocalizedValidationError))]
144 [NotifyPropertyChangedFor(nameof(LocalizedValidationError))]
148 [NotifyPropertyChangedFor(nameof(LocalizedSendCodeText))]
149 [NotifyCanExecuteChangedFor(nameof(SendCodeCommand))]
150 [NotifyCanExecuteChangedFor(nameof(ResendCodeCommand))]
151 private int countDownSeconds;
154 private IDispatcherTimer? countDownTimer;
156 public string LocalizedSendCodeText
160 if (this.CountDownSeconds > 0)
167 public string LocalizedValidationError
171 if (!this.TypeIsValid)
174 if (!this.LengthIsValid)
185 private string phoneNumber =
string.Empty;
187 public bool CanSendCode => this.NumberIsValid && !this.IsBusy &&
188 (this.PhoneNumber.Length > 0) && (this.CountDownSeconds <= 0);
190 public bool CanResendCode => this.CountDownSeconds <= 0;
193 private async Task SelectPhoneCode()
196 await MopupService.Instance.PushAsync(Page);
200 if (Result is not
null)
201 this.SelectedCountry = Result;
206 [RelayCommand(CanExecute = nameof(CanSendCode))]
207 private async Task SendCode()
220 string FullPhoneNumber = $
"+{this.SelectedCountry.DialCode}{this.PhoneNumber}";
222 if (this.SelectedCountry.DialCode ==
"46")
223 FullPhoneNumber = $
"+{this.SelectedCountry.DialCode}{this.PhoneNumber.TrimStart('0')}";
227 new Dictionary<string, object>()
229 {
"Nr", FullPhoneNumber },
230 {
"AppName", Constants.Application.Name },
231 {
"Language", CultureInfo.CurrentCulture.TwoLetterISOLanguageName }
232 },
new KeyValuePair<string, string>(
"Accept",
"application/json"));
234 if (SendResult is Dictionary<string, object> SendResponse &&
235 SendResponse.TryGetValue(
"Status", out
object? Obj) && Obj is
bool SendStatus && SendStatus &&
236 SendResponse.TryGetValue(
"IsTemporary", out Obj) && Obj is
bool SendIsTemporary)
248 VerifyCodeNavigationArgs
NavigationArgs =
new(
this, FullPhoneNumber);
252 if (!
string.IsNullOrEmpty(Code))
263 new Dictionary<string, object>()
265 {
"Nr", FullPhoneNumber },
266 {
"Code",
int.Parse(Code, NumberStyles.None, CultureInfo.InvariantCulture) },
268 },
new KeyValuePair<string, string>(
"Accept",
"application/json"));
271 if (VerifyResult is Dictionary<string, object> VerifyResponse &&
272 VerifyResponse.TryGetValue(
"Status", out Obj) && Obj is
bool VerifyStatus && VerifyStatus &&
273 VerifyResponse.TryGetValue(
"Domain", out Obj) && Obj is
string VerifyDomain &&
274 VerifyResponse.TryGetValue(
"Key", out Obj) && Obj is
string VerifyKey &&
275 VerifyResponse.TryGetValue(
"Secret", out Obj) && Obj is
string VerifySecret &&
276 VerifyResponse.TryGetValue(
"Temporary", out Obj) && Obj is
bool VerifyIsTemporary)
280 ServiceRef.TagProfile.TestOtpTimestamp = VerifyIsTemporary ? DateTime.Now :
null;
288 bool DefaultConnectivity;
292 (
string HostName,
int PortNumber,
bool IsIpAddress) = await
ServiceRef.
NetworkService.LookupXmppHostnameAndPort(VerifyDomain);
297 DefaultConnectivity =
false;
302 if (VerifyIsTemporary)
338 [RelayCommand(CanExecute = nameof(CanResendCode))]
339 private async Task ResendCode()
351 string FullPhoneNumber = $
"+{this.SelectedCountry.DialCode}{this.PhoneNumber}";
353 if (this.SelectedCountry.DialCode ==
"46")
354 FullPhoneNumber = $
"+{this.SelectedCountry.DialCode}{this.PhoneNumber.TrimStart('0')}";
358 new Dictionary<string, object>()
360 {
"Nr", FullPhoneNumber },
361 {
"AppName", Constants.Application.Name },
362 {
"Language", CultureInfo.CurrentCulture.TwoLetterISOLanguageName }
363 },
new KeyValuePair<string, string>(
"Accept",
"application/json"));
365 if (SendResult is Dictionary<string, object> SendResponse &&
366 SendResponse.TryGetValue(
"Status", out
object? Obj) && Obj is
bool SendStatus && SendStatus)
387 private void StartTimer()
389 if (this.CountDownTimer is not
null)
391 this.CountDownSeconds = 300;
393 if (!this.CountDownTimer.IsRunning)
394 this.CountDownTimer.Start();
398 private void CountDownEventHandler(
object? sender, EventArgs e)
400 if (this.CountDownTimer is not
null)
402 if (this.CountDownSeconds > 0)
403 this.CountDownSeconds--;
405 this.CountDownTimer.Stop();
The Application class, representing an instance of the Neuro-Access app.
static new? App Current
Gets the current application, type casted to App.
const string IdDomain
Neuro-Access domain.
A set of never changing property constants and helpful values.
Conversion between Country Names and ISO-3166-1 country codes.
static bool TryGetCountryByCode(string? CountryCode, [NotNullWhen(true)] out ISO_3166_Country? Country)
Tries to get the country, given its country code.
static ISO_3166_Country DefaultCountry
This collection built from Wikipedia entry on ISO3166-1 on 9th Feb 2016
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 ITagProfile TagProfile
TAG Profile service.
static IStringLocalizer Localizer
Localization service
An base class holding page specific navigation parameters.
override async Task OnInitialize()
override async Task OnDispose()
override async Task DoAssignProperties()
Static class managing encoding and decoding of internet content.
static Task< object > PostAsync(Uri Uri, object Data, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
Class containing credentials for an XMPP client connection.
const int DefaultPort
Default XMPP Server port.
void SetDomain(string DomainName, bool DefaultXmppConnectivity, string Key, string Secret)
Set the domain name to connect to.
string? SelectedCountry
Selected country. Some countries have the same phone code, so we want to save the selected country
PurposeUse Purpose
Purpose for using the app.
void SetPhone(string Country, string PhoneNumber)
Sets the phone number used for contacting the user.
string? PhoneNumber
Verified phone number.
void SetPurpose(bool IsTest, PurposeUse Purpose)
Set if the user choose the educational or experimental purpose.
string? Domain
The domain this profile is connected to.
Task GoToAsync(string Route, BackMethod BackMethod=BackMethod.Inherited, string? UniqueId=null)
Navigates the AppShell to the specified route, with page arguments to match.
Task< bool > DisplayAlert(string Title, string Message, string? Accept=null, string? Cancel=null)
Displays an alert/message box to the user.
class ISO_3166_Country(string Name, string Alpha2, string Alpha3, int NumericCode, string DialCode, EmojiInfo? EmojiInfo=null)
Representation of an ISO3166-1 Country
RegistrationStep
The different steps of a TAG Profile registration journey.
PurposeUse
For what purpose the app will be used
BackMethod
Navigation Back Method