diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Database/AdvancedDbCollectionView.cs b/src/Snap.Hutao/Snap.Hutao/Core/Database/AdvancedDbCollectionView.cs index 7b03141f..1ebcc02b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Database/AdvancedDbCollectionView.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Database/AdvancedDbCollectionView.cs @@ -1,6 +1,7 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using CommunityToolkit.Mvvm.Messaging; using Microsoft.EntityFrameworkCore; using Snap.Hutao.Core.Database.Abstraction; using Snap.Hutao.Model; @@ -52,6 +53,10 @@ internal sealed class AdvancedDbCollectionView : AdvancedCollectionView dbContext.Set().UpdateAndSave(currentItem); } } + + serviceProvider + .GetRequiredService() + .Send(new AdvancedDbCollectionViewCurrentChangedMessage(currentItem)); } } @@ -100,5 +105,9 @@ internal sealed class AdvancedDbCollectionView : Advance dbContext.Set().UpdateAndSave(currentItem.Entity); } } + + serviceProvider + .GetRequiredService() + .Send(new AdvancedDbCollectionViewCurrentChangedMessage(currentItem)); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Database/AdvancedDbCollectionViewCurrentChangedMessage.cs b/src/Snap.Hutao/Snap.Hutao/Core/Database/AdvancedDbCollectionViewCurrentChangedMessage.cs new file mode 100644 index 00000000..3a2eca12 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Core/Database/AdvancedDbCollectionViewCurrentChangedMessage.cs @@ -0,0 +1,15 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Core.Database; + +internal sealed class AdvancedDbCollectionViewCurrentChangedMessage + where TItem : class +{ + public AdvancedDbCollectionViewCurrentChangedMessage(TItem? currentItem) + { + CurrentItem = currentItem; + } + + public TItem? CurrentItem { get; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/DependencyInjection.cs b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/DependencyInjection.cs index ee49a41f..c226c003 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/DependencyInjection.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/DependencyInjection.cs @@ -44,7 +44,7 @@ internal static class DependencyInjection .AddConfiguredHttpClients() // Discrete services - .AddSingleton() + .AddSingleton() .BuildServiceProvider(true); Ioc.Default.ConfigureServices(serviceProvider); diff --git a/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Proxy/HttpProxyUsingSystemProxy.cs b/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Proxy/HttpProxyUsingSystemProxy.cs index 3ee4700d..78331d22 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Proxy/HttpProxyUsingSystemProxy.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Proxy/HttpProxyUsingSystemProxy.cs @@ -26,7 +26,7 @@ internal sealed partial class HttpProxyUsingSystemProxy : ObservableObject, IWeb UpdateInnerProxy(); watcher = new(ProxySettingPath, OnSystemProxySettingsChanged); - watcher.Start(); + watcher.Start(serviceProvider.GetRequiredService>()); } public string CurrentProxyUri diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Threading/TaskExtension.cs b/src/Snap.Hutao/Snap.Hutao/Core/Threading/TaskExtension.cs index 10dc53a5..6ae3f2b0 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Threading/TaskExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Threading/TaskExtension.cs @@ -24,7 +24,9 @@ internal static class TaskExtension return new(task); } +#if NET9_0_OR_GREATER [Obsolete("SafeForget without logger is not recommended.")] +#endif public static async void SafeForget(this Task task) { try @@ -101,7 +103,9 @@ internal static class TaskExtension } } +#if NET9_0_OR_GREATER [Obsolete("SafeForget without logger is not recommended.")] +#endif public static async void SafeForget(this ValueTask task) { try diff --git a/src/Snap.Hutao/Snap.Hutao/Message/BackgroundImageTypeChangedMessage.cs b/src/Snap.Hutao/Snap.Hutao/Message/BackgroundImageTypeChangedMessage.cs deleted file mode 100644 index ea98e6ad..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Message/BackgroundImageTypeChangedMessage.cs +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Message; - -[Obsolete] -internal sealed class BackgroundImageTypeChangedMessage; \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Message/CultivateProjectChangedMessage.cs b/src/Snap.Hutao/Snap.Hutao/Message/CultivateProjectChangedMessage.cs deleted file mode 100644 index 2b6b3a16..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Message/CultivateProjectChangedMessage.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Snap.Hutao.Model.Entity; - -namespace Snap.Hutao.Message; - -/// -/// 养成计划切换消息 -/// -[HighQuality] -[Obsolete] -internal sealed class CultivateProjectChangedMessage : ValueChangedMessage -{ -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Message/GachaArchiveChangedMessage.cs b/src/Snap.Hutao/Snap.Hutao/Message/GachaArchiveChangedMessage.cs deleted file mode 100644 index 4db35e48..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Message/GachaArchiveChangedMessage.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Snap.Hutao.Model.Entity; - -namespace Snap.Hutao.Message; - -/// -/// 祈愿记录存档切换消息 -/// -[HighQuality] -[Obsolete] -internal sealed class GachaArchiveChangedMessage : ValueChangedMessage -{ -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Message/UserChangeFlag.cs b/src/Snap.Hutao/Snap.Hutao/Message/UserChangeFlag.cs deleted file mode 100644 index 0023c396..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Message/UserChangeFlag.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Message; - -internal enum UserChangeFlag -{ - // This flag is impossible to appear alone - UserChanged = 0b0001, - RoleChanged = 0b0010, - UserAndRoleChanged = UserChanged | RoleChanged, -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Message/UserChangedMessage.cs b/src/Snap.Hutao/Snap.Hutao/Message/UserChangedMessage.cs deleted file mode 100644 index d60f9642..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Message/UserChangedMessage.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Snap.Hutao.ViewModel.User; -using System.Diagnostics; -using System.Text; - -namespace Snap.Hutao.Message; - -/// -/// 用户切换消息 -/// -[HighQuality] -[DebuggerDisplay("{DebuggerDisplay(),nq}")] -[Obsolete] -internal sealed class UserChangedMessage : ValueChangedMessage -{ - // defaults to the UserAndRoleChanged when we raise this message in ScopedDbCurrent - public UserChangeFlag Flag { get; private set; } = UserChangeFlag.UserAndRoleChanged; - - public bool IsOnlyRoleChanged { get => Flag == UserChangeFlag.RoleChanged; } - - public static UserChangedMessage Create(User oldValue, User newValue, UserChangeFlag flag) - { - return new UserChangedMessage - { - OldValue = oldValue, - NewValue = newValue, - Flag = flag, - }; - } - - public static UserChangedMessage CreateOnlyRoleChanged(User value) - { - return Create(value, value, UserChangeFlag.RoleChanged); - } - -#if DEBUG - private string DebuggerDisplay() - { - StringBuilder stringBuilder = new(); - stringBuilder - .Append("Name:") - .Append(OldValue?.UserInfo?.Nickname) - .Append("|Role[") - .Append(OldValue?.UserGameRoles?.Count) - .Append("]:<") - .Append(OldValue?.SelectedUserGameRole) - .Append("> -> Name:") - .Append(NewValue?.UserInfo?.Nickname) - .Append("|Role[") - .Append(NewValue?.UserGameRoles?.Count) - .Append("]:<") - .Append(NewValue?.SelectedUserGameRole) - .Append('>'); - - return stringBuilder.ToString(); - } -#endif -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Message/UserRemovedMessage.cs b/src/Snap.Hutao/Snap.Hutao/Message/UserRemovedMessage.cs deleted file mode 100644 index aac75468..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Message/UserRemovedMessage.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Snap.Hutao.Model.Entity; - -namespace Snap.Hutao.Message; - -/// -/// 用户删除消息 -/// -[HighQuality] -[Obsolete] -internal sealed class UserRemovedMessage -{ - /// - /// 构造一个新的用户删除消息 - /// - /// 用户 - public UserRemovedMessage(User user) - { - RemovedUserId = user.InnerId; - } - - /// - /// 删除的用户Id - /// - public Guid RemovedUserId { get; } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Message/ValueChangedMessage.cs b/src/Snap.Hutao/Snap.Hutao/Message/ValueChangedMessage.cs deleted file mode 100644 index e962e631..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Message/ValueChangedMessage.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Message; - -/// -/// 值变化消息 -/// -/// 值的类型 -[HighQuality] -[Obsolete] -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] -internal abstract class ValueChangedMessage - where TValue : class -{ - /// - /// 动态访问 - /// - public ValueChangedMessage() - { - } - - /// - /// 构造一个新的值变化消息 - /// - /// 旧值 - /// 新值 - protected ValueChangedMessage(TValue? oldValue, TValue? newValue) - { - OldValue = oldValue; - NewValue = newValue; - } - - /// - /// 旧的值 - /// - public TValue? OldValue { get; set; } - - /// - /// 新的值 - /// - public TValue? NewValue { get; set; } - - public Guid UniqueMessageId { get; } = Guid.NewGuid(); -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs index b52e88bf..0893ad3b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs @@ -64,24 +64,15 @@ internal sealed partial class AchievementDbService : IAchievementDbService } } - public async ValueTask OverwriteAchievementAsync(EntityAchievement achievement, CancellationToken token = default) - { - await this.DeleteByInnerIdAsync(achievement, token).ConfigureAwait(false); - if (achievement.Status >= Model.Intrinsic.AchievementStatus.STATUS_FINISHED) - { - await this.AddAsync(achievement, token).ConfigureAwait(false); - } - } - public ObservableCollection GetAchievementArchiveCollection() { return this.ObservableCollection(); } - public async ValueTask RemoveAchievementArchiveAsync(AchievementArchive archive, CancellationToken token = default) + public void RemoveAchievementArchive(AchievementArchive archive) { // It will cascade delete the achievements. - await this.DeleteAsync(archive, token).ConfigureAwait(false); + this.Delete(archive); } public List GetAchievementListByArchiveId(Guid archiveId) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs index 0f19858e..fb465b14 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs @@ -77,7 +77,7 @@ internal sealed partial class AchievementService : IAchievementService // Sync database await taskContext.SwitchToBackgroundAsync(); - await achievementDbService.RemoveAchievementArchiveAsync(archive).ConfigureAwait(false); + achievementDbService.RemoveAchievementArchive(archive); } public async ValueTask ImportFromUIAFAsync(AchievementArchive archive, List list, ImportStrategyKind strategy) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs index 45755d9d..0be00207 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs @@ -10,8 +10,6 @@ namespace Snap.Hutao.Service.Achievement; internal interface IAchievementDbService : IAppDbService, IAppDbService { - ValueTask RemoveAchievementArchiveAsync(Model.Entity.AchievementArchive archive, CancellationToken token = default); - ObservableCollection GetAchievementArchiveCollection(); List GetAchievementArchiveList(); @@ -30,5 +28,5 @@ internal interface IAchievementDbService : IAppDbService -/// 实时便笺服务 -/// -[HighQuality] [ConstructorGenerated] [Injection(InjectAs.Singleton, typeof(IDailyNoteService))] -internal sealed partial class DailyNoteService : IDailyNoteService, IRecipient +internal sealed partial class DailyNoteService : IDailyNoteService { private readonly DailyNoteNotificationOperation dailyNoteNotificationOperation; private readonly IServiceProvider serviceProvider; @@ -176,4 +170,4 @@ internal sealed partial class DailyNoteService : IDailyNoteService, IRecipient> GetUserAndUidCollectionAsync(); - ValueTask> GetUserCollectionAsync(); + ValueTask> GetUserCollectionAsync(); UserGameRole? GetUserGameRoleByUid(string uid); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/User/IUserService.cs b/src/Snap.Hutao/Snap.Hutao/Service/User/IUserService.cs index 8c9fe4d9..a5488eea 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/User/IUserService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/User/IUserService.cs @@ -2,56 +2,20 @@ // Licensed under the MIT license. using Snap.Hutao.Core.Database; -using Snap.Hutao.ViewModel.User; using Snap.Hutao.Web.Hoyolab.Takumi.Binding; -using System.Collections.ObjectModel; using BindingUser = Snap.Hutao.ViewModel.User.User; using EntityUser = Snap.Hutao.Model.Entity.User; namespace Snap.Hutao.Service.User; -/// -/// 用户服务 -/// -[HighQuality] internal interface IUserService { - /// - /// 获取或设置当前用户 - /// - BindingUser? Current { get; set; } - - /// - /// 异步获取角色与用户集合 - /// - /// 角色与用户集合 - ValueTask> GetRoleCollectionAsync(); - - /// - /// 初始化用户服务及所有用户 - /// 异步获取同步的用户信息集合 - /// 对集合的操作应通过服务抽象完成 - /// 此操作不能取消 - /// - /// 准备完成的用户信息集合 - ValueTask> GetUserCollectionAsync(); - - /// - /// 获取角色信息 - /// - /// uid - /// 对应的角色信息 - UserGameRole? GetUserGameRoleByUid(string uid); + ValueTask> GetUserCollectionAsync(); ValueTask> ProcessInputCookieAsync(InputCookie inputCookie); - ValueTask RefreshCookieTokenAsync(Model.Entity.User user); + ValueTask RefreshCookieTokenAsync(EntityUser user); - /// - /// 异步移除用户 - /// - /// 待移除的用户 - /// 任务 ValueTask RemoveUserAsync(BindingUser user); ValueTask RefreshProfilePictureAsync(UserGameRole userGameRole); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/User/IUserServiceUnsafe.cs b/src/Snap.Hutao/Snap.Hutao/Service/User/IUserServiceUnsafe.cs index 6ba659b6..21990a8e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/User/IUserServiceUnsafe.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/User/IUserServiceUnsafe.cs @@ -5,5 +5,5 @@ namespace Snap.Hutao.Service.User; internal interface IUserServiceUnsafe { - ValueTask UnsafeRemoveUsersAsync(); + ValueTask UnsafeRemoveAllUsersAsync(); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/User/UserCollectionService.cs b/src/Snap.Hutao/Snap.Hutao/Service/User/UserCollectionService.cs index aba08378..635ce40c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/User/UserCollectionService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/User/UserCollectionService.cs @@ -3,7 +3,6 @@ using CommunityToolkit.Mvvm.Messaging; using Snap.Hutao.Core.Database; -using Snap.Hutao.Message; using Snap.Hutao.ViewModel.User; using Snap.Hutao.Web.Hoyolab.Takumi.Binding; using System.Collections.ObjectModel; @@ -16,7 +15,6 @@ namespace Snap.Hutao.Service.User; [Injection(InjectAs.Singleton, typeof(IUserCollectionService))] internal sealed partial class UserCollectionService : IUserCollectionService, IDisposable { - private readonly ScopedDbCurrent dbCurrent; private readonly IUserInitializationService userInitializationService; private readonly IServiceProvider serviceProvider; private readonly IUserDbService userDbService; @@ -25,37 +23,21 @@ internal sealed partial class UserCollectionService : IUserCollectionService, ID private readonly SemaphoreSlim throttler = new(1); - private ObservableReorderableDbCollection? userCollection; - private Dictionary? midUserMap; + private AdvancedDbCollectionView? users; - private ObservableCollection? userAndUidCollection; - private Dictionary? uidUserGameRoleMap; - - public BindingUser? CurrentUser - { - get => dbCurrent.Current; - set => dbCurrent.Current = value; - } - - public async ValueTask> GetUserCollectionAsync() + public async ValueTask> GetUserCollectionAsync() { // Force run in background thread, otherwise will cause reentrance await taskContext.SwitchToBackgroundAsync(); using (await throttler.EnterAsync().ConfigureAwait(false)) { - if (userCollection is null) + if (users is null) { List entities = await userDbService.GetUserListAsync().ConfigureAwait(false); List users = await entities.SelectListAsync(userInitializationService.ResumeUserAsync).ConfigureAwait(false); - midUserMap = []; foreach (BindingUser user in users) { - if (user.Entity.Mid is not null) - { - midUserMap[user.Entity.Mid] = user; - } - if (user.NeedDbUpdateAfterResume) { await userDbService.UpdateUserAsync(user.Entity).ConfigureAwait(false); @@ -63,25 +45,12 @@ internal sealed partial class UserCollectionService : IUserCollectionService, ID } } - userCollection = users.ToObservableReorderableDbCollection(serviceProvider); - - try - { - CurrentUser = users.SelectedOrDefault(); - } - catch (InvalidOperationException) - { - foreach (BindingUser user in users) - { - user.IsSelected = false; - } - - await userDbService.ClearUserSelectionAsync().ConfigureAwait(false); - } + await taskContext.SwitchToMainThreadAsync(); + this.users = new(users.ToObservableReorderableDbCollection(serviceProvider), serviceProvider); } } - return userCollection; + return users; } public async ValueTask> GetUserAndUidCollectionAsync() @@ -112,8 +81,8 @@ internal sealed partial class UserCollectionService : IUserCollectionService, ID { // Sync cache await taskContext.SwitchToMainThreadAsync(); - ArgumentNullException.ThrowIfNull(userCollection); - userCollection.Remove(user); + ArgumentNullException.ThrowIfNull(users); + users.Remove(user); userAndUidCollection?.RemoveWhere(r => r.User.Mid == user.Entity.Mid); if (user.Entity.Mid is not null) { @@ -159,11 +128,11 @@ internal sealed partial class UserCollectionService : IUserCollectionService, ID } await GetUserCollectionAsync().ConfigureAwait(false); - ArgumentNullException.ThrowIfNull(userCollection); + ArgumentNullException.ThrowIfNull(users); // Sync cache await taskContext.SwitchToMainThreadAsync(); - userCollection.Add(newUser); // Database synced in the collection + users.Add(newUser); // Database synced in the collection if (newUser.Entity.Mid is not null) { midUserMap?.Add(newUser.Entity.Mid, newUser); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs b/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs index eaf87c88..14166477 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs @@ -9,14 +9,12 @@ using Snap.Hutao.Web.Hoyolab.Passport; using Snap.Hutao.Web.Hoyolab.Takumi.Binding; using Snap.Hutao.Web.Response; using System.Collections.ObjectModel; +using Windows.Foundation; using BindingUser = Snap.Hutao.ViewModel.User.User; using EntityUser = Snap.Hutao.Model.Entity.User; namespace Snap.Hutao.Service.User; -/// -/// 用户服务 -/// [ConstructorGenerated] [Injection(InjectAs.Singleton, typeof(IUserService))] internal sealed partial class UserService : IUserService, IUserServiceUnsafe @@ -27,24 +25,18 @@ internal sealed partial class UserService : IUserService, IUserServiceUnsafe private readonly IUserDbService userDbService; private readonly ITaskContext taskContext; - public BindingUser? Current - { - get => userCollectionService.CurrentUser; - set => userCollectionService.CurrentUser = value; - } - public ValueTask RemoveUserAsync(BindingUser user) { return userCollectionService.RemoveUserAsync(user); } - public async ValueTask UnsafeRemoveUsersAsync() + public async ValueTask UnsafeRemoveAllUsersAsync() { await taskContext.SwitchToBackgroundAsync(); await userDbService.RemoveUsersAsync().ConfigureAwait(false); } - public ValueTask> GetUserCollectionAsync() + public ValueTask> GetUserCollectionAsync() { return userCollectionService.GetUserCollectionAsync(); } diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/MainView.xaml b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/MainView.xaml index 76d5965e..6782dda1 100644 --- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/MainView.xaml +++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/MainView.xaml @@ -16,6 +16,7 @@ mc:Ignorable="d"> + diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/MainView.xaml.cs b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/MainView.xaml.cs index f27cc152..691a0a29 100644 --- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/MainView.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/MainView.xaml.cs @@ -1,6 +1,7 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Snap.Hutao.Service.Navigation; using Snap.Hutao.UI.Xaml.View.Page; @@ -27,6 +28,8 @@ internal sealed partial class MainView : UserControl InitializeComponent(); + this.Unloaded += OnUnloaded; + (DataContext as MainViewModel)?.Initialize(new BackgroundImagePresenterAccessor(BackgroundImagePresenter)); navigationService = serviceProvider.GetRequiredService(); @@ -38,6 +41,11 @@ internal sealed partial class MainView : UserControl navigationService.Navigate(INavigationAwaiter.Default, true); } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + (DataContext as MainViewModel)?.Uninitialize(); + } + private class NavigationViewAccessor : INavigationViewAccessor { public NavigationViewAccessor(NavigationView navigationView, Frame frame) diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementImporterDependencies.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementImporterScopeContext.cs similarity index 100% rename from src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementImporterDependencies.cs rename to src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementImporterScopeContext.cs diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/MainViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/MainViewModel.cs index fb052a64..ff509163 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/MainViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/MainViewModel.cs @@ -16,7 +16,7 @@ namespace Snap.Hutao.ViewModel; [ConstructorGenerated] [Injection(InjectAs.Singleton)] -internal sealed partial class MainViewModel : Abstraction.ViewModel, IMainViewModelInitialization, IRecipient +internal sealed partial class MainViewModel : Abstraction.ViewModel, IMainViewModelInitialization { private readonly IBackgroundImageService backgroundImageService; private readonly ILogger logger; @@ -34,9 +34,23 @@ internal sealed partial class MainViewModel : Abstraction.ViewModel, IMainViewMo UpdateBackgroundAsync(true).SafeForget(); } - public void Receive(BackgroundImageTypeChangedMessage message) + protected override ValueTask InitializeOverrideAsync() { - UpdateBackgroundAsync().SafeForget(); + appOptions.PropertyChanged += OnAppOptionsPropertyChanged; + return ValueTask.FromResult(true); + } + + protected override void UninitializeOverride() + { + appOptions.PropertyChanged -= OnAppOptionsPropertyChanged; + } + + private void OnAppOptionsPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(AppOptions.BackgroundImageType)) + { + UpdateBackgroundAsync().SafeForget(); + } } [Command("UpdateBackgroundCommand")] diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingViewModel.cs index 740bcc24..53a37b80 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingViewModel.cs @@ -120,7 +120,6 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel if (SetProperty(ref selectedBackgroundImageType, value) && value is not null) { AppOptions.BackgroundImageType = value.Value; - messenger.Send(new Message.BackgroundImageTypeChangedMessage()); } } } @@ -347,7 +346,7 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel if (result is ContentDialogResult.Primary) { - await @unsafe.UnsafeRemoveUsersAsync().ConfigureAwait(false); + await @unsafe.UnsafeRemoveAllUsersAsync().ConfigureAwait(false); AppInstance.Restart(string.Empty); } } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/User/User.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/User/User.cs index 2f87e5d9..ef6dc288 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/User/User.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/User/User.cs @@ -8,6 +8,7 @@ using Snap.Hutao.Core.Database; using Snap.Hutao.Core.Database.Abstraction; using Snap.Hutao.Model; using Snap.Hutao.Model.Entity.Database; +using Snap.Hutao.UI.Xaml.Data; using Snap.Hutao.Web.Hoyolab; using Snap.Hutao.Web.Hoyolab.Bbs.User; using Snap.Hutao.Web.Hoyolab.Takumi.Binding; @@ -15,11 +16,11 @@ using EntityUser = Snap.Hutao.Model.Entity.User; namespace Snap.Hutao.ViewModel.User; -/// -/// 用于视图绑定的用户 -/// -[HighQuality] -internal sealed class User : ObservableObject, IEntityAccess, IMappingFrom, ISelectable +internal sealed class User : ObservableObject, + IEntityAccess, + IMappingFrom, + ISelectable, + IAdvancedCollectionViewItem { private readonly EntityUser inner; private readonly IServiceProvider serviceProvider; @@ -34,19 +35,10 @@ internal sealed class User : ObservableObject, IEntityAccess, IMappi public bool IsInitialized { get; set; } - /// - /// 用户信息 - /// public UserInfo? UserInfo { get; set; } - /// - /// 用户信息 - /// public List UserGameRoles { get; set; } = default!; - /// - /// 用户信息 - /// public UserGameRole? SelectedUserGameRole { get => selectedUserGameRole; @@ -57,42 +49,32 @@ internal sealed class User : ObservableObject, IEntityAccess, IMappi public Guid InnerId { get => inner.InnerId; } - /// public bool IsSelected { get => inner.IsSelected; set => inner.IsSelected = value; } - /// public Cookie? CookieToken { get => inner.CookieToken; set => inner.CookieToken = value; } - /// public Cookie? LToken { get => inner.LToken; set => inner.LToken = value; } - /// public Cookie? SToken { get => inner.SToken; set => inner.SToken = value; } - /// - /// 是否为国际服 - /// public bool IsOversea { get => Entity.IsOversea; } - /// - /// 内部的用户实体 - /// public EntityUser Entity { get => inner; } public bool NeedDbUpdateAfterResume { get; set; } @@ -123,4 +105,12 @@ internal sealed class User : ObservableObject, IEntityAccess, IMappi } } } + + public object? GetPropertyValue(string name) + { + return name switch + { + _ => default, + }; + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSBridgeFacade.cs b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSBridgeFacade.cs index 339b5a28..71b39157 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSBridgeFacade.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSBridgeFacade.cs @@ -103,6 +103,8 @@ internal class MiHoYoJSBridgeFacade public event Action? ClosePageRequested; + protected ILogger Logger { get => logger; } + public void Detach() { coreWebView2.WebMessageReceived -= OnWebMessageReceived; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJSBridgeOversea.cs b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJSBridgeOversea.cs index 4a234f6f..1f098e45 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJSBridgeOversea.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJSBridgeOversea.cs @@ -6,10 +6,6 @@ using Snap.Hutao.ViewModel.User; namespace Snap.Hutao.Web.Bridge; -/// -/// HoYoLAB 签到页面JS桥 -/// -[HighQuality] internal sealed class SignInJSBridgeOversea : MiHoYoJSBridgeFacade { // 移除 请旋转手机 提示所在的HTML元素 @@ -30,6 +26,6 @@ internal sealed class SignInJSBridgeOversea : MiHoYoJSBridgeFacade protected override void DOMContentLoaded(CoreWebView2 coreWebView2) { - coreWebView2.ExecuteScriptAsync(RemoveRotationWarningScript).AsTask().SafeForget(); + coreWebView2.ExecuteScriptAsync(RemoveRotationWarningScript).AsTask().SafeForget(Logger); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Win32/Registry/RegistryWatcher.cs b/src/Snap.Hutao/Snap.Hutao/Win32/Registry/RegistryWatcher.cs index 227cd3d2..0709935f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Win32/Registry/RegistryWatcher.cs +++ b/src/Snap.Hutao/Snap.Hutao/Win32/Registry/RegistryWatcher.cs @@ -47,10 +47,10 @@ internal sealed partial class RegistryWatcher : IDisposable this.valueChangedCallback = valueChangedCallback; } - public void Start() + public void Start(ILogger logger) { ObjectDisposedException.ThrowIf(disposed, this); - WatchAsync(cancellationTokenSource.Token).SafeForget(); + WatchAsync(cancellationTokenSource.Token).SafeForget(logger); } public void Dispose()