1using System.ComponentModel;
2using System.Globalization;
3using CommunityToolkit.Mvvm.ComponentModel;
24 public partial class MyThingsViewModel(MyThingsNavigationArgs? Args)
27 private readonly Dictionary<CaseInsensitiveString, List<ContactInfoModel>> byBareJid = [];
28 private TaskCompletionSource<ContactInfoModel?>? result = Args?.ThingToShare;
31 public override async Task OnInitializeAsync()
35 ServiceRef.XmppService.OnPresence += this.Xmpp_OnPresence;
36 ServiceRef.NotificationService.OnNewNotification += this.NotificationService_OnNewNotification;
37 ServiceRef.NotificationService.OnNotificationsDeleted += this.NotificationService_OnNotificationsDeleted;
41 public override async Task OnAppearingAsync()
43 await base.OnAppearingAsync();
44 this.SelectedThing =
null;
46 if (this.result is not
null && this.result.Task.IsCompleted)
52 await this.LoadThings();
56 private async Task LoadThings()
58 SortedDictionary<string, ContactInfo> SortedByName = [];
59 SortedDictionary<string, ContactInfo> SortedByAddress = [];
68 if (SortedByName.ContainsKey(Name))
74 Suffix =
" " + (++i).
ToString(CultureInfo.InvariantCulture);
76 while (SortedByName.ContainsKey(Name + Suffix));
78 SortedByName[Name + Suffix] = Info;
81 SortedByName[Name] = Info;
83 Key = Info.BareJid +
", " + Info.SourceId +
", " + Info.Partition +
", " + Info.
NodeId;
84 SortedByAddress[Key] = Info;
90 Property[] MetaData = ViewClaimThing.ViewClaimThingViewModel.ToProperties(Thing.
Tags);
92 Key = Thing.Jid +
", " + Thing.Node.SourceId +
", " + Thing.Node.Partition +
", " + Thing.
Node.NodeId;
93 if (SortedByAddress.TryGetValue(Key, out
ContactInfo? Info))
95 if (!Info.Owner.HasValue || !Info.Owner.Value || !AreSame(Info.MetaData, MetaData))
98 Info.MetaData = MetaData;
99 Info.FriendlyName = ViewClaimThing.ViewClaimThingViewModel.GetFriendlyName(MetaData) ??
string.Empty;
110 LegalId =
string.Empty,
112 FriendlyName = ViewClaimThing.ViewClaimThingViewModel.GetFriendlyName(Thing.
Tags) ??
string.Empty,
114 SourceId = Thing.
Node.SourceId,
115 Partition = Thing.
Node.Partition,
116 NodeId = Thing.
Node.NodeId,
119 RegistryJid = ServiceRef.XmppService.RegistryServiceJid
124 if (Tag.
Name.Equals(
"R", StringComparison.OrdinalIgnoreCase))
130 Name = Info.FriendlyName;
131 if (SortedByName.ContainsKey(Name))
137 Suffix =
" " + (++i).
ToString(CultureInfo.InvariantCulture);
139 while (SortedByName.ContainsKey(Name + Suffix));
141 SortedByName[Name + Suffix] = Info;
144 SortedByName[Name] = Info;
146 SortedByAddress[Key] = Info;
151 this.byBareJid.Clear();
153 ObservableItemGroup<IUniqueItem> NewThings =
new(nameof(this.Things), []);
160 NewThings.Add(InfoModel);
162 if (!this.byBareJid.TryGetValue(Info.
BareJid, out List<ContactInfoModel>? Contacts))
165 this.byBareJid[Info.
BareJid] = Contacts;
168 Contacts.Add(InfoModel);
171 this.ShowThingsMissing = SortedByName.Count == 0;
173 MainThread.BeginInvokeOnMainThread(() => ObservableItemGroup<IUniqueItem>.UpdateGroupsItems(this.Things, NewThings));
184 if (!
string.IsNullOrEmpty(Thing.
SourceId) ||
185 !
string.IsNullOrEmpty(Thing.
Partition) ||
186 !
string.IsNullOrEmpty(Thing.
NodeId) ||
189 ContactEvents =
null;
195 return ThingEvents is
null ? ContactEvents : (ContactEvents?.Join(ThingEvents) ?? ThingEvents);
199 public override async Task OnDisposeAsync()
201 ServiceRef.XmppService.OnPresence -= this.Xmpp_OnPresence;
202 ServiceRef.NotificationService.OnNewNotification -= this.NotificationService_OnNewNotification;
203 ServiceRef.NotificationService.OnNotificationsDeleted -= this.NotificationService_OnNotificationsDeleted;
205 this.ShowThingsMissing =
false;
208 this.result?.TrySetResult(
null);
210 await base.OnDisposeAsync();
221 if ((MetaData1 is
null) ^ (MetaData2 is
null))
224 if (MetaData1 is
null || MetaData2 is
null)
227 int i, c = MetaData1.Length;
228 if (MetaData2.Length != c)
231 for (i = 0; i < c; i++)
233 if ((MetaData1[i].Name != MetaData2[i].Name) || (MetaData1[i].Value != MetaData2[i].Value))
244 private bool showThingsMissing;
249 public ObservableItemGroup<IUniqueItem> Things {
get; } =
new(nameof(Things), []);
257 protected override void OnPropertyChanged(PropertyChangedEventArgs e)
261 switch (e.PropertyName)
263 case nameof(this.SelectedThing):
264 if (this.SelectedThing is not null)
265 this.OnSelected(this.SelectedThing);
275 MainThread.BeginInvokeOnMainThread(async () =>
277 if (this.result is
null)
284 this.result.TrySetResult(Thing);
292 if (this.byBareJid.TryGetValue(e.
FromBareJID, out List<ContactInfoModel>? Contacts))
298 return Task.CompletedTask;
303 MainThread.BeginInvokeOnMainThread(() =>
309 case NotificationEventType.Contacts:
310 foreach (IUniqueItem Item in this.Things)
312 if (Item is ContactInfoModel Thing)
315 if (!string.IsNullOrEmpty(Thing.NodeId) ||
316 !string.IsNullOrEmpty(Thing.SourceId) ||
317 !string.IsNullOrEmpty(Thing.Partition))
322 if (Event.Category != Thing.BareJid)
325 Thing.RemoveEvent(Event);
330 case NotificationEventType.Things:
331 foreach (IUniqueItem Item in this.Things)
333 if (Item is ContactInfoModel Thing)
336 if (Event.Category != ContactInfo.GetThingNotificationCategoryKey(Thing.BareJid, Thing.NodeId, Thing.SourceId, Thing.Partition))
339 Thing.RemoveEvent(Event);
350 return Task.CompletedTask;
355 MainThread.BeginInvokeOnMainThread(() =>
359 switch (e.Event.Type)
361 case NotificationEventType.Contacts:
362 foreach (IUniqueItem Item in this.Things)
364 if (Item is ContactInfoModel Thing)
366 if (!string.IsNullOrEmpty(Thing.NodeId) ||
367 !string.IsNullOrEmpty(Thing.SourceId) ||
368 !string.IsNullOrEmpty(Thing.Partition))
373 if (e.Event.Category != Thing.BareJid)
376 Thing.AddEvent(e.Event);
389 Thing.AddEvent(e.Event);
404 return Task.CompletedTask;
Base class that references services in the app.
static ILogService LogService
Log service.
static INavigationService NavigationService
The navigation service for navigating between pages.
static INotificationService NotificationService
Service for managing notifications for the user.
static IXmppService XmppService
The XMPP service for XMPP communication.
A base class for all view models, inheriting from the BindableObject. NOTE: using this class requir...
virtual async Task OnInitializeAsync()
Method called when view is initialized for the first time. Use this method to implement registration ...
Contact Information model, including related notification information.
NotificationEvent[] Events
Notification events.
void PresenceUpdated()
Method called when presence for contact has been updated.
ContactInfo? Contact
Contact Information object in database.
void OnPropertyChanged(string PropertyName)
Called when a property has changed.
Holds navigation parameters specific to viewing things.
A page that displays information about a thing and allows the user to interact with it.
Event arguments for presence events.
string FromBareJID
Bare JID of resource sending the presence.
Contains information about a thing in a search result.
MetaDataTag[] Tags
Meta-data tags.
ThingReference Node
Node reference. Can be equal to ThingReference.Empty if not behind a concentrator.
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 Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
This filter selects objects that have a named field equal to a given value.
bool TryGetNotificationEvents(NotificationEventType Type, CaseInsensitiveString Category, [NotNullWhen(true)] out NotificationEvent[]? Events)
Tries to get available notification events.
Task GoToAsync(string Route)
Navigates to the specified route and pushes the page onto the navigation stack.
Task Flush()
Persists any pending changes.
abstract class NotificationEvent()
Abstract base class of notification events.
class NotificationEventsArgs(NotificationEvent[] Events)
Event argument for notification events.
class NotificationEventArgs(NotificationEvent Event)
Event argument for notification events.
NotificationEventType
Button on which event is to be displayed.
BackMethod
Navigation Back Method
delegate string ToString(IElement Element)
Delegate for callback methods that convert an element value to a string.