Compare commits

..

7 Commits
1.9.0 ... 1.9.1

Author SHA1 Message Date
DismissedLight
b11526761e Merge pull request #1214 from DGP-Studio/develop 2023-12-23 19:19:45 +08:00
DismissedLight
d293149672 1.9.1 package 2023-12-23 19:18:29 +08:00
DismissedLight
3784df67a3 adjust launch page ui 2023-12-23 19:15:04 +08:00
DismissedLight
4aaca4d19f fix reentrant issue 2023-12-23 18:51:41 +08:00
DismissedLight
e6cf39831d fix daily note fetch uid crash 2023-12-23 18:22:12 +08:00
DismissedLight
24a2a18760 fix #1212 2023-12-23 17:34:44 +08:00
DismissedLight
d8dce5c062 empty sha256 tolerance 2023-12-23 14:48:24 +08:00
10 changed files with 37 additions and 44 deletions

View File

@@ -31,4 +31,5 @@
<x:String x:Key="UI_EmotionIcon250">https://api.snapgenshin.com/static/raw/EmotionIcon/UI_EmotionIcon250.png</x:String>
<x:String x:Key="UI_EmotionIcon272">https://api.snapgenshin.com/static/raw/EmotionIcon/UI_EmotionIcon272.png</x:String>
<x:String x:Key="UI_EmotionIcon293">https://api.snapgenshin.com/static/raw/EmotionIcon/UI_EmotionIcon293.png</x:String>
<x:String x:Key="UI_EmotionIcon445">https://api.snapgenshin.com/static/raw/EmotionIcon/UI_EmotionIcon445.png</x:String>
</ResourceDictionary>

View File

@@ -1,19 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
namespace Snap.Hutao.Core.Threading;
internal sealed class Throttler
{
private readonly ConcurrentDictionary<string, SemaphoreSlim> methodSemaphoreMap = new();
public ValueTask<SemaphoreSlimToken> ThrottleAsync(CancellationToken token = default, [CallerMemberName] string callerName = default!, [CallerLineNumber] int callerLine = 0)
{
string key = $"{callerName}L{callerLine}";
SemaphoreSlim semaphore = methodSemaphoreMap.GetOrAdd(key, name => new SemaphoreSlim(1));
return semaphore.EnterAsync(token);
}
}

View File

@@ -12,7 +12,7 @@
<Identity
Name="60568DGPStudio.SnapHutao"
Publisher="CN=35C8E923-85DF-49A7-9172-B39DC6312C52"
Version="1.9.0.0" />
Version="1.9.1.0" />
<Properties>
<DisplayName>Snap Hutao</DisplayName>

View File

@@ -12,7 +12,7 @@
<Identity
Name="60568DGPStudio.SnapHutaoDev"
Publisher="CN=35C8E923-85DF-49A7-9172-B39DC6312C52"
Version="1.9.0.0" />
Version="1.9.1.0" />
<Properties>
<DisplayName>Snap Hutao Dev</DisplayName>

View File

@@ -2144,6 +2144,9 @@
<data name="ViewPageLaunchGameResourcePreDownloadHeader" xml:space="preserve">
<value>预下载</value>
</data>
<data name="ViewPageLaunchGameSelectGamePath" xml:space="preserve">
<value>选择游戏路径</value>
</data>
<data name="ViewPageLaunchGameSwitchAccountAttachUidNull" xml:space="preserve">
<value>该账号尚未绑定实时便笺通知 UID</value>
</data>

View File

@@ -77,7 +77,7 @@ internal sealed partial class DailyNoteService : IDailyNoteService, IRecipient<U
List<DailyNoteEntry> entryList = await dailyNoteDbService.GetDailyNoteEntryIncludeUserListAsync().ConfigureAwait(false);
entryList.ForEach(entry => { entry.UserGameRole = userService.GetUserGameRoleByUid(entry.Uid); });
entries = new(entryList);
entries = entryList.ToObservableCollection();
}
return entries;

View File

@@ -49,7 +49,7 @@ internal sealed partial class UpdateService : IUpdateService
progress.Report(new(versionInformation.Version.ToString(), 0, 0));
if (versionInformation.Sha256 is not { } sha256)
if (versionInformation.Sha256 is not { Length: > 0 } sha256)
{
return false;
}

View File

@@ -14,7 +14,7 @@ namespace Snap.Hutao.Service.User;
[ConstructorGenerated]
[Injection(InjectAs.Singleton, typeof(IUserCollectionService))]
internal sealed partial class UserCollectionService : IUserCollectionService
internal sealed partial class UserCollectionService : IUserCollectionService, IDisposable
{
private readonly ScopedDbCurrent<BindingUser, Model.Entity.User, UserChangedMessage> dbCurrent;
private readonly IUserInitializationService userInitializationService;
@@ -22,7 +22,7 @@ internal sealed partial class UserCollectionService : IUserCollectionService
private readonly ITaskContext taskContext;
private readonly IMessenger messenger;
private readonly Throttler throttler = new();
private readonly SemaphoreSlim throttler = new(1);
private ObservableCollection<BindingUser>? userCollection;
private Dictionary<string, BindingUser>? midUserMap;
@@ -38,7 +38,9 @@ internal sealed partial class UserCollectionService : IUserCollectionService
public async ValueTask<ObservableCollection<BindingUser>> GetUserCollectionAsync()
{
using (await throttler.ThrottleAsync().ConfigureAwait(false))
// Force run in background thread, otherwise will cause reentrance
await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
using (await throttler.EnterAsync().ConfigureAwait(false))
{
if (userCollection is null)
{
@@ -131,17 +133,7 @@ internal sealed partial class UserCollectionService : IUserCollectionService
return default;
}
try
{
return uidUserGameRoleMap[uid];
}
catch (InvalidOperationException)
{
// Sequence contains more than one matching element
// TODO: return a specialize UserGameRole to indicate error
}
return default;
return uidUserGameRoleMap.GetValueOrDefault(uid);
}
public bool TryGetUserByMid(string mid, [NotNullWhen(true)] out BindingUser? user)
@@ -186,4 +178,9 @@ internal sealed partial class UserCollectionService : IUserCollectionService
ArgumentNullException.ThrowIfNull(newUser.UserInfo);
return new(UserOptionResult.Added, newUser.UserInfo.Uid);
}
public void Dispose()
{
throttler.Dispose();
}
}

View File

@@ -13,6 +13,7 @@
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
xmlns:shccs="using:Snap.Hutao.Control.Collection.Selector"
xmlns:shch="using:Snap.Hutao.Control.Helper"
xmlns:shci="using:Snap.Hutao.Control.Image"
xmlns:shcm="using:Snap.Hutao.Control.Markup"
xmlns:shvc="using:Snap.Hutao.View.Control"
xmlns:shvg="using:Snap.Hutao.ViewModel.Game"
@@ -346,10 +347,20 @@
</Grid>
<Grid Visibility="{Binding GamePathSelectedAndValid, Converter={StaticResource BoolToVisibilityRevertConverter}}">
<StackPanel
MaxWidth="600"
Margin="128,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="3">
<shci:CachedImage
Width="120"
Height="120"
EnableLazyLoading="False"
Source="{StaticResource UI_EmotionIcon445}"/>
<TextBlock
Margin="0,5,0,21"
HorizontalAlignment="Center"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageLaunchGameSelectGamePath}"/>
<Border Style="{ThemeResource BorderCardStyle}">
<ListView
ItemTemplate="{StaticResource GamePathEntryListTemplate}"

View File

@@ -136,17 +136,17 @@
Background="{ThemeResource SystemFillColorSuccessBackgroundBrush}"
Description="{shcm:ResourceString Name=ViewPageSettingHutaoPassportLicensedDeveloperDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingHutaoPassportLicensedDeveloperHeader}"
Visibility="{Binding UserOptions.IsLicensedDeveloper, Converter={StaticResource BoolToVisibilityConverter}}"/>
<cwc:SettingsCard
Background="{ThemeResource SystemFillColorSuccessBackgroundBrush}"
Description="{shcm:ResourceString Name=ViewPageSettingHutaoPassportMaintainerDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingHutaoPassportMaintainerHeader}"
Visibility="{Binding UserOptions.IsMaintainer, Converter={StaticResource BoolToVisibilityConverter}}">
Visibility="{Binding UserOptions.IsLicensedDeveloper, Converter={StaticResource BoolToVisibilityConverter}}">
<Button
Command="{Binding OpenTestPageCommand}"
Content="TEST"
Style="{ThemeResource SettingButtonStyle}"/>
</cwc:SettingsCard>
<cwc:SettingsCard
Background="{ThemeResource SystemFillColorSuccessBackgroundBrush}"
Description="{shcm:ResourceString Name=ViewPageSettingHutaoPassportMaintainerDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingHutaoPassportMaintainerHeader}"
Visibility="{Binding UserOptions.IsMaintainer, Converter={StaticResource BoolToVisibilityConverter}}"/>
<cwc:SettingsCard Description="{Binding UserOptions.GachaLogExpireAtSlim}" Header="{shcm:ResourceString Name=ViewPageSettingHutaoPassportGachaLogExpiredAtHeader}"/>
<cwc:SettingsCard
Command="{Binding Passport.OpenRedeemWebsiteCommand}"