Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ObservableRole.cs
1using System.Collections.ObjectModel;
2using System.Collections.Specialized;
3using System.ComponentModel;
4using CommunityToolkit.Mvvm.ComponentModel;
5using CommunityToolkit.Mvvm.Input;
15
17{
22 public partial class ObservableRole : ObservableObject
23 {
24 #region Constructor
25 public ObservableRole(Role role)
26 {
27 this.Role = role;
28 this.parts = new ObservableCollection<ObservablePart>();
29 }
30
31
32 #endregion
33
34 #region Initialization
40 public async Task InitializeAsync(Contract contract)
41 {
42 try
43 {
44 // Set the description based on the contract language
45 string UntrimmedDescription = await contract.ToPlainText(this.Role.Descriptions, contract.DeviceLanguage());
46 this.Description = UntrimmedDescription.Trim();
47
48 // Add the parts associated with the role
49 if (contract.Parts is null)
50 return;
51 foreach (Part Part in contract.Parts)
52 {
53 if (Part.Role == this.Name)
54 {
55 await this.AddPart(Part);
56 }
57 }
58 }
59 catch (Exception E)
60 {
61 ServiceRef.LogService.LogException(E);
62 }
63 }
64 #endregion
65
66
67 #region Properties
71 public Role Role { get; }
72
76 public ObservableCollection<ObservablePart> Parts
77 {
78 get => this.parts;
79 private set => this.SetProperty(ref this.parts, value);
80 }
81 private ObservableCollection<ObservablePart> parts;
82
86 public string Name => this.Role.Name;
87
92 public string Description
93 {
94 get => this.description;
95 private set
96 {
97 if (this.SetProperty(ref this.description, value))
98 {
99 this.OnPropertyChanged(nameof(this.Label));
100 }
101 }
102 }
103 private string description = string.Empty;
104
108 public string Label => string.IsNullOrEmpty(this.Description) ? this.Name : this.Description;
109
113 public int MaxCount => this.Role.MaxCount;
114
118 public int MinCount => this.Role.MinCount;
119
123 public bool HasReachedMaxCount => this.Parts.Count >= this.MaxCount;
124
128 public bool HasReachedMinCount => this.Parts.Count >= this.MinCount;
129
133 public bool CanSelectMe
134 {
135 get
136 {
137 string? MyId = ServiceRef.TagProfile.LegalIdentity?.Id;
138 bool AlreadySelected = !string.IsNullOrEmpty(MyId) && this.Parts.Any(p => p.LegalId == MyId);
139 return AlreadySelected || !this.HasReachedMaxCount;
140 }
141 }
142
147 public bool IsSelectedByMe
148 {
149 get
150 {
151 string? MyId = ServiceRef.TagProfile.LegalIdentity?.Id;
152 if (string.IsNullOrEmpty(MyId))
153 return false;
154 return this.Parts.Any(p => p.LegalId == MyId);
155 }
156 set
157 {
158 string? MyId = ServiceRef.TagProfile.LegalIdentity?.Id;
159 if (string.IsNullOrEmpty(MyId))
160 {
161 // No identity selected; ignore.
162 return;
163 }
164
165 bool CurrentlySelected = this.Parts.Any(p => p.LegalId == MyId);
166 if (value == CurrentlySelected)
167 return;
168
169 if (value)
170 {
171 if (this.Parts.Count >= this.MaxCount)
172 {
173 // Cannot add, would exceed max. Simply ignore.
174 return;
175 }
176 _ = this.AddPart(MyId, false);
177 }
178 else
179 {
180 this.RemovePart(MyId, false);
181 }
182
183 this.OnPropertyChanged();
184 }
185 }
186 #endregion
187
188 #region Methods
193 public async Task AddPart(string LegalId, bool Notify = true, bool AutoPetition = true, bool PresetFromArgs = false)
194 {
195 //Check if Part Exists
196 if (this.Parts.Any(p => string.Equals(p.LegalId, LegalId, StringComparison.OrdinalIgnoreCase)))
197 return;
198
199 //Create Part
200 Part Part = new() { LegalId = LegalId, Role = this.Name };
202 {
203 IsPresetFromArgs = PresetFromArgs
204 };
205 await ObservablePart.InitializeAsync(AutoPetition);
206
207 //Notify changes
208 TaskCompletionSource TaskCompletionSource = new();
209 MainThread.BeginInvokeOnMainThread(() =>
210 {
211 this.Parts.Add(ObservablePart);
212 this.OnPropertyChanged(nameof(this.HasReachedMaxCount));
213 this.OnPropertyChanged(nameof(this.HasReachedMinCount));
214 this.OnPropertyChanged(nameof(this.IsSelectedByMe));
215 if (Notify)
216 this.OnPropertyChanged(nameof(this.Parts));
217 TaskCompletionSource.SetResult();
218 });
219 await TaskCompletionSource.Task;
220 }
221
225 public async Task AddPart(Part part)
226 {
227 await this.AddPart(part.LegalId);
228 }
229
233 public async Task AddPart(ClientSignature signature)
234 {
235 await this.AddPart(signature.LegalId, true, false);
236 ObservablePart? Found = this.Parts.FirstOrDefault(p => p.LegalId == signature.LegalId);
237 if (Found is not null)
238 {
239 await MainThread.InvokeOnMainThreadAsync(() =>
240 {
241 Found.Signature = signature;
242 });
243 await Found.InitializeAsync(false);
244 }
245 }
246
250 public void RemovePart(string LegalId, bool Notify = true)
251 {
252 ObservablePart? Part = this.Parts.FirstOrDefault(p => p.LegalId == LegalId);
253 if (Part is not null)
254 {
255 MainThread.BeginInvokeOnMainThread(() =>
256 {
257 this.Parts.Remove(Part);
258 this.OnPropertyChanged(nameof(this.HasReachedMaxCount));
259 this.OnPropertyChanged(nameof(this.HasReachedMinCount));
260 this.OnPropertyChanged(nameof(this.IsSelectedByMe));
261 if (Notify)
262 this.OnPropertyChanged(nameof(this.Parts));
263 });
264 }
265 }
266
270 public void RemovePart(Part part)
271 {
272 this.RemovePart(part.LegalId);
273 }
274
275 [RelayCommand]
276 private void RemovePart(ObservablePart? part)
277 {
278 if (part is null)
279 return;
280 this.RemovePart(part.LegalId);
281
282 }
283 #endregion
284
285 #region Commands
286 [RelayCommand(AllowConcurrentExecutions = false)]
287 private async Task AddPartFromContacts()
288 {
289 IEnumerable<ContactInfo> Contacts = await Database.Find<ContactInfo>();
290 TaskCompletionSource<ContactInfoModel?> Selected = new();
292 {
293 CanScanQrCode = true,
294 Contacts = Contacts
295 };
296
298
299 ContactInfoModel? Contact = await Selected.Task;
300 if (Contact is null)
301 return;
302
303 string LegalId = Contact.LegalId;
304
305 await this.AddPart(LegalId);
306 }
307
308 [RelayCommand(AllowConcurrentExecutions = false)]
309 private async Task AddPartFromQr()
310 {
311 string? Code = await QrCode.ScanQrCode(nameof(AppResources.ScanQRCode), [Constants.UriSchemes.IotId]);
312 if (string.IsNullOrEmpty(Code))
313 return;
314
315 string LegalId = Constants.UriSchemes.RemoveScheme(Code) ?? string.Empty;
316
317 await this.AddPart(LegalId);
318 }
319 #endregion
320 }
321}
static ? string RemoveScheme(string Url)
Removes the URI Schema from an URL.
Definition: Constants.cs:272
const string IotId
The IoT ID URI Scheme (iotid)
Definition: Constants.cs:153
A set of never changing property constants and helpful values.
Definition: Constants.cs:24
A strongly-typed resource class, for looking up localized strings, etc.
static string ScanQRCode
Looks up a localized string similar to Scan QR Code.
static string AddContactToContract
Looks up a localized string similar to Add Contact to Contract.
Contains information about a contact.
Definition: ContactInfo.cs:22
Base class that references services in the app.
Definition: ServiceRef.cs:43
static ILogService LogService
Log service.
Definition: ServiceRef.cs:214
static INavigationService NavigationService
The navigation service for navigating between pages.
Definition: ServiceRef.cs:178
static ITagProfile TagProfile
TAG Profile service.
Definition: ServiceRef.cs:202
static IReportingStringLocalizer Localizer
Localization service
Definition: ServiceRef.cs:370
Helper class to perform scanning of QR Codes by displaying the UI and handling async results.
Definition: QrCode.cs:20
static async Task< string?> ScanQrCode(string? QrTitle, string[] AllowedSchemas)
Navigates to the Scan QR Code Page, waits for scan to complete, and returns the result....
Definition: QrCode.cs:191
Contact Information model, including related notification information.
CaseInsensitiveString? LegalId
Legal ID of contact.
Holds navigation parameters specific to views displaying a list of contacts.
A page that displays a list of the current user's contacts.
async Task InitializeAsync(bool sendPetition=true)
Initializes the part, setting properties which needs to be set asynchronosly
An observable object that wraps a Waher.Networking.XMPP.Contracts.Role object. This allows for easier...
ObservableCollection< ObservablePart > Parts
The parts associated with the role
async Task AddPart(Part part)
Adds a part object to the role.
bool HasReachedMaxCount
If the role has reached the maximum amount of parts.
async Task AddPart(string LegalId, bool Notify=true, bool AutoPetition=true, bool PresetFromArgs=false)
Adds a part with a given LegalId to the role.
bool HasReachedMinCount
If the role has reached the minimum amount of parts.
int MinCount
Smallest amount of signatures of this role required for a legally binding contract.
bool IsSelectedByMe
If current user has selected to sign as this role. Toggling this will add/remove "Me" as a part,...
async Task InitializeAsync(Contract contract)
Initializes the role in regards to a contract. E.g Sets the description of the role,...
int MaxCount
Largest amount of signatures of this role required for a legally binding contract.
void RemovePart(string LegalId, bool Notify=true)
Removes a part with a given LegalId from the role.
string Description
The localized description of the role Has to be initialized with InitializeAsync
string Label
Label to display in the UI, defaults to Name if Description is not set.
async Task AddPart(ClientSignature signature)
Add a part from a signature, or mark the part as signed if it already exists.
void RemovePart(Part part)
Removes a part object from the role.
bool CanSelectMe
True if user can select themselves for this role (not at max or already selected).
Represents a digital signature on a contract.
string LegalId
ID of legal identity signing the contract.
Contains the definition of a contract
Definition: Contract.cs:22
Task< string > ToPlainText(string Language)
Creates a human-readable Plain Trext document for the contract.
Definition: Contract.cs:2081
Part[] Parts
Defined parts for the smart contract.
Definition: Contract.cs:258
HumanReadableText[] Descriptions
Discriptions of the object, in different languages.
Class defining a part in a contract
Definition: Part.cs:30
string LegalId
Legal identity of part
Definition: Part.cs:38
string Role
Role of the part in the contract
Definition: Part.cs:57
Class defining a role
Definition: Role.cs:7
int MaxCount
Largest amount of signatures of this role required for a legally binding contract.
Definition: Role.cs:35
int MinCount
Smallest amount of signatures of this role required for a legally binding contract.
Definition: Role.cs:26
string Name
Name of the role.
Definition: Role.cs:17
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:21
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
Definition: Database.cs:238
Task GoToAsync(string Route)
Navigates to the specified route and pushes the page onto the navigation stack.
Definition: ImplTypes.g.cs:58
BackMethod
Navigation Back Method
Definition: BackMethod.cs:7