mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
uigf 4 support
This commit is contained in:
@@ -18,4 +18,11 @@ internal static class SelectableExtension
|
||||
{
|
||||
return source.SingleOrDefault(i => i.IsSelected);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TSource? SelectedOrFirstOrDefault<TSource>(this IEnumerable<TSource> source)
|
||||
where TSource : ISelectable
|
||||
{
|
||||
return source.SingleOrDefault(i => i.IsSelected) ?? source.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Entity.Abstraction;
|
||||
using Snap.Hutao.Model.InterChange;
|
||||
using Snap.Hutao.Model.InterChange.Achievement;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
|
||||
@@ -6,7 +6,6 @@ using Snap.Hutao.Model.InterChange.GachaLog;
|
||||
using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Snap.Hutao.Model.Entity;
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ namespace Snap.Hutao.Model.InterChange.GachaLog;
|
||||
internal sealed class UIGF
|
||||
{
|
||||
[JsonPropertyName("info")]
|
||||
public required UIGFInfo Info { get; set; }
|
||||
[JsonRequired]
|
||||
public UIGFInfo Info { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("hk4e")]
|
||||
public List<UIGFEntry<Hk4eItem>>? Hk4e { get; set; }
|
||||
|
||||
@@ -6,7 +6,8 @@ namespace Snap.Hutao.Model.InterChange.GachaLog;
|
||||
internal sealed class UIGFEntry<TItem>
|
||||
{
|
||||
[JsonPropertyName("uid")]
|
||||
public required string Uid { get; set; }
|
||||
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
|
||||
public required uint Uid { get; set; }
|
||||
|
||||
[JsonPropertyName("timezone")]
|
||||
public required int TimeZone { get; set; }
|
||||
|
||||
@@ -1274,6 +1274,12 @@
|
||||
<data name="ViewDialogDailyNoteWebhookUrlTitle" xml:space="preserve">
|
||||
<value>实时便笺 Webhook Url</value>
|
||||
</data>
|
||||
<data name="ViewDialogExportUIGFSubtitle" xml:space="preserve">
|
||||
<value>选择要导出记录的 UID</value>
|
||||
</data>
|
||||
<data name="ViewDialogExportUIGFTitle" xml:space="preserve">
|
||||
<value>导出 UIGF 文件</value>
|
||||
</data>
|
||||
<data name="ViewDialogFeedbackEnableLoopbackContent" xml:space="preserve">
|
||||
<value>解除限制后需要使用其他工具恢复限制</value>
|
||||
</data>
|
||||
@@ -1361,6 +1367,12 @@
|
||||
<data name="ViewDialogImportUIGFExportUIGFVersion" xml:space="preserve">
|
||||
<value>UIGF 版本</value>
|
||||
</data>
|
||||
<data name="ViewDialogImportUIGFSubtitle" xml:space="preserve">
|
||||
<value>选择要导入记录的 UID</value>
|
||||
</data>
|
||||
<data name="ViewDialogImportUIGFTitle" xml:space="preserve">
|
||||
<value>导入 UIGF 文件</value>
|
||||
</data>
|
||||
<data name="ViewDialogLaunchGameAccountInputPlaceholder" xml:space="preserve">
|
||||
<value>在此处输入名称</value>
|
||||
</data>
|
||||
@@ -1802,9 +1814,18 @@
|
||||
<data name="ViewModelSettingSetGamePathDatabaseFailedTitle" xml:space="preserve">
|
||||
<value>保存游戏路径失败</value>
|
||||
</data>
|
||||
<data name="ViewModelUIGFExportError" xml:space="preserve">
|
||||
<value>导出失败</value>
|
||||
</data>
|
||||
<data name="ViewModelUIGFExportSuccess" xml:space="preserve">
|
||||
<value>导出成功</value>
|
||||
</data>
|
||||
<data name="ViewModelUIGFImportDuplicatedHk4eEntry" xml:space="preserve">
|
||||
<value>导入的 UIGF 文件中包含 UID 重复的祈愿记录项</value>
|
||||
</data>
|
||||
<data name="ViewModelUIGFImportError" xml:space="preserve">
|
||||
<value>导入失败</value>
|
||||
</data>
|
||||
<data name="ViewModelUIGFImportNoHk4eEntry" xml:space="preserve">
|
||||
<value>导入的 UIGF 文件中不包含祈愿数据</value>
|
||||
</data>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
using Snap.Hutao.Core.Database;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Model.Entity.Database;
|
||||
using Snap.Hutao.Model.InterChange;
|
||||
using Snap.Hutao.Service.Abstraction;
|
||||
using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo;
|
||||
using System.Collections.ObjectModel;
|
||||
@@ -111,8 +110,8 @@ internal sealed partial class GachaLogDbService : IGachaLogDbService
|
||||
this.Delete<GachaItem>(i => i.ArchiveId == archiveId && i.QueryType == queryType && i.Id >= endId);
|
||||
}
|
||||
|
||||
public List<GachaArchive> GetGachaArchiveList()
|
||||
public List<string> GetGachaArchiveUidList()
|
||||
{
|
||||
return this.List<GachaArchive>();
|
||||
return this.List<GachaArchive, string>(query => query.Select(archive => archive.Uid));
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ internal interface IGachaLogDbService : IAppDbService<GachaArchive>, IAppDbServi
|
||||
|
||||
GachaArchive? GetGachaArchiveByUid(string uid);
|
||||
|
||||
List<GachaArchive> GetGachaArchiveList();
|
||||
List<string> GetGachaArchiveUidList();
|
||||
|
||||
ObservableCollection<GachaArchive> GetGachaArchiveCollection();
|
||||
|
||||
|
||||
@@ -3,16 +3,11 @@
|
||||
|
||||
using Snap.Hutao.Core.Database;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Model.InterChange.GachaLog;
|
||||
using Snap.Hutao.Service.GachaLog.QueryProvider;
|
||||
using Snap.Hutao.ViewModel.GachaLog;
|
||||
|
||||
namespace Snap.Hutao.Service.GachaLog;
|
||||
|
||||
/// <summary>
|
||||
/// 祈愿记录服务
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal interface IGachaLogService
|
||||
{
|
||||
AdvancedDbCollectionView<GachaArchive>? Archives { get; }
|
||||
|
||||
@@ -33,7 +33,7 @@ internal sealed partial class UIGF40ExportService : IUIGFExportService
|
||||
},
|
||||
};
|
||||
|
||||
ExportGachaArchives(uigf, exportOptions.GachaArchiveIds);
|
||||
ExportGachaArchives(uigf, exportOptions.GachaArchiveUids);
|
||||
|
||||
using (FileStream stream = File.Create(exportOptions.FilePath))
|
||||
{
|
||||
@@ -41,9 +41,9 @@ internal sealed partial class UIGF40ExportService : IUIGFExportService
|
||||
}
|
||||
}
|
||||
|
||||
private void ExportGachaArchives(Model.InterChange.GachaLog.UIGF uigf, List<Guid> archiveIds)
|
||||
private void ExportGachaArchives(Model.InterChange.GachaLog.UIGF uigf, List<uint> uids)
|
||||
{
|
||||
if (archiveIds.Count <= 0)
|
||||
if (uids.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -51,14 +51,14 @@ internal sealed partial class UIGF40ExportService : IUIGFExportService
|
||||
IGachaLogDbService gachaLogDbService = serviceProvider.GetRequiredService<IGachaLogDbService>();
|
||||
|
||||
List<UIGFEntry<Hk4eItem>> results = [];
|
||||
foreach (Guid archiveId in archiveIds)
|
||||
foreach (uint uid in uids)
|
||||
{
|
||||
GachaArchive? archive = gachaLogDbService.GetGachaArchiveById(archiveId);
|
||||
GachaArchive? archive = gachaLogDbService.GetGachaArchiveByUid($"{uid}");
|
||||
ArgumentNullException.ThrowIfNull(archive);
|
||||
List<GachaItem> dbItems = gachaLogDbService.GetGachaItemListByArchiveId(archiveId);
|
||||
List<GachaItem> dbItems = gachaLogDbService.GetGachaItemListByArchiveId(archive.InnerId);
|
||||
UIGFEntry<Hk4eItem> entry = new()
|
||||
{
|
||||
Uid = archive.Uid,
|
||||
Uid = uid,
|
||||
TimeZone = 0,
|
||||
List = dbItems.SelectList(Hk4eItem.From),
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ internal sealed partial class UIGF40ImportService : IUIGFImportService
|
||||
ImportGachaArchives(importOptions.UIGF.Hk4e, importOptions.GachaArchiveUids);
|
||||
}
|
||||
|
||||
private void ImportGachaArchives(List<UIGFEntry<Hk4eItem>>? entries, HashSet<string> uids)
|
||||
private void ImportGachaArchives(List<UIGFEntry<Hk4eItem>>? entries, HashSet<uint> uids)
|
||||
{
|
||||
if (entries.IsNullOrEmpty() || uids.IsNullOrEmpty())
|
||||
{
|
||||
@@ -37,11 +37,11 @@ internal sealed partial class UIGF40ImportService : IUIGFImportService
|
||||
continue;
|
||||
}
|
||||
|
||||
GachaArchive? archive = gachaLogDbService.GetGachaArchiveByUid(entry.Uid);
|
||||
GachaArchive? archive = gachaLogDbService.GetGachaArchiveByUid($"{entry.Uid}");
|
||||
|
||||
if (archive is null)
|
||||
{
|
||||
archive = GachaArchive.From(entry.Uid);
|
||||
archive = GachaArchive.From($"{entry.Uid}");
|
||||
gachaLogDbService.AddGachaArchive(archive);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ internal sealed partial class UIGF40ImportService : IUIGFImportService
|
||||
List<GachaItem> fullItems = [];
|
||||
foreach (GachaType queryType in GachaLog.GachaLog.QueryTypes)
|
||||
{
|
||||
long trimId = gachaLogDbService.GetOldestGachaItemIdByArchiveIdAndQueryType(archiveId, queryType);
|
||||
long trimId = gachaLogDbService.GetNewestGachaItemIdByArchiveIdAndQueryType(archiveId, queryType);
|
||||
List<GachaItem> currentTypedList = entry.List
|
||||
.Where(item => item.UIGFGachaType == queryType && item.Id > trimId)
|
||||
.OrderByDescending(item => item.Id)
|
||||
|
||||
@@ -7,5 +7,5 @@ internal sealed class UIGFExportOptions
|
||||
{
|
||||
public required string FilePath { get; set; }
|
||||
|
||||
public required List<Guid> GachaArchiveIds { get; set; }
|
||||
public required List<uint> GachaArchiveUids { get; set; }
|
||||
}
|
||||
@@ -7,5 +7,5 @@ internal sealed class UIGFImportOptions
|
||||
{
|
||||
public required Model.InterChange.GachaLog.UIGF UIGF { get; set; }
|
||||
|
||||
public required HashSet<string> GachaArchiveUids { get; set; }
|
||||
public required HashSet<uint> GachaArchiveUids { get; set; }
|
||||
}
|
||||
@@ -150,6 +150,7 @@
|
||||
<None Remove="Resource\WelcomeView_Background.png" />
|
||||
<None Remove="Service\Game\Automation\ScreenCapture\GameScreenCaptureDebugPreviewWindow.xaml" />
|
||||
<None Remove="stylecop.json" />
|
||||
<None Remove="UI\Xaml\View\Dialog\UIGFExportDialog.xaml" />
|
||||
<None Remove="UI\Xaml\View\Dialog\UIGFImportDialog.xaml" />
|
||||
<None Remove="UI\Xaml\View\Window\WebView2Window.xaml" />
|
||||
<None Remove="UI\Xaml\View\Dialog\AchievementArchiveCreateDialog.xaml" />
|
||||
@@ -340,6 +341,11 @@
|
||||
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnablePreviewMsixTooling)'=='true'">
|
||||
<ProjectCapability Include="Msix" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="UI\Xaml\View\Dialog\UIGFExportDialog.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="UI\Xaml\View\Dialog\UIGFImportDialog.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.UI.Xaml.Data.Converter.Specialized;
|
||||
|
||||
internal sealed class TimestampToLocalTimeStringConverter : ValueConverter<long, string>
|
||||
{
|
||||
public override string Convert(long from)
|
||||
{
|
||||
DateTimeOffset dto = DateTimeOffset.FromUnixTimeSeconds(from).ToLocalTime();
|
||||
return $"{dto:yyyy-MM-dd HH:mm:ss}";
|
||||
}
|
||||
}
|
||||
@@ -38,13 +38,4 @@ internal sealed partial class UInt32ToGradientColorConverter : DependencyValueCo
|
||||
color.B = (byte)b;
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class TimestampToLocalTimeStringConverter : ValueConverter<long, string>
|
||||
{
|
||||
public override string Convert(long from)
|
||||
{
|
||||
DateTimeOffset dto = DateTimeOffset.FromUnixTimeSeconds(from).ToLocalTime();
|
||||
return $"{dto:yyyy-MM-dd HH:mm:ss}";
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Service.User;
|
||||
|
||||
namespace Snap.Hutao.UI.Xaml.View.Dialog;
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<ContentDialog
|
||||
x:Class="Snap.Hutao.UI.Xaml.View.Dialog.UIGFExportDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:cwc="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Snap.Hutao.UI.Xaml.View.Dialog"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:shuxm="using:Snap.Hutao.UI.Xaml.Markup"
|
||||
Title="{shuxm:ResourceString Name=ViewDialogExportUIGFTitle}"
|
||||
CloseButtonText="{shuxm:ResourceString Name=ContentDialogCancelCloseButtonText}"
|
||||
DefaultButton="Primary"
|
||||
PrimaryButtonText="{shuxm:ResourceString Name=ContentDialogConfirmPrimaryButtonText}"
|
||||
Style="{StaticResource DefaultContentDialogStyle}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<cwc:HeaderedContentControl Header="{shuxm:ResourceString Name=ViewDialogExportUIGFSubtitle}">
|
||||
<ItemsControl Margin="0,4,0,0" ItemsSource="{x:Bind Selections}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox Content="{Binding Uid}" IsChecked="{Binding IsSelected, Mode=TwoWay}"/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</cwc:HeaderedContentControl>
|
||||
</Grid>
|
||||
</ContentDialog>
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Snap.Hutao.UI.Xaml.View.Dialog;
|
||||
|
||||
[DependencyProperty("Selections", typeof(List<UIGFUidSelection>))]
|
||||
internal sealed partial class UIGFExportDialog : ContentDialog
|
||||
{
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
public UIGFExportDialog(IServiceProvider serviceProvider, List<uint> uids)
|
||||
{
|
||||
InitializeComponent();
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
|
||||
Selections = uids.SelectList(item => new UIGFUidSelection(item));
|
||||
}
|
||||
|
||||
public async ValueTask<ValueResult<bool, List<uint>>> GetSelectedUidsAsync()
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
if (await ShowAsync() is ContentDialogResult.Primary)
|
||||
{
|
||||
List<uint> uids = Selections.Where(item => item.IsSelected).Select(item => item.Uid).ToList();
|
||||
return new(true, uids);
|
||||
}
|
||||
|
||||
return new(false, default!);
|
||||
}
|
||||
}
|
||||
@@ -9,17 +9,23 @@
|
||||
xmlns:shmig="using:Snap.Hutao.Model.InterChange.GachaLog"
|
||||
xmlns:shuxdcs="using:Snap.Hutao.UI.Xaml.Data.Converter.Specialized"
|
||||
xmlns:shuxm="using:Snap.Hutao.UI.Xaml.Markup"
|
||||
Title="{shuxm:ResourceString Name=ViewDialogImportUIGFTitle}"
|
||||
CloseButtonText="{shuxm:ResourceString Name=ContentDialogCancelCloseButtonText}"
|
||||
DefaultButton="Primary"
|
||||
PrimaryButtonText="{shuxm:ResourceString Name=ContentDialogConfirmPrimaryButtonText}"
|
||||
Style="{StaticResource DefaultContentDialogStyle}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<ContentDialog.Resources>
|
||||
<shuxdcs:TimestampToLocalTimeStringConverter x:Key="TimestampToLocalTimeStringConverter"/>
|
||||
</ContentDialog.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid RowSpacing="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<cwc:UniformGrid
|
||||
Grid.Row="0"
|
||||
ColumnSpacing="16"
|
||||
@@ -34,6 +40,7 @@
|
||||
</cwc:HeaderedContentControl>
|
||||
<cwc:HeaderedContentControl Header="{shuxm:ResourceString Name=ViewDialogImportExportTime}">
|
||||
<TextBlock
|
||||
MinWidth="120"
|
||||
Margin="0,4,0,0"
|
||||
Opacity="0.6"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
@@ -54,13 +61,17 @@
|
||||
Text="{x:Bind UIGF.Info.Version, Mode=OneWay}"/>
|
||||
</cwc:HeaderedContentControl>
|
||||
|
||||
<ItemsControl ItemsSource="{x:Bind Selections}">
|
||||
|
||||
</cwc:UniformGrid>
|
||||
|
||||
<cwc:HeaderedContentControl Grid.Row="1" Header="{shuxm:ResourceString Name=ViewDialogImportUIGFSubtitle}">
|
||||
<ItemsControl Margin="0,4,0,0" ItemsSource="{x:Bind Selections}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox Content="{Binding Uid}" IsChecked="{Binding IsSelected, Mode=TwoWay}"/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</cwc:UniformGrid>
|
||||
</cwc:HeaderedContentControl>
|
||||
</Grid>
|
||||
</ContentDialog>
|
||||
|
||||
@@ -21,12 +21,12 @@ internal sealed partial class UIGFImportDialog : ContentDialog
|
||||
Selections = uigf.Hk4e?.SelectList(item => new UIGFUidSelection(item.Uid));
|
||||
}
|
||||
|
||||
public async ValueTask<ValueResult<bool, HashSet<string>>> GetSelectedUidsAsync()
|
||||
public async ValueTask<ValueResult<bool, HashSet<uint>>> GetSelectedUidsAsync()
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
if (await ShowAsync() is ContentDialogResult.Primary)
|
||||
{
|
||||
HashSet<string> uids = Selections.Where(item => item.IsSelected).Select(item => item.Uid).ToHashSet();
|
||||
HashSet<uint> uids = Selections.Where(item => item.IsSelected).Select(item => item.Uid).ToHashSet();
|
||||
return new(true, uids);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Model.InterChange.GachaLog;
|
||||
|
||||
namespace Snap.Hutao.UI.Xaml.View.Dialog;
|
||||
|
||||
@@ -11,12 +9,12 @@ internal sealed class UIGFUidSelection : ObservableObject
|
||||
{
|
||||
private bool isSelected = true;
|
||||
|
||||
public UIGFUidSelection(string uid)
|
||||
public UIGFUidSelection(uint uid)
|
||||
{
|
||||
Uid = uid;
|
||||
}
|
||||
|
||||
public bool IsSelected { get => isSelected; set => SetProperty(ref isSelected, value); }
|
||||
|
||||
public string Uid { get; set; }
|
||||
public uint Uid { get; set; }
|
||||
}
|
||||
@@ -274,13 +274,6 @@
|
||||
Header="{shuxm:ResourceString Name=ViewPageGachaLogRefreshByManualInput}"
|
||||
HeaderIcon="{shuxm:FontIcon Glyph=}"
|
||||
IsClickEnabled="True"/>
|
||||
<cwcont:SettingsCard
|
||||
ActionIconToolTip="{shuxm:ResourceString Name=ViewPageGachaLogImportAction}"
|
||||
Command="{Binding ImportFromUIGFJsonCommand}"
|
||||
Description="{shuxm:ResourceString Name=ViewPageGachaLogImportDescription}"
|
||||
Header="{shuxm:ResourceString Name=ViewPageGachaLogImportHeader}"
|
||||
HeaderIcon="{shuxm:FontIcon Glyph=}"
|
||||
IsClickEnabled="True"/>
|
||||
<cwcont:SettingsCard
|
||||
Description="{shuxm:ResourceString Name=ViewPageGachaLogRecoverFromHutaoCloudDescription}"
|
||||
FlyoutBase.AttachedFlyout="{StaticResource HutaoCloudFlyout}"
|
||||
@@ -342,14 +335,6 @@
|
||||
Icon="{shuxm:FontIcon Glyph=}"
|
||||
Label="{shuxm:ResourceString Name=ViewPageGachaLogHutaoCloud}"/>
|
||||
<AppBarSeparator/>
|
||||
<AppBarButton
|
||||
Command="{Binding ImportFromUIGFJsonCommand}"
|
||||
Icon="{shuxm:FontIcon Glyph=}"
|
||||
Label="{shuxm:ResourceString Name=ViewPageGachaLogImportAction}"/>
|
||||
<AppBarButton
|
||||
Command="{Binding ExportToUIGFJsonCommand}"
|
||||
Icon="{shuxm:FontIcon Glyph=}"
|
||||
Label="{shuxm:ResourceString Name=ViewPageGachaLogExportAction}"/>
|
||||
<CommandBar.SecondaryCommands>
|
||||
<AppBarButton
|
||||
Command="{Binding RemoveArchiveCommand}"
|
||||
|
||||
@@ -580,6 +580,21 @@
|
||||
OffContent="{shuxm:ResourceString Name=ViewPageSettingEmptyHistoryVisibleOff}"
|
||||
OnContent="{shuxm:ResourceString Name=ViewPageSettingEmptyHistoryVisibleOn}"/>
|
||||
</cwc:SettingsCard>
|
||||
<cwc:SettingsCard
|
||||
Description="导入/导出 UIGF 4 文件"
|
||||
Header="数据迁移"
|
||||
HeaderIcon="{shuxm:FontIcon Glyph=}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="3">
|
||||
<Button
|
||||
Command="{Binding ExportUIGFJsonCommand}"
|
||||
Content="导出"
|
||||
Style="{ThemeResource SettingButtonStyle}"/>
|
||||
<Button
|
||||
Command="{Binding ImportUIGFJsonCommand}"
|
||||
Content="导入"
|
||||
Style="{ThemeResource SettingButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</cwc:SettingsCard>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Border>
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.AvatarProperty;
|
||||
|
||||
/// <summary>
|
||||
/// 圣遗物副词条
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal class ReliquarySubProperty
|
||||
{
|
||||
public ReliquarySubProperty(FightProperty type, string value, float score)
|
||||
@@ -22,23 +17,11 @@ internal class ReliquarySubProperty
|
||||
Opacity = score == 0 ? 0.25 : Math.Ceiling(score / 25) / 4;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 属性值
|
||||
/// </summary>
|
||||
public string Value { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 透明度
|
||||
/// </summary>
|
||||
public double Opacity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 评分
|
||||
/// </summary>
|
||||
internal float Score { get; }
|
||||
}
|
||||
@@ -1,39 +1,18 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.AvatarProperty;
|
||||
|
||||
/// <summary>
|
||||
/// 圣遗物
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class ReliquaryView : EquipView
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始词条
|
||||
/// </summary>
|
||||
public List<ReliquarySubProperty> PrimarySubProperties { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 强化词条
|
||||
/// </summary>
|
||||
public List<ReliquarySubProperty> SecondarySubProperties { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 合成的副属性
|
||||
/// </summary>
|
||||
public List<ReliquaryComposedSubProperty> ComposedSubProperties { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 格式化评分
|
||||
/// </summary>
|
||||
public string ScoreFormatted { get => $"{Score:F2}"; }
|
||||
|
||||
/// <summary>
|
||||
/// 评分
|
||||
/// </summary>
|
||||
internal float Score { get; set; }
|
||||
|
||||
internal string SetName { get; set; } = default!;
|
||||
|
||||
@@ -4,12 +4,10 @@
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Core.Database;
|
||||
using Snap.Hutao.Core.ExceptionService;
|
||||
using Snap.Hutao.Core.IO;
|
||||
using Snap.Hutao.Factory.ContentDialog;
|
||||
using Snap.Hutao.Factory.Picker;
|
||||
using Snap.Hutao.Factory.Progress;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Model.InterChange.GachaLog;
|
||||
using Snap.Hutao.Service.GachaLog;
|
||||
using Snap.Hutao.Service.GachaLog.QueryProvider;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
@@ -90,7 +88,7 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
Archives = gachaLogService.Archives;
|
||||
HutaoCloudViewModel.RetrieveCommand = RetrieveFromCloudCommand;
|
||||
Archives.MoveCurrentTo(Archives.SourceCollection.SelectedOrDefault());
|
||||
Archives.MoveCurrentTo(Archives.SourceCollection.SelectedOrFirstOrDefault());
|
||||
}
|
||||
|
||||
// When `Archives.CurrentItem` is not null, the `Initialization` actually completed in
|
||||
@@ -277,7 +275,6 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel
|
||||
{
|
||||
if (archive is null)
|
||||
{
|
||||
IsInitialized = false;
|
||||
Statistics = default;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using Snap.Hutao.Core.IO;
|
||||
using Snap.Hutao.Factory.ContentDialog;
|
||||
using Snap.Hutao.Factory.Picker;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Model.InterChange.GachaLog;
|
||||
using Snap.Hutao.Service;
|
||||
using Snap.Hutao.Service.GachaLog;
|
||||
@@ -59,7 +60,7 @@ internal sealed partial class SettingGachaLogViewModel : Abstraction.ViewModel
|
||||
}
|
||||
|
||||
UIGFImportDialog importDialog = await contentDialogFactory.CreateInstanceAsync<UIGFImportDialog>(uigf).ConfigureAwait(false);
|
||||
(bool isOk2, HashSet<string> uids) = await importDialog.GetSelectedUidsAsync().ConfigureAwait(false);
|
||||
(bool isOk2, HashSet<uint> uids) = await importDialog.GetSelectedUidsAsync().ConfigureAwait(false);
|
||||
if (!isOk2)
|
||||
{
|
||||
return;
|
||||
@@ -84,7 +85,7 @@ internal sealed partial class SettingGachaLogViewModel : Abstraction.ViewModel
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
infoBarService.Error(ex, SH.ViewModelUIGFImportSuccess);
|
||||
infoBarService.Error(ex, SH.ViewModelUIGFImportError);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,16 +102,29 @@ internal sealed partial class SettingGachaLogViewModel : Abstraction.ViewModel
|
||||
return;
|
||||
}
|
||||
|
||||
List<uint> allUids = gachaLogDbService.GetGachaArchiveUidList().SelectList(uint.Parse);
|
||||
UIGFExportDialog exportDialog = await contentDialogFactory.CreateInstanceAsync<UIGFExportDialog>(allUids).ConfigureAwait(false);
|
||||
|
||||
|
||||
LegacyUIGF uigf = await gachaLogService.ExportToUIGFAsync(Archives.CurrentItem).ConfigureAwait(false);
|
||||
if (await file.SerializeToJsonAsync(uigf, options).ConfigureAwait(false))
|
||||
(bool isOk2, List<uint> uids) = await exportDialog.GetSelectedUidsAsync().ConfigureAwait(false);
|
||||
if (!isOk2)
|
||||
{
|
||||
infoBarService.Success(SH.ViewModelExportSuccessTitle, SH.ViewModelExportSuccessMessage);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
UIGFExportOptions options = new()
|
||||
{
|
||||
infoBarService.Warning(SH.ViewModelExportWarningTitle, SH.ViewModelExportWarningMessage);
|
||||
FilePath = file,
|
||||
GachaArchiveUids = uids,
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
await uigfService.ExportAsync(options).ConfigureAwait(false);
|
||||
infoBarService.Success(SH.ViewModelUIGFExportSuccess);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
infoBarService.Error(ex, SH.ViewModelUIGFExportError);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user