uigf 4 support

This commit is contained in:
DismissedLight
2024-07-14 23:51:09 +08:00
parent d30ef6daa0
commit 110af48385
28 changed files with 184 additions and 110 deletions

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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; }

View File

@@ -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>

View File

@@ -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));
}
}

View File

@@ -22,7 +22,7 @@ internal interface IGachaLogDbService : IAppDbService<GachaArchive>, IAppDbServi
GachaArchive? GetGachaArchiveByUid(string uid);
List<GachaArchive> GetGachaArchiveList();
List<string> GetGachaArchiveUidList();
ObservableCollection<GachaArchive> GetGachaArchiveCollection();

View File

@@ -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; }

View File

@@ -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),
};

View File

@@ -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)

View File

@@ -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; }
}

View File

@@ -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; }
}

View File

@@ -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>

View File

@@ -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}";
}
}

View File

@@ -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}";
}
}

View File

@@ -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;

View File

@@ -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>

View File

@@ -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!);
}
}

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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; }
}

View File

@@ -274,13 +274,6 @@
Header="{shuxm:ResourceString Name=ViewPageGachaLogRefreshByManualInput}"
HeaderIcon="{shuxm:FontIcon Glyph=&#xE765;}"
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=&#xE8B5;}"
IsClickEnabled="True"/>
<cwcont:SettingsCard
Description="{shuxm:ResourceString Name=ViewPageGachaLogRecoverFromHutaoCloudDescription}"
FlyoutBase.AttachedFlyout="{StaticResource HutaoCloudFlyout}"
@@ -342,14 +335,6 @@
Icon="{shuxm:FontIcon Glyph=&#xE753;}"
Label="{shuxm:ResourceString Name=ViewPageGachaLogHutaoCloud}"/>
<AppBarSeparator/>
<AppBarButton
Command="{Binding ImportFromUIGFJsonCommand}"
Icon="{shuxm:FontIcon Glyph=&#xE8B5;}"
Label="{shuxm:ResourceString Name=ViewPageGachaLogImportAction}"/>
<AppBarButton
Command="{Binding ExportToUIGFJsonCommand}"
Icon="{shuxm:FontIcon Glyph=&#xEDE1;}"
Label="{shuxm:ResourceString Name=ViewPageGachaLogExportAction}"/>
<CommandBar.SecondaryCommands>
<AppBarButton
Command="{Binding RemoveArchiveCommand}"

View File

@@ -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=&#xE8AF;}">
<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>

View File

@@ -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; }
}

View File

@@ -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!;

View File

@@ -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;
}

View File

@@ -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);
}
}
}