// Copyright (c) Arlo Godfrey. All Rights Reserved. // Licensed under the GNU Lesser General Public License, Version 3.0 with additional terms. // See the LICENSE, LICENSE.LESSER and LICENSE.ADDITIONAL files in the project root for more information. using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.Threading; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using OwlCore.Events; using OwlCore.Extensions; using StrixMusic.Sdk.AdapterModels; using StrixMusic.Sdk.AppModels; using StrixMusic.Sdk.CoreModels; using StrixMusic.Sdk.ViewModels.Helpers; namespace StrixMusic.Sdk.ViewModels { /// /// A ViewModel for . /// public class UserProfileViewModel : ObservableObject, ISdkViewModel, IUserProfile, IImageCollectionViewModel, IUrlCollectionViewModel { private readonly IUserProfile _userProfile; private readonly IReadOnlyList _sources; private readonly SynchronizationContext _syncContext; /// /// Initializes a new instance of the class. /// /// The base public UserProfileViewModel(IUserProfile userProfile) { _syncContext = SynchronizationContext.Current; _userProfile = userProfile ?? throw new ArgumentNullException(nameof(userProfile)); var userProfileImpl = userProfile.Cast(); _sources = userProfileImpl.Sources; PopulateMoreImagesCommand = new AsyncRelayCommand(PopulateMoreImagesAsync); PopulateMoreUrlsCommand = new AsyncRelayCommand(PopulateMoreUrlsAsync); InitImageCollectionAsyncCommand = new AsyncRelayCommand(InitImageCollectionAsync); Images = new ObservableCollection(); Urls = new ObservableCollection(); } /// public Task InitAsync(CancellationToken cancellationToken = default) { if (IsInitialized) return Task.CompletedTask; IsInitialized = true; return InitImageCollectionAsync(cancellationToken); } /// public event EventHandler? SourcesChanged { add => _userProfile.SourcesChanged += value; remove => _userProfile.SourcesChanged -= value; } /// public event EventHandler? DisplayNameChanged { add => _userProfile.DisplayNameChanged += value; remove => _userProfile.DisplayNameChanged -= value; } /// public event EventHandler? BirthDateChanged { add => _userProfile.BirthDateChanged += value; remove => _userProfile.BirthDateChanged -= value; } /// public event EventHandler? FullNameChanged { add => _userProfile.FullNameChanged += value; remove => _userProfile.FullNameChanged -= value; } /// public event EventHandler? RegionChanged { add => _userProfile.RegionChanged += value; remove => _userProfile.RegionChanged -= value; } /// public event EventHandler? EmailChanged { add => _userProfile.EmailChanged += value; remove => _userProfile.EmailChanged -= value; } /// public event EventHandler? ImagesCountChanged { add => _userProfile.ImagesCountChanged += value; remove => _userProfile.ImagesCountChanged -= value; } /// public event CollectionChangedEventHandler? ImagesChanged { add => _userProfile.ImagesChanged += value; remove => _userProfile.ImagesChanged -= value; } /// public event EventHandler? UrlsCountChanged { add => _userProfile.UrlsCountChanged += value; remove => _userProfile.UrlsCountChanged -= value; } /// public event CollectionChangedEventHandler? UrlsChanged { add => _userProfile.UrlsChanged += value; remove => _userProfile.UrlsChanged -= value; } /// IReadOnlyList IMerged.Sources => _sources; /// IReadOnlyList IMerged.Sources => _sources; /// public string Id => _userProfile.Id; /// public int TotalImageCount => _userProfile.TotalImageCount; /// public int TotalUrlCount => _userProfile.TotalUrlCount; /// public string DisplayName => _userProfile.DisplayName; /// public string? FullName => _userProfile.FullName; /// public string? Email => _userProfile.Email; /// public DateTime? Birthdate => _userProfile.Birthdate; /// public bool IsInitialized { get; private set; } /// public ObservableCollection Images { get; } /// public ObservableCollection Urls { get; } /// public CultureInfo Region => _userProfile.Region; /// public bool IsChangeDisplayNameAvailable => _userProfile.IsChangeDisplayNameAvailable; /// public bool IsChangeBirthDateAsyncAvailable => _userProfile.IsChangeBirthDateAsyncAvailable; /// public bool IsChangeFullNameAsyncAsyncAvailable => _userProfile.IsChangeFullNameAsyncAsyncAvailable; /// public bool IsChangeRegionAsyncAvailable => _userProfile.IsChangeRegionAsyncAvailable; /// public bool IsChangeEmailAsyncAvailable => _userProfile.IsChangeEmailAsyncAvailable; /// public Task IsAddUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => _userProfile.IsAddUrlAvailableAsync(index, cancellationToken); /// public Task IsAddImageAvailableAsync(int index, CancellationToken cancellationToken = default) => _userProfile.IsAddImageAvailableAsync(index, cancellationToken); /// public Task IsRemoveImageAvailableAsync(int index, CancellationToken cancellationToken = default) => _userProfile.IsRemoveImageAvailableAsync(index, cancellationToken); /// public Task IsRemoveUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => _userProfile.IsRemoveUrlAvailableAsync(index, cancellationToken); /// public Task ChangeDisplayNameAsync(string displayName, CancellationToken cancellationToken = default) => _userProfile.ChangeDisplayNameAsync(displayName, cancellationToken); /// public Task ChangeBirthDateAsync(DateTime birthdate, CancellationToken cancellationToken = default) => _userProfile.ChangeBirthDateAsync(birthdate, cancellationToken); /// public Task ChangeFullNameAsync(string fullname, CancellationToken cancellationToken = default) => _userProfile.ChangeFullNameAsync(fullname, cancellationToken); /// public Task ChangeRegionAsync(CultureInfo region, CancellationToken cancellationToken = default) => _userProfile.ChangeRegionAsync(region, cancellationToken); /// public Task ChangeEmailAsync(string? email, CancellationToken cancellationToken = default) => _userProfile.ChangeEmailAsync(email, cancellationToken); /// public IAsyncEnumerable GetImagesAsync(int limit, int offset, CancellationToken cancellationToken = default) => _userProfile.GetImagesAsync(limit, offset, cancellationToken); /// public IAsyncEnumerable GetUrlsAsync(int limit, int offset, CancellationToken cancellationToken = default) => _userProfile.GetUrlsAsync(limit, offset, cancellationToken); /// public Task RemoveImageAsync(int index, CancellationToken cancellationToken = default) => _userProfile.RemoveImageAsync(index, cancellationToken); /// public Task AddImageAsync(IImage image, int index, CancellationToken cancellationToken = default) => _userProfile.AddImageAsync(image, index, cancellationToken); /// public Task AddUrlAsync(IUrl url, int index, CancellationToken cancellationToken = default) => _userProfile.AddUrlAsync(url, index, cancellationToken); /// public Task RemoveUrlAsync(int index, CancellationToken cancellationToken = default) => _userProfile.RemoveUrlAsync(index, cancellationToken); /// public async Task PopulateMoreImagesAsync(int limit, CancellationToken cancellationToken = default) { _syncContext.Post(async _ => { await foreach (var item in GetImagesAsync(limit, Images.Count, cancellationToken)) Images.Add(item); }, null); } /// public async Task PopulateMoreUrlsAsync(int limit, CancellationToken cancellationToken = default) { _syncContext.Post(async _ => { await foreach (var item in GetUrlsAsync(limit, Urls.Count, cancellationToken)) Urls.Add(item); }, null); } /// public Task InitImageCollectionAsync(CancellationToken cancellationToken = default) => CollectionInit.ImageCollection(this, cancellationToken); /// public IAsyncRelayCommand InitImageCollectionAsyncCommand { get; } /// public IAsyncRelayCommand PopulateMoreImagesCommand { get; } /// public IAsyncRelayCommand PopulateMoreUrlsCommand { get; } /// public bool Equals(ICoreImageCollection other) => _userProfile.Equals(other); /// public bool Equals(ICoreUrlCollection other) => _userProfile.Equals(other); /// public ValueTask DisposeAsync() => _userProfile.DisposeAsync(); } }