Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ScanQrCodeViewModel.cs
1using System.Collections.ObjectModel;
2using System.ComponentModel;
3using CommunityToolkit.Mvvm.ComponentModel;
4using CommunityToolkit.Mvvm.Input;
7
9{
13 public partial class ScanQrCodeViewModel : BaseViewModel
14 {
15 private readonly ScanQrCodeNavigationArgs? navigationArgs;
16 private IDispatcherTimer? countDownTimer;
17
22 public ScanQrCodeViewModel(ScanQrCodeNavigationArgs? Args)
23 {
24 this.navigationArgs = Args;
25 if (this.navigationArgs is not null &&
26 this.navigationArgs.AllowedSchemas is not null &&
27 this.navigationArgs.AllowedSchemas.Length > 0 &&
28 this.Icons.Count == 0)
29 {
30 foreach (string Schema in this.navigationArgs.AllowedSchemas)
31 {
32 switch (Schema)
33 {
35 this.Icons.Add(new UriSchemaIcon(Geometries.UserIconPath, Geometries.UserColor, this));
36 break;
37
40 break;
41
44 break;
45
48 break;
49
52 break;
53
56 break;
57
60 break;
61
64 break;
65
67 default:
68 break;
69 }
70 }
71
72 if (this.Icons.Count == 0)
74 }
75 }
76
78 protected override async Task OnInitialize()
79 {
80 await base.OnInitialize();
81
82 LocalizationManager.Current.PropertyChanged += this.LocalizationManagerEventHandler;
83
84 if (App.Current is not null)
85 {
86 this.countDownTimer = App.Current.Dispatcher.CreateTimer();
87 this.countDownTimer.Interval = TimeSpan.FromMilliseconds(500);
88 this.countDownTimer.Tick += this.CountDownEventHandler;
89 }
90 }
91
93 protected override async Task OnDispose()
94 {
95 LocalizationManager.Current.PropertyChanged -= this.LocalizationManagerEventHandler;
96
97 if (this.countDownTimer is not null)
98 {
99 this.countDownTimer.Stop();
100 this.countDownTimer.Tick -= this.CountDownEventHandler;
101 this.countDownTimer = null;
102 }
103
104 if (this.navigationArgs?.QrCodeScanned is TaskCompletionSource<string> TaskSource)
105 TaskSource.TrySetResult(string.Empty);
106
107 await base.OnDispose();
108 }
109
110 private void CountDownEventHandler(object? sender, EventArgs e)
111 {
112 this.countDownTimer?.Stop();
113 this.OnBackgroundColorChanged();
114 }
115
116 private void OnBackgroundColorChanged()
117 {
118 this.OnPropertyChanged(nameof(this.IconBackgroundColor));
119
120 foreach (UriSchemaIcon Icon in this.Icons)
121 Icon.BackgroundColorChanged();
122 }
123
124 public void LocalizationManagerEventHandler(object? sender, PropertyChangedEventArgs e)
125 {
126 this.OnPropertyChanged(nameof(this.LocalizedQrPageTitle));
127 }
128
129 public Task DoSwitchMode(bool IsAutomaticScan)
130 {
131 this.IsAutomaticScan = IsAutomaticScan;
132 return Task.CompletedTask;
133 }
134
135 public Task SetScannedText(string? ScannedText)
136 {
137 this.ScannedText = ScannedText ?? string.Empty;
138 this.countDownTimer?.Stop();
139 this.OnBackgroundColorChanged();
140
141 if (this.CanOpen(ScannedText))
142 {
143 return this.TrySetResultAndClosePage(ScannedText!.Trim());
144 }
145 this.countDownTimer?.Start();
146 this.OnBackgroundColorChanged();
147
148 return Task.CompletedTask;
149 }
150
155 private async Task TrySetResultAndClosePage(string? Url)
156 {
157 if (this.navigationArgs?.QrCodeScanned is not null)
158 {
159 TaskCompletionSource<string?> TaskSource = this.navigationArgs.QrCodeScanned;
160 this.navigationArgs.QrCodeScanned = null;
161
162 await MainThread.InvokeOnMainThreadAsync(async () =>
163 {
164 try
165 {
166 await base.GoBack();
167 TaskSource.TrySetResult(Url);
168 }
169 catch (Exception ex)
170 {
171 ServiceRef.LogService.LogException(ex);
172 }
173 });
174 }
175 }
176
177 #region Properties
178
182 [ObservableProperty]
183 [NotifyCanExecuteChangedFor(nameof(OpenUrlCommand))]
184 private string? manualText;
185
189 [ObservableProperty]
190 private string? scannedText;
191
195 [ObservableProperty]
196 private bool isAutomaticScan = true;
197
201 public bool HasAllowedSchemas => this.navigationArgs?.AllowedSchemas is not null && this.navigationArgs.AllowedSchemas.Length > 0;
202
206 [ObservableProperty]
207 [NotifyPropertyChangedFor(nameof(MultipleIcons))]
208 [NotifyPropertyChangedFor(nameof(SingleIcon))]
209 private ObservableCollection<UriSchemaIcon> icons = [];
210
214 public bool MultipleIcons => this.Icons.Count > 1;
215
219 public bool SingleIcon => this.Icons.Count == 1;
220
225 {
226 get
227 {
228 if (string.IsNullOrEmpty(this.ScannedText))
229 return Colors.White;
230
231 string Url = this.ScannedText.Trim();
232
233 if ((this.countDownTimer?.IsRunning ?? false) &&
234 (this.navigationArgs?.AllowedSchemas is not null) &&
235 this.navigationArgs.AllowedSchemas.Length > 0)
236 {
237 return this.IsPermittedUrl(Url) ? Colors.White : Colors.LightSalmon;
238 }
239
240 return Colors.White;
241 }
242 }
243
244 private bool IsPermittedUrl(string Url)
245 {
246 if (this.navigationArgs?.AllowedSchemas is not null &&
247 System.Uri.TryCreate(Url, UriKind.Absolute, out Uri? Uri))
248 {
249 foreach (string Schema in this.navigationArgs.AllowedSchemas)
250 {
251 if (string.Equals(Uri.Scheme, Schema, StringComparison.OrdinalIgnoreCase))
252 return true;
253 }
254 }
255
256 return false;
257 }
258
263 {
264 get
265 {
266 if (this.navigationArgs?.QrTitle is not null)
267 return ServiceRef.Localizer[this.navigationArgs.QrTitle];
268
269 return string.Empty;
270 }
271 }
272
273 private bool CanOpen(string? Text)
274 {
275 string? Url = Text?.Trim();
276 if (string.IsNullOrEmpty(Url))
277 return false;
278
279 if (this.navigationArgs?.AllowedSchemas is not null && this.navigationArgs.AllowedSchemas.Length > 0)
280 return this.IsPermittedUrl(Url);
281 else
282 return Url.Length > 0;
283 }
284
288 public bool CanOpenScanned => this.CanOpen(this.ScannedText);
289
293 public bool CanOpenManual => this.CanOpen(this.ManualText);
294
295 #endregion
296
297 [RelayCommand(CanExecute = nameof(CanOpenManual))]
298 private Task OpenUrl()
299 {
300 return this.TrySetResultAndClosePage(this.ManualText!.Trim());
301 }
302
304 public override Task GoBack()
305 {
306 return this.TrySetResultAndClosePage(null);
307 }
308 }
309}
The Application class, representing an instance of the Neuro-Access app.
Definition: App.xaml.cs:69
static new? App Current
Gets the current application, type casted to App.
Definition: App.xaml.cs:99
const string TagSign
TAG Signature (Quick-Login) URI Scheme (tagsign)
Definition: Constants.cs:114
const string IotSc
The IoT Smart Contract URI Scheme (iotsc)
Definition: Constants.cs:109
const string Onboarding
Onboarding URI Scheme (obinfo)
Definition: Constants.cs:129
const string NeuroFeature
eDaler URI Scheme (edaler)
Definition: Constants.cs:124
const string Aes256
AES-256-encrypted data.
Definition: Constants.cs:139
const string IotDisco
The IoT Discovery URI Scheme (iotdisco)
Definition: Constants.cs:104
const string Xmpp
XMPP URI Scheme (xmpp)
Definition: Constants.cs:134
const string IotId
The IoT ID URI Scheme (iotid)
Definition: Constants.cs:99
const string EDaler
eDaler URI Scheme (edaler)
Definition: Constants.cs:119
A set of never changing property constants and helpful values.
Definition: Constants.cs:7
Base class that references services in the app.
Definition: ServiceRef.cs:31
static ILogService LogService
Log service.
Definition: ServiceRef.cs:91
static IStringLocalizer Localizer
Localization service
Definition: ServiceRef.cs:235
Static class containing SVG Paths for symbols used in the app.
Definition: Geometries.cs:11
static readonly Color UserColor
Default user icon color
Definition: Geometries.cs:256
static readonly Color EDalerColor
Default eDaler icon color
Definition: Geometries.cs:287
static readonly Geometry UserIconPath
User symbol for QR codes
Definition: Geometries.cs:261
static readonly Geometry OnboardingIconPath
Onboarding symbol for QR codes
Definition: Geometries.cs:276
static readonly Color OnboardingColor
Default onboarding icon color
Definition: Geometries.cs:271
static readonly Color TokenColor
Default token icon color
Definition: Geometries.cs:365
static readonly Geometry SignatureIconPath
Signature symbol for QR codes
Definition: Geometries.cs:321
static readonly Geometry EDalerIconPath
eDaler symbol for QR codes
Definition: Geometries.cs:292
static readonly Color Aes256Color
Default encrypted icon color
Definition: Geometries.cs:301
static readonly Color ContractColor
Default contract icon color
Definition: Geometries.cs:330
static readonly Geometry Aes256IconPath
Encrypted symbol for QR codes
Definition: Geometries.cs:306
static readonly Geometry ThingsIconPath
Things symbol for QR codes
Definition: Geometries.cs:352
static readonly Geometry ContractIconPath
Contract symbol for QR codes
Definition: Geometries.cs:335
static readonly Geometry TokenIconPath
Token symbol for QR codes
Definition: Geometries.cs:370
static readonly Color ThingsColor
Default things icon color
Definition: Geometries.cs:347
static readonly Color SignatureColor
Default signature icon color
Definition: Geometries.cs:316
A base class for all view models, inheriting from the BindableObject. NOTE: using this class requir...
The view model to bind to when scanning a QR code.
override Task GoBack()
Method called when user wants to navigate to the previous screen.
bool CanOpenManual
If the manual code can be opened
override async Task OnDispose()
Method called when the view is disposed, and will not be used more. Use this method to unregister eve...
string LocalizedQrPageTitle
The localized page title text to display.
override async Task OnInitialize()
Method called when view is initialized for the first time. Use this method to implement registration ...
bool HasAllowedSchemas
If scanning of codes is restricted to a set of allowed schemas.
Color IconBackgroundColor
Background color of displayed icon.
bool CanOpenScanned
If the scanned code can be opened
ScanQrCodeViewModel(ScanQrCodeNavigationArgs? Args)
The view model to bind to when scanning a QR code.
bool MultipleIcons
If the view shows more than one icon.
class UriSchemaIcon(Geometry Geometry, Color ForegroundColor, ScanQrCodeViewModel ParentViewModel)
Represents an icon for an URI schema.