fix minor issue

This commit is contained in:
DismissedLight
2024-07-02 22:20:02 +08:00
parent a3fb0486c2
commit e837e425c5
14 changed files with 76 additions and 62 deletions

View File

@@ -10,7 +10,7 @@ using Snap.Hutao.UI.Xaml.Data;
namespace Snap.Hutao.Core.Database;
// The scope of the view follows the scope of the service provider.
internal sealed class AdvancedDbCollectionView<TEntity> : AdvancedCollectionView<TEntity>
internal sealed class AdvancedDbCollectionView<TEntity> : AdvancedCollectionView<TEntity>, IAdvancedDbCollectionView<TEntity>
where TEntity : class, IAdvancedCollectionViewItem, ISelectable
{
private readonly IServiceProvider serviceProvider;
@@ -57,7 +57,7 @@ internal sealed class AdvancedDbCollectionView<TEntity> : AdvancedCollectionView
// The scope of the view follows the scope of the service provider.
[SuppressMessage("", "SA1402")]
internal sealed class AdvancedDbCollectionView<TEntityAccess, TEntity> : AdvancedCollectionView<TEntityAccess>
internal sealed class AdvancedDbCollectionView<TEntityAccess, TEntity> : AdvancedCollectionView<TEntityAccess>, IAdvancedDbCollectionView<TEntityAccess>
where TEntityAccess : class, IEntityAccess<TEntity>, IAdvancedCollectionViewItem
where TEntity : class, ISelectable
{

View File

@@ -0,0 +1,12 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.UI.Xaml.Data;
namespace Snap.Hutao.Core.Database;
internal interface IAdvancedDbCollectionView<TEntity> : IAdvancedCollectionView<TEntity>
where TEntity : class
{
void Detach();
}

View File

@@ -51,13 +51,6 @@ internal sealed class HutaoException : Exception
throw new HutaoException(SH.FormatServiceGachaStatisticsFactoryItemIdInvalid(id), innerException);
}
[DoesNotReturn]
[MethodImpl(MethodImplOptions.NoInlining)]
public static HutaoException UserdataCorrupted(string message, Exception? innerException = default)
{
throw new HutaoException(message, innerException);
}
[DoesNotReturn]
[MethodImpl(MethodImplOptions.NoInlining)]
public static InvalidCastException InvalidCast<TFrom, TTo>(string name, Exception? innerException = default)

View File

@@ -28,7 +28,7 @@ internal sealed partial class AchievementDbService : IAchievementDbService
}
catch (ArgumentException ex)
{
throw HutaoException.UserdataCorrupted(SH.ServiceAchievementUserdataCorruptedAchievementIdNotUnique, ex);
throw HutaoException.Throw(SH.ServiceAchievementUserdataCorruptedAchievementIdNotUnique, ex);
}
}
@@ -65,7 +65,7 @@ internal sealed partial class AchievementDbService : IAchievementDbService
public void RemoveAchievementArchive(AchievementArchive archive)
{
// It will cascade delete the achievements.
// Cascade delete the achievements.
this.Delete(archive);
}

View File

@@ -7,7 +7,9 @@ using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.InterChange.Achievement;
using Snap.Hutao.Model.Primitive;
using Snap.Hutao.UI.Xaml.Data;
using Snap.Hutao.ViewModel.Achievement;
using System.Collections.ObjectModel;
using EntityAchievement = Snap.Hutao.Model.Entity.Achievement;
namespace Snap.Hutao.Service.Achievement;
@@ -23,11 +25,19 @@ internal sealed partial class AchievementService : IAchievementService
private readonly RuntimeOptions runtimeOptions;
private readonly ITaskContext taskContext;
private AdvancedDbCollectionView<AchievementArchive>? archivesView;
private AdvancedDbCollectionView<AchievementArchive>? archives;
public AdvancedDbCollectionView<AchievementArchive> Archives
public async ValueTask<IAdvancedDbCollectionView<AchievementArchive>> GetArchivesAsync(CancellationToken token = default)
{
get => archivesView ??= new(achievementDbService.GetAchievementArchiveCollection(), serviceProvider);
if (archives is null)
{
await taskContext.SwitchToBackgroundAsync();
ObservableCollection<AchievementArchive> source = achievementDbService.GetAchievementArchiveCollection();
await taskContext.SwitchToMainThreadAsync();
archives = new(source, serviceProvider);
}
return archives;
}
public List<AchievementView> GetAchievementViewList(AchievementArchive archive, AchievementServiceMetadataContext context)
@@ -53,27 +63,27 @@ internal sealed partial class AchievementService : IAchievementService
return ArchiveAddResultKind.InvalidName;
}
ArgumentNullException.ThrowIfNull(archivesView);
ArgumentNullException.ThrowIfNull(archives);
if (archivesView.SourceCollection.Any(a => a.Name == newArchive.Name))
if (archives.SourceCollection.Any(a => a.Name == newArchive.Name))
{
return ArchiveAddResultKind.AlreadyExists;
}
await taskContext.SwitchToMainThreadAsync();
archivesView.Add(newArchive);
archivesView.MoveCurrentTo(newArchive);
archives.Add(newArchive);
archives.MoveCurrentTo(newArchive);
return ArchiveAddResultKind.Added;
}
public async ValueTask RemoveArchiveAsync(AchievementArchive archive)
{
ArgumentNullException.ThrowIfNull(archivesView);
ArgumentNullException.ThrowIfNull(archives);
// Sync cache
await taskContext.SwitchToMainThreadAsync();
archivesView.Remove(archive);
archives.Remove(archive);
// Sync database
await taskContext.SwitchToBackgroundAsync();

View File

@@ -10,9 +10,9 @@ namespace Snap.Hutao.Service.Achievement;
internal interface IAchievementService
{
AdvancedDbCollectionView<EntityArchive> Archives { get; }
ValueTask<IAdvancedDbCollectionView<EntityArchive>> GetArchivesAsync(CancellationToken token = default);
ValueTask<UIAF> ExportToUIAFAsync(EntityArchive selectedArchive);
ValueTask<UIAF> ExportToUIAFAsync(EntityArchive archive);
List<AchievementView> GetAchievementViewList(EntityArchive archive, AchievementServiceMetadataContext context);

View File

@@ -13,10 +13,6 @@ using ModelItem = Snap.Hutao.Model.Item;
namespace Snap.Hutao.Service.Cultivation;
/// <summary>
/// 养成计算服务
/// </summary>
[HighQuality]
[ConstructorGenerated]
[Injection(InjectAs.Singleton, typeof(ICultivationService))]
internal sealed partial class CultivationService : ICultivationService
@@ -126,19 +122,17 @@ internal sealed partial class CultivationService : ICultivationService
return true;
}
await taskContext.SwitchToMainThreadAsync();
if (Projects.CurrentItem is null)
{
Projects.MoveCurrentTo(Projects.SourceCollection.SelectedOrDefault());
if (Projects.CurrentItem is null)
{
return false;
}
}
await taskContext.SwitchToBackgroundAsync();
if (Projects?.CurrentItem is null)
{
// Initialize
_ = Projects;
}
if (Projects?.CurrentItem is null)
{
return false;
}
CultivateEntry? entry = cultivationDbService.GetCultivateEntryByProjectIdAndItemId(Projects.CurrentItem.InnerId, itemId);
if (entry is null)

View File

@@ -5,6 +5,7 @@
<Visibility x:Key="VisibilityVisible">Visible</Visibility>
<Visibility x:Key="VisibilityCollapsed">Collapsed</Visibility>
<Duration x:Key="StandardViewOpacityAnimationDuration">0:0:0.5</Duration>
<CubicEase x:Key="CubicEaseFunction"/>
<Style BasedOn="{StaticResource DefaultStandardViewStyle}" TargetType="shuxc:StandardView"/>
@@ -34,7 +35,7 @@
Storyboard.TargetName="PartEmptyContent"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:0.3"/>
Duration="{StaticResource StandardViewOpacityAnimationDuration}"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PartEmptyContent" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource VisibilityCollapsed}"/>
</ObjectAnimationUsingKeyFrames>
@@ -46,7 +47,7 @@
Storyboard.TargetName="PartContent"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0.3"/>
Duration="{StaticResource StandardViewOpacityAnimationDuration}"/>
</Storyboard>
</VisualState>
@@ -57,7 +58,7 @@
Storyboard.TargetName="PartContent"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:0.3"/>
Duration="{StaticResource StandardViewOpacityAnimationDuration}"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PartContent" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource VisibilityCollapsed}"/>
</ObjectAnimationUsingKeyFrames>
@@ -69,7 +70,7 @@
Storyboard.TargetName="PartEmptyContent"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0.3"/>
Duration="{StaticResource StandardViewOpacityAnimationDuration}"/>
</Storyboard>
</VisualState>
@@ -80,7 +81,7 @@
Storyboard.TargetName="PartContent"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:0.3"/>
Duration="{StaticResource StandardViewOpacityAnimationDuration}"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PartContent" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource VisibilityCollapsed}"/>
</ObjectAnimationUsingKeyFrames>
@@ -90,7 +91,7 @@
Storyboard.TargetName="PartEmptyContent"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:0.3"/>
Duration="{StaticResource StandardViewOpacityAnimationDuration}"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PartEmptyContent" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource VisibilityCollapsed}"/>
</ObjectAnimationUsingKeyFrames>

View File

@@ -107,7 +107,11 @@ internal class AdvancedCollectionView<T> : IAdvancedCollectionView<T>, INotifyPr
set => MoveCurrentTo(value);
}
public int CurrentPosition { get; private set; }
public int CurrentPosition
{
get;
private set;
}
public bool HasMoreItems
{
@@ -633,6 +637,7 @@ internal class AdvancedCollectionView<T> : IAdvancedCollectionView<T>, INotifyPr
if (itemIndex <= CurrentPosition)
{
CurrentPosition--;
OnPropertyChanged(nameof(CurrentItem));
}
OnVectorChanged(new VectorChangedEventArgs(CollectionChange.ItemRemoved, itemIndex, item));
@@ -650,13 +655,14 @@ internal class AdvancedCollectionView<T> : IAdvancedCollectionView<T>, INotifyPr
private bool MoveCurrentToIndex(int i)
{
if (i < -1 || i >= view.Count)
if (i == CurrentPosition)
{
return false;
}
if (i == CurrentPosition)
if (i < -1 || i >= view.Count)
{
OnPropertyChanged(nameof(CurrentItem));
return false;
}

View File

@@ -191,7 +191,7 @@
<shuxb:InvokeCommandOnLoadedBehavior Command="{Binding LoadCommand}"/>
</mxi:Interaction.Behaviors>
<shuxc:StandardView HideCondition="{Binding IsInitialized, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" ShowCondition="{Binding Achievements, Converter={StaticResource EmptyObjectToBoolConverter}, Mode=OneWay}">
<shuxc:StandardView HideCondition="{Binding IsInitialized, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" ShowCondition="{Binding Archives.CurrentItem, Converter={StaticResource EmptyObjectToBoolConverter}, Mode=OneWay}">
<shuxc:StandardView.EmptyContent>
<Border
HorizontalAlignment="Center"

View File

@@ -419,7 +419,7 @@
HorizontalAlignment="Center"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{shuxm:ResourceString Name=ViewPageLaunchGameSelectGamePath}"/>
<Border Style="{ThemeResource BorderCardStyle}">
<Border Style="{ThemeResource BorderCardStyle}" Visibility="{Binding GamePathEntries.Count, Converter={StaticResource Int32ToVisibilityConverter}}">
<ListView
ItemTemplate="{StaticResource GamePathEntryListTemplate}"
ItemsSource="{Binding GamePathEntries}"

View File

@@ -21,7 +21,7 @@ internal sealed partial class AchievementImporter
public async ValueTask<bool> FromClipboardAsync(AchievementViewModelScopeContext context)
{
if (context.AchievementService.Archives.CurrentItem is not { } archive)
if (await context.AchievementService.GetArchivesAsync().ConfigureAwait(false) is not { CurrentItem: { } archive })
{
scopeContext.InfoBarService.Warning(SH.ViewModelImportWarningTitle, SH.ViewModelImportWarningMessage2);
return false;
@@ -38,7 +38,7 @@ internal sealed partial class AchievementImporter
public async ValueTask<bool> FromFileAsync(AchievementViewModelScopeContext context)
{
if (context.AchievementService.Archives.CurrentItem is not { } archive)
if (await context.AchievementService.GetArchivesAsync().ConfigureAwait(false) is not { CurrentItem: { } archive })
{
scopeContext.InfoBarService.Warning(SH.ViewModelImportWarningTitle, SH.ViewModelImportWarningMessage2);
return false;

View File

@@ -16,7 +16,7 @@ using Snap.Hutao.Service.Notification;
using Snap.Hutao.UI.Xaml.Data;
using Snap.Hutao.UI.Xaml.View.Dialog;
using System.Text.RegularExpressions;
using EntityAchievementArchive = Snap.Hutao.Model.Entity.AchievementArchive;
using EntityArchive = Snap.Hutao.Model.Entity.AchievementArchive;
using MetadataAchievementGoal = Snap.Hutao.Model.Metadata.Achievement.AchievementGoal;
namespace Snap.Hutao.ViewModel.Achievement;
@@ -36,13 +36,13 @@ internal sealed partial class AchievementViewModel : Abstraction.ViewModel, INav
private AdvancedCollectionView<AchievementView>? achievements;
private AdvancedCollectionView<AchievementGoalView>? achievementGoals;
private AdvancedDbCollectionView<EntityAchievementArchive>? archives;
private IAdvancedDbCollectionView<EntityArchive>? archives;
private bool isUncompletedItemsFirst = true;
private string searchText = string.Empty;
private string? finishDescription;
public AdvancedDbCollectionView<EntityAchievementArchive>? Archives
public IAdvancedDbCollectionView<EntityArchive>? Archives
{
get => archives;
set
@@ -137,10 +137,11 @@ internal sealed partial class AchievementViewModel : Abstraction.ViewModel, INav
sortedGoals = goals.SortBy(goal => goal.Order).SelectList(AchievementGoalView.From);
}
IAdvancedDbCollectionView<EntityArchive> archives = await scopeContext.AchievementService.GetArchivesAsync(CancellationToken).ConfigureAwait(false);
await scopeContext.TaskContext.SwitchToMainThreadAsync();
AchievementGoals = new(sortedGoals, true);
Archives = scopeContext.AchievementService.Archives;
Archives = archives;
Archives.MoveCurrentTo(Archives.SourceCollection.SelectedOrDefault());
return true;
}
@@ -183,7 +184,7 @@ internal sealed partial class AchievementViewModel : Abstraction.ViewModel, INav
return;
}
switch (await scopeContext.AchievementService.AddArchiveAsync(EntityAchievementArchive.From(name)).ConfigureAwait(false))
switch (await scopeContext.AchievementService.AddArchiveAsync(EntityArchive.From(name)).ConfigureAwait(false))
{
case ArchiveAddResultKind.Added:
await scopeContext.TaskContext.SwitchToMainThreadAsync();
@@ -225,9 +226,6 @@ internal sealed partial class AchievementViewModel : Abstraction.ViewModel, INav
{
await scopeContext.AchievementService.RemoveArchiveAsync(current).ConfigureAwait(false);
}
await scopeContext.TaskContext.SwitchToMainThreadAsync();
Archives.MoveCurrentToFirstOrDefault();
}
catch (OperationCanceledException)
{
@@ -281,7 +279,7 @@ internal sealed partial class AchievementViewModel : Abstraction.ViewModel, INav
}
}
private async ValueTask UpdateAchievementsAsync(EntityAchievementArchive? archive)
private async ValueTask UpdateAchievementsAsync(EntityArchive? archive)
{
// TODO: immediately clear values
if (archive is null)
@@ -305,7 +303,7 @@ internal sealed partial class AchievementViewModel : Abstraction.ViewModel, INav
UpdateAchievementsSort();
}
private bool TryGetAchievements(EntityAchievementArchive archive, AchievementServiceMetadataContext context, [NotNullWhen(true)] out List<AchievementView>? combined)
private bool TryGetAchievements(EntityArchive archive, AchievementServiceMetadataContext context, [NotNullWhen(true)] out List<AchievementView>? combined)
{
try
{

View File

@@ -73,7 +73,7 @@ internal sealed partial class CultivationViewModel : Abstraction.ViewModel
{
await taskContext.SwitchToMainThreadAsync();
Projects = cultivationService.Projects;
Projects.CurrentItem = Projects.SourceCollection.SelectedOrDefault();
Projects.MoveCurrentTo(Projects.SourceCollection.SelectedOrDefault());
return true;
}