From c4602f891f326b26714653cf44b4a27782e28109 Mon Sep 17 00:00:00 2001 From: DismissedLight <1686188646@qq.com> Date: Thu, 23 Jun 2022 15:23:19 +0800 Subject: [PATCH] style improvement --- .../DedendencyInjection/InjectionGenerator.cs | 32 +- src/Snap.Hutao/Snap.Hutao/App.xaml | 3 + .../Control/Behavior/AutoHeightBehavior.cs | 4 +- .../Control/Cancellable/CancellablePage.cs | 4 +- src/Snap.Hutao/Snap.Hutao/MainWindow.xaml.cs | 5 +- .../Snap.Hutao/Model/Entity/User.cs | 35 ++ .../Service/Abstraction/IUserService.cs | 4 +- .../Navigation/INavigationAwaiter.cs | 21 ++ .../Navigation/INavigationExtra.cs | 23 ++ .../Navigation/INavigationService.cs | 12 +- .../Abstraction/Navigation/NavigationExtra.cs | 34 +- .../Snap.Hutao/Service/NavigationService.cs | 29 +- .../Snap.Hutao/Service/UserService.cs | 16 +- src/Snap.Hutao/Snap.Hutao/View/MainView.xaml | 2 +- .../Snap.Hutao/View/MainView.xaml.cs | 4 +- .../View/Page/AnnouncementContentPage.xaml.cs | 9 +- .../View/Page/AnnouncementPage.xaml | 6 +- src/Snap.Hutao/Snap.Hutao/View/UserView.xaml | 318 ++++++++++-------- .../ViewModel/AnnouncementViewModel.cs | 2 +- .../Snap.Hutao/ViewModel/UserViewModel.cs | 61 ++-- .../Snap.Hutao/Web/Hutao/HutaoClient.cs | 11 +- .../Web/Hutao/Model/TeamCombination.cs | 17 +- .../Web/Hutao/Model/TeamCombination2.cs | 23 ++ .../Snap.Hutao/Web/Response/Response.cs | 9 +- .../Web/Response/Response{TData}.cs | 1 + 25 files changed, 430 insertions(+), 255 deletions(-) create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationAwaiter.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationExtra.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/TeamCombination2.cs diff --git a/src/Snap.Hutao/Snap.Hutao.SourceGeneration/DedendencyInjection/InjectionGenerator.cs b/src/Snap.Hutao/Snap.Hutao.SourceGeneration/DedendencyInjection/InjectionGenerator.cs index 9d354c13..b3c2dc99 100644 --- a/src/Snap.Hutao/Snap.Hutao.SourceGeneration/DedendencyInjection/InjectionGenerator.cs +++ b/src/Snap.Hutao/Snap.Hutao.SourceGeneration/DedendencyInjection/InjectionGenerator.cs @@ -5,6 +5,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Text; @@ -19,6 +20,9 @@ namespace Snap.Hutao.SourceGeneration.DedendencyInjection; [Generator] public class InjectionGenerator : ISourceGenerator { + private const string InjectAsSingletonName = "Snap.Hutao.Core.DependencyInjection.InjectAs.Singleton"; + private const string InjectAsTransientName = "Snap.Hutao.Core.DependencyInjection.InjectAs.Transient"; + /// public void Initialize(GeneratorInitializationContext context) { @@ -63,9 +67,14 @@ internal static partial class ServiceCollectionExtensions private static void FillWithInjectionServices(InjectionSyntaxContextReceiver receiver, StringBuilder sourceCodeBuilder) { - foreach (INamedTypeSymbol classSymbol in receiver.Classes.OrderByDescending(symbol => symbol.ToDisplayString())) + List lines = new(); + StringBuilder lineBuilder = new(); + + foreach (INamedTypeSymbol classSymbol in receiver.Classes) { - sourceCodeBuilder.Append("\r\n"); + lineBuilder + .Clear() + .Append("\r\n"); AttributeData injectionInfo = classSymbol .GetAttributes() @@ -77,11 +86,11 @@ internal static partial class ServiceCollectionExtensions string injectAsName = injectAs.ToCSharpString(); switch (injectAsName) { - case "Snap.Hutao.Core.DependencyInjection.InjectAs.Singleton": - sourceCodeBuilder.Append(@" .AddSingleton("); + case InjectAsSingletonName: + lineBuilder.Append(@" .AddSingleton("); break; - case "Snap.Hutao.Core.DependencyInjection.InjectAs.Transient": - sourceCodeBuilder.Append(@" .AddTransient("); + case InjectAsTransientName: + lineBuilder.Append(@" .AddTransient("); break; default: throw new InvalidOperationException($"非法的InjectAs值: [{injectAsName}]。"); @@ -90,10 +99,17 @@ internal static partial class ServiceCollectionExtensions if (arguments.Length == 2) { TypedConstant interfaceType = arguments[1]; - sourceCodeBuilder.Append($"{interfaceType.ToCSharpString()}, "); + lineBuilder.Append($"{interfaceType.ToCSharpString()}, "); } - sourceCodeBuilder.Append($"typeof({classSymbol.ToDisplayString()}))"); + lineBuilder.Append($"typeof({classSymbol.ToDisplayString()}))"); + + lines.Add(lineBuilder.ToString()); + } + + foreach (string line in lines.OrderByDescending(x => x)) + { + sourceCodeBuilder.Append(line); } } } diff --git a/src/Snap.Hutao/Snap.Hutao/App.xaml b/src/Snap.Hutao/Snap.Hutao/App.xaml index 7f9ff759..f051bbca 100644 --- a/src/Snap.Hutao/Snap.Hutao/App.xaml +++ b/src/Snap.Hutao/Snap.Hutao/App.xaml @@ -17,6 +17,9 @@ + 6,16,16,16 + 16,0,0,0 + 4 4,4,0,0 0,4,4,0 diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Behavior/AutoHeightBehavior.cs b/src/Snap.Hutao/Snap.Hutao/Control/Behavior/AutoHeightBehavior.cs index 04816f01..11d8d246 100644 --- a/src/Snap.Hutao/Snap.Hutao/Control/Behavior/AutoHeightBehavior.cs +++ b/src/Snap.Hutao/Snap.Hutao/Control/Behavior/AutoHeightBehavior.cs @@ -21,7 +21,6 @@ internal class AutoHeightBehavior : BehaviorBase public double TargetWidth { get => (double)GetValue(TargetWidthProperty); - set => SetValue(TargetWidthProperty, value); } @@ -31,15 +30,14 @@ internal class AutoHeightBehavior : BehaviorBase public double TargetHeight { get => (double)GetValue(TargetHeightProperty); - set => SetValue(TargetHeightProperty, value); } /// protected override void OnAssociatedObjectLoaded() { - AssociatedObject.SizeChanged += OnSizeChanged; UpdateElementHeight(); + AssociatedObject.SizeChanged += OnSizeChanged; } /// diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Cancellable/CancellablePage.cs b/src/Snap.Hutao/Snap.Hutao/Control/Cancellable/CancellablePage.cs index 362b72b7..89f43683 100644 --- a/src/Snap.Hutao/Snap.Hutao/Control/Cancellable/CancellablePage.cs +++ b/src/Snap.Hutao/Snap.Hutao/Control/Cancellable/CancellablePage.cs @@ -27,7 +27,7 @@ public class CancellablePage : Page /// protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { - viewLoadingConcellationTokenSource.Cancel(); base.OnNavigatingFrom(e); + viewLoadingConcellationTokenSource.Cancel(); } -} +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/MainWindow.xaml.cs b/src/Snap.Hutao/Snap.Hutao/MainWindow.xaml.cs index 3dca749a..bf7007ea 100644 --- a/src/Snap.Hutao/Snap.Hutao/MainWindow.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/MainWindow.xaml.cs @@ -27,6 +27,9 @@ public sealed partial class MainWindow : Window private void MainWindowClosed(object sender, WindowEventArgs args) { // save datebase - Ioc.Default.GetRequiredService().SaveChanges(); + AppDbContext appDbContext = Ioc.Default.GetRequiredService(); + int changes = appDbContext.SaveChanges(); + + Verify.Operation(changes == 0, "存在可避免的未经处理的数据库更改"); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/User.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/User.cs index 8f5bc6b4..442e45ab 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/User.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/User.cs @@ -1,13 +1,16 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using CommunityToolkit.Mvvm.Input; using Snap.Hutao.Extension; +using Snap.Hutao.Service.Abstraction; using Snap.Hutao.Web.Hoyolab.Bbs.User; using Snap.Hutao.Web.Hoyolab.Takumi.Binding; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; +using Windows.ApplicationModel.DataTransfer; namespace Snap.Hutao.Model.Entity; @@ -21,6 +24,7 @@ public class User : Observable /// 无用户 /// public static readonly User None = new(); + private bool isInitialized = false; private UserGameRole? selectedUserGameRole; /// @@ -68,6 +72,12 @@ public class User : Observable [NotMapped] public ICommand? RemoveCommand { get; set; } + /// + /// 复制Cookie命令 + /// + [NotMapped] + public ICommand? CopyCookieCommand { get; set; } + /// /// 判断用户是否为空用户 /// @@ -110,6 +120,12 @@ public class User : Observable return false; } + if (isInitialized) + { + return true; + } + + CopyCookieCommand = new RelayCommand(CopyCookie); Must.NotNull(RemoveCommand!); UserInfo = await userClient @@ -122,6 +138,8 @@ public class User : Observable SelectedUserGameRole = UserGameRoles.FirstOrFirstOrDefault(role => role.IsChosen); + isInitialized = true; + return UserInfo != null && UserGameRoles.Any(); } @@ -141,4 +159,21 @@ public class User : Observable return user; } } + + private void CopyCookie() + { + IInfoBarService infoBarService = Ioc.Default.GetRequiredService(); + try + { + DataPackage content = new(); + content.SetText(Must.NotNull(Cookie!)); + Clipboard.SetContent(content); + + infoBarService.Success($"{UserInfo?.Nickname} 的 Cookie 复制成功"); + } + catch (Exception e) + { + infoBarService.Error(e); + } + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/IUserService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/IUserService.cs index 7b298f44..19d97f25 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/IUserService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/IUserService.cs @@ -28,6 +28,7 @@ public interface IUserService /// /// 异步添加用户 + /// 通常用户是未初始化的 /// /// 待添加的用户 /// 用户初始化是否成功 @@ -37,7 +38,8 @@ public interface IUserService /// 异步移除用户 /// /// 待移除的用户 - void RemoveUser(User user); + /// 任务 + Task RemoveUserAsync(User user); /// /// 将cookie的字符串形式转换为字典 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationAwaiter.cs b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationAwaiter.cs new file mode 100644 index 00000000..b25ad268 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationAwaiter.cs @@ -0,0 +1,21 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Service.Abstraction.Navigation; + +/// +/// 表示导航等待器 +/// +public interface INavigationAwaiter +{ + /// + /// 默认的等待器 + /// + static readonly INavigationAwaiter Default = new NavigationExtra(); + + /// + /// 等待导航完成,或直到抛出异常 + /// + /// 导航完成的任务 + Task WaitForCompletionAsync(); +} diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationExtra.cs b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationExtra.cs new file mode 100644 index 00000000..418f0c4c --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationExtra.cs @@ -0,0 +1,23 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Service.Abstraction.Navigation; + +public interface INavigationExtra +{ + /// + /// 数据 + /// + object? Data { get; set; } + + /// + /// 通知导航服务导航已经结束 + /// + void NotifyNavigationCompleted(); + + /// + /// 通知导航服务导航异常 + /// + /// 异常 + void NotifyNavigationException(Exception exception); +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationService.cs index 39ea31ae..e3921cc2 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/INavigationService.cs @@ -41,29 +41,29 @@ public interface INavigationService /// 导航到指定类型的页面 /// /// 指定的页面类型 - /// 是否同步标签,当在代码中调用时应设为 true /// 要传递的数据 + /// 是否同步标签,当在代码中调用时应设为 true /// 是否导航成功 - NavigationResult Navigate(Type pageType, bool isSyncTabRequested = false, NavigationExtra? data = null); + NavigationResult Navigate(Type pageType, INavigationAwaiter data, bool isSyncTabRequested = false); /// /// 导航到指定类型的页面 /// /// 指定的页面类型 - /// 是否同步标签,当在代码中调用时应设为 true /// 要传递的数据 + /// 是否同步标签,当在代码中调用时应设为 true /// 是否导航成功 - NavigationResult Navigate(bool isSyncTabRequested = false, NavigationExtra? data = null) + NavigationResult Navigate(INavigationAwaiter data, bool isSyncTabRequested = false) where T : Page; /// /// 异步的导航到指定类型的页面 /// /// 指定的页面类型 - /// 是否同步标签,当在代码中调用时应设为 true /// 要传递的数据 + /// 是否同步标签,当在代码中调用时应设为 true /// 是否导航成功 - Task NavigateAsync(bool syncNavigationViewItem = false, NavigationExtra? data = null) + Task NavigateAsync(INavigationAwaiter data, bool syncNavigationViewItem = false) where TPage : Page; /// diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/NavigationExtra.cs b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/NavigationExtra.cs index 47067c0f..fb0508d9 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/NavigationExtra.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/Navigation/NavigationExtra.cs @@ -6,8 +6,13 @@ namespace Snap.Hutao.Service.Abstraction.Navigation; /// /// 导航额外信息 /// -public class NavigationExtra +public class NavigationExtra : INavigationExtra, INavigationAwaiter { + /// + /// 任务完成源 + /// + private readonly TaskCompletionSource navigationCompletedTaskCompletionSource = new(); + /// /// 构造一个新的导航额外信息 /// @@ -17,13 +22,24 @@ public class NavigationExtra Data = data; } - /// - /// 数据 - /// + /// public object? Data { get; set; } - /// - /// 任务完成源 - /// - public TaskCompletionSource NavigationCompletedTaskCompletionSource { get; } = new(); -} + /// + public Task WaitForCompletionAsync() + { + return navigationCompletedTaskCompletionSource.Task; + } + + /// + public void NotifyNavigationCompleted() + { + navigationCompletedTaskCompletionSource.TrySetResult(); + } + + /// + public void NotifyNavigationException(Exception exception) + { + navigationCompletedTaskCompletionSource.TrySetException(exception); + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/NavigationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/NavigationService.cs index d5377b9c..4d8d4d35 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/NavigationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/NavigationService.cs @@ -25,11 +25,11 @@ internal class NavigationService : INavigationService /// /// 构造一个新的导航服务 /// - /// 信息条服务 + /// 信息条服务 /// 日志器 - public NavigationService(IInfoBarService infobarService, ILogger logger) + public NavigationService(IInfoBarService infoBarService, ILogger logger) { - this.infoBarService = infobarService; + this.infoBarService = infoBarService; this.logger = logger; } @@ -93,7 +93,7 @@ internal class NavigationService : INavigationService } /// - public NavigationResult Navigate(Type pageType, bool syncNavigationViewItem = false, NavigationExtra? data = null) + public NavigationResult Navigate(Type pageType, INavigationAwaiter data, bool syncNavigationViewItem = false) { Type? currentType = Frame?.Content?.GetType(); @@ -123,22 +123,28 @@ internal class NavigationService : INavigationService } /// - public NavigationResult Navigate(bool syncNavigationViewItem = false, NavigationExtra? data = null) + public NavigationResult Navigate(INavigationAwaiter data, bool syncNavigationViewItem = false) where TPage : Page { - return Navigate(typeof(TPage), syncNavigationViewItem, data); + return Navigate(typeof(TPage), data, syncNavigationViewItem); } /// - public async Task NavigateAsync(bool syncNavigationViewItem = false, NavigationExtra? data = null) + public async Task NavigateAsync(INavigationAwaiter data, bool syncNavigationViewItem = false) where TPage : Page { - data ??= new NavigationExtra(); - NavigationResult result = Navigate(syncNavigationViewItem, data); + NavigationResult result = Navigate(data, syncNavigationViewItem); if (result is NavigationResult.Succeed) { - await data.NavigationCompletedTaskCompletionSource.Task; + try + { + await data.WaitForCompletionAsync(); + } + catch (AggregateException) + { + return NavigationResult.Failed; + } } return result; @@ -158,7 +164,8 @@ internal class NavigationService : INavigationService ? typeof(SettingPage) : NavHelper.GetNavigateTo(Selected); - Navigate(Must.NotNull(targetType!), false, new(NavHelper.GetExtraData(Selected))); + INavigationAwaiter navigationAwaiter = new NavigationExtra(NavHelper.GetExtraData(Selected)); + Navigate(Must.NotNull(targetType!), navigationAwaiter, false); } private void OnBackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/UserService.cs b/src/Snap.Hutao/Snap.Hutao/Service/UserService.cs index df65d610..ec090533 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/UserService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/UserService.cs @@ -24,7 +24,7 @@ internal class UserService : IUserService private readonly UserGameRoleClient userGameRoleClient; private User? currentUser; - private ObservableCollection? cachedUser = null; + private ObservableCollection? cachedUsers = null; /// /// 构造一个新的用户服务 @@ -52,6 +52,7 @@ internal class UserService : IUserService { User.SetSelectionState(currentUser, false); appDbContext.Users.Update(currentUser); + appDbContext.SaveChanges(); } } @@ -62,6 +63,7 @@ internal class UserService : IUserService { User.SetSelectionState(currentUser, true); appDbContext.Users.Update(currentUser); + appDbContext.SaveChanges(); } } } @@ -72,6 +74,7 @@ internal class UserService : IUserService if (await user.InitializeAsync(userClient, userGameRoleClient)) { appDbContext.Users.Add(user); + await appDbContext.SaveChangesAsync(); return true; } @@ -79,20 +82,21 @@ internal class UserService : IUserService } /// - public void RemoveUser(User user) + public async Task RemoveUserAsync(User user) { appDbContext.Users.Remove(user); + await appDbContext.SaveChangesAsync(); } /// public async Task> GetInitializedUsersAsync(ICommand removeCommand) { - if (cachedUser == null) + if (cachedUsers == null) { appDbContext.Users.Load(); - cachedUser = appDbContext.Users.Local.ToObservableCollection(); + cachedUsers = appDbContext.Users.Local.ToObservableCollection(); - foreach (User user in cachedUser) + foreach (User user in cachedUsers) { user.RemoveCommand = removeCommand; await user.InitializeAsync(userClient, userGameRoleClient); @@ -101,7 +105,7 @@ internal class UserService : IUserService CurrentUser = await appDbContext.Users.SingleOrDefaultAsync(user => user.IsSelected); } - return cachedUser; + return cachedUsers; } /// diff --git a/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml b/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml index 21552f70..fa1849e1 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml @@ -14,7 +14,7 @@ (); navigationService.Initialize(NavView, ContentFrame); - navigationService.Navigate(true); + navigationService.Navigate(INavigationAwaiter.Default, true); } -} +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml.cs index 03d583e3..316a7b6b 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml.cs @@ -35,14 +35,14 @@ openInWebview: function(url){ location.href = url }}"; { base.OnNavigatedTo(e); - if (e.Parameter is NavigationExtra extra) + if (e.Parameter is INavigationExtra extra) { targetContent = extra.Data as string; LoadAnnouncementAsync(extra).Forget(); } } - private async Task LoadAnnouncementAsync(NavigationExtra extra) + private async Task LoadAnnouncementAsync(INavigationExtra extra) { try { @@ -51,12 +51,13 @@ openInWebview: function(url){ location.href = url }}"; await WebView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(MihoyoSDKDefinition); WebView.CoreWebView2.WebMessageReceived += (_, e) => Browser.Open(e.TryGetWebMessageAsString); } - catch + catch (Exception ex) { + extra.NotifyNavigationException(ex); return; } WebView.NavigateToString(targetContent); - extra.NavigationCompletedTaskCompletionSource.TrySetResult(); + extra.NotifyNavigationCompleted(); } } diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml index 0eaa470f..6ffc9406 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml @@ -17,7 +17,6 @@ xmlns:shvc="using:Snap.Hutao.View.Converter" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> - @@ -46,7 +45,7 @@ @@ -70,7 +69,6 @@ @@ -176,4 +174,4 @@ - + \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/View/UserView.xaml b/src/Snap.Hutao/Snap.Hutao/View/UserView.xaml index cdb5231d..df2bc99f 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/UserView.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/UserView.xaml @@ -2,7 +2,6 @@ x:Class="Snap.Hutao.View.UserView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:local="using:Snap.Hutao.View" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mxi="using:Microsoft.Xaml.Interactivity" @@ -14,157 +13,188 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs index 3fc8b7d3..c9f20d10 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs @@ -99,7 +99,7 @@ internal class AnnouncementViewModel : ObservableObject, ISupportCancellation if (WebView2Helper.IsSupported) { - navigationService.Navigate(data: new(content)); + navigationService.Navigate(data: new NavigationExtra(content)); } else { diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/UserViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/UserViewModel.cs index 1d1a54a3..ee1ff00b 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/UserViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/UserViewModel.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; using Microsoft.UI.Xaml.Controls; using Snap.Hutao.Core.Threading; using Snap.Hutao.Factory.Abstraction; @@ -23,8 +22,7 @@ internal class UserViewModel : ObservableObject { private readonly IUserService userService; private readonly IInfoBarService infoBarService; - - private ICommand removeUserCommand; + private readonly ICommand removeUserCommandCache; private User? selectedUser; private ObservableCollection? userInfos; @@ -43,7 +41,7 @@ internal class UserViewModel : ObservableObject OpenUICommand = asyncRelayCommandFactory.Create(OpenUIAsync); AddUserCommand = asyncRelayCommandFactory.Create(AddUserAsync); - removeUserCommand = new RelayCommand(RemoveUser); + removeUserCommandCache = asyncRelayCommandFactory.Create(RemoveUserAsync); } /// @@ -76,46 +74,36 @@ internal class UserViewModel : ObservableObject /// public ICommand AddUserCommand { get; } - private static bool TryValidateCookie(IDictionary map, [NotNullWhen(true)] out SortedDictionary? filteredCookie) + private static bool TryValidateCookie(IDictionary map, [NotNullWhen(true)] out IDictionary? filteredCookie) { int validFlag = 4; - filteredCookie = new(); + filteredCookie = new SortedDictionary(); // O(1) to validate cookie foreach ((string key, string value) in map) { - if (key == "account_id") - { - validFlag--; - filteredCookie[key] = value; - } - - if (key == "cookie_token") - { - validFlag--; - filteredCookie[key] = value; - } - - if (key == "ltoken") - { - validFlag--; - filteredCookie[key] = value; - } - - if (key == "ltuid") + if (key == "account_id" || key == "cookie_token" || key == "ltoken" || key == "ltuid") { validFlag--; filteredCookie[key] = value; } } - return validFlag == 0; + if (validFlag == 0) + { + return true; + } + else + { + filteredCookie = null; + return false; + } } private async Task OpenUIAsync() { - Users = await userService.GetInitializedUsersAsync(removeUserCommand); + Users = await userService.GetInitializedUsersAsync(removeUserCommandCache); SelectedUser = userService.CurrentUser; } @@ -131,28 +119,37 @@ internal class UserViewModel : ObservableObject { IDictionary map = userService.ParseCookie(result.Value); - if (TryValidateCookie(map, out SortedDictionary? filteredCookie)) + if (TryValidateCookie(map, out IDictionary? filteredCookie)) { string simplifiedCookie = string.Join(';', filteredCookie.Select(kvp => $"{kvp.Key}={kvp.Value}")); User user = new() { Cookie = simplifiedCookie, - RemoveCommand = removeUserCommand, + RemoveCommand = removeUserCommandCache, }; if (!await userService.TryAddUserAsync(user)) { - infoBarService.Warning("提供的Cookie无效!"); + infoBarService.Warning("此Cookie无法获取用户信息,请重新输入"); } + else + { + infoBarService.Success($"成功添加用户 [{user.UserInfo!.Nickname}]"); + } + } + else + { + infoBarService.Warning("提供的字符串并不是有效的Cookie,请重新输入"); } } } - private void RemoveUser(User? user) + private async Task RemoveUserAsync(User? user) { if (!User.IsNone(user)) { - userService.RemoveUser(user); + await userService.RemoveUserAsync(user); + infoBarService.Success($"成功移除用户 [{user.UserInfo!.Nickname}]"); } } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HutaoClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HutaoClient.cs index 5b6c65a1..81cc077f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HutaoClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HutaoClient.cs @@ -55,6 +55,11 @@ internal class HutaoClient : ISupportAsyncInitialization /// public async Task InitializeAsync(CancellationToken token = default) { + if (isInitialized) + { + return true; + } + Auth auth = new( "08d9e212-0cb3-4d71-8ed7-003606da7b20", "7ueWgZGn53dDhrm8L5ZRw+YWfOeSWtgQmJWquRgaygw="); @@ -185,7 +190,7 @@ internal class HutaoClient : ISupportAsyncInitialization } /// - /// 异步获取队伍出场次数 + /// 异步获取队伍出场次数 层间 /// /// 取消令牌 /// 队伍出场列表 @@ -201,7 +206,7 @@ internal class HutaoClient : ISupportAsyncInitialization } /// - /// 异步获取队伍出场次数 + /// 异步获取队伍出场次数 层 /// /// 取消令牌 /// 队伍出场列表 @@ -217,7 +222,7 @@ internal class HutaoClient : ISupportAsyncInitialization } /// - /// 异步获取队伍出场次数 + /// 按角色列表异步获取推荐队伍 /// /// 楼层 /// 期望的角色,按期望出现顺序排序 diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/TeamCombination.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/TeamCombination.cs index d98014cf..fc5275a0 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/TeamCombination.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/TeamCombination.cs @@ -7,6 +7,7 @@ namespace Snap.Hutao.Web.Hutao.Model; /// /// 队伍上场率 +/// 层间上场率 /// public record TeamCombination { @@ -15,22 +16,6 @@ public record TeamCombination /// public LevelInfo Level { get; set; } = null!; - /// - /// 队伍 - /// - public IEnumerable> Teams { get; set; } = null!; -} - -/// -/// 队伍上场率2 -/// -public record TeamCombination2 -{ - /// - /// 带有层的间 - /// - public int Floor { get; set; } - /// /// 队伍 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/TeamCombination2.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/TeamCombination2.cs new file mode 100644 index 00000000..8a2ef1dc --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/TeamCombination2.cs @@ -0,0 +1,23 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using System.Collections.Generic; + +namespace Snap.Hutao.Web.Hutao.Model; + +/// +/// 队伍上场率2 +/// 层上场率 +/// +public record TeamCombination2 +{ + /// + /// 带有层的间 + /// + public int Floor { get; set; } + + /// + /// 队伍 + /// + public IEnumerable> Teams { get; set; } = null!; +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Response/Response.cs b/src/Snap.Hutao/Snap.Hutao/Web/Response/Response.cs index 425c5607..4e455988 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Response/Response.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Response/Response.cs @@ -27,7 +27,14 @@ public class Response : ISupportValidation { Ioc.Default .GetRequiredService() - .Information(ToString()); + .Error(ToString()); + } + + if (ReturnCode != 0) + { + Ioc.Default + .GetRequiredService() + .Warning(ToString()); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Response/Response{TData}.cs b/src/Snap.Hutao/Snap.Hutao/Web/Response/Response{TData}.cs index c2d1c2fc..34fa102b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Response/Response{TData}.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Response/Response{TData}.cs @@ -17,6 +17,7 @@ public class Response : Response /// 返回代码 /// 消息 /// 数据 + [JsonConstructor] public Response(int returnCode, string message, TData? data) : base(returnCode, message) {