launch screenshot folder

This commit is contained in:
DismissedLight
2023-03-10 20:32:49 +08:00
parent c71ecd89e3
commit 8ee2908633
29 changed files with 139 additions and 35 deletions

View File

@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using System.IO;
using Windows.ApplicationModel.DataTransfer;
using Windows.Storage.Streams;
@@ -51,7 +52,7 @@ internal static class Clipboard
/// 设置位图
/// </summary>
/// <param name="stream">位图流</param>
public static void SetBitmapStream(IRandomAccessStream stream)
public static void SetBitmap(IRandomAccessStream stream)
{
RandomAccessStreamReference reference = RandomAccessStreamReference.CreateFromStream(stream);
DataPackage content = new() { RequestedOperation = DataPackageOperation.Copy };
@@ -59,4 +60,16 @@ internal static class Clipboard
Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(content);
Windows.ApplicationModel.DataTransfer.Clipboard.Flush();
}
/// <summary>
/// 设置位图
/// </summary>
/// <param name="file">文件</param>
public static void SetBitmap(string file)
{
using (IRandomAccessStream stream = File.OpenRead(file).AsRandomAccessStream())
{
SetBitmap(stream);
}
}
}

View File

@@ -270,7 +270,7 @@ internal static class Activation
private static async Task HandleLaunchGameActionAsync(string? uid = null)
{
Ioc.Default.GetRequiredService<IMemoryCache>().Set(ViewModel.LaunchGameViewModel.DesiredUid, uid);
Ioc.Default.GetRequiredService<IMemoryCache>().Set(ViewModel.Game.LaunchGameViewModel.DesiredUid, uid);
await ThreadHelper.SwitchToMainThreadAsync();
if (!MainWindow.IsPresent)

View File

@@ -18,7 +18,7 @@ internal static class Must
/// <param name="message">message</param>
/// <param name="parameterName">The name of the parameter to blame in the exception, if thrown.</param>
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Argument([DoesNotReturnIf(false)] bool condition, string? message, [CallerArgumentExpression("condition")] string? parameterName = null)
public static void Argument([DoesNotReturnIf(false)] bool condition, string? message, [CallerArgumentExpression(nameof(condition))] string? parameterName = null)
{
if (!condition)
{
@@ -33,7 +33,7 @@ internal static class Must
/// <param name="message">message</param>
/// <param name="parameterName">The name of the parameter to blame in the exception, if thrown.</param>
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Range([DoesNotReturnIf(false)] bool condition, string? message, [CallerArgumentExpression("condition")] string? parameterName = null)
public static void Range([DoesNotReturnIf(false)] bool condition, string? message, [CallerArgumentExpression(nameof(condition))] string? parameterName = null)
{
if (!condition)
{
@@ -62,7 +62,7 @@ internal static class Must
/// <returns>The value of the parameter.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is <c>null</c>.</exception>
[MethodImpl(MethodImplOptions.NoInlining)]
public static T NotNull<T>([NotNull] T value, [CallerArgumentExpression("value")] string? parameterName = null)
public static T NotNull<T>([NotNull] T value, [CallerArgumentExpression(nameof(value))] string? parameterName = null)
where T : class // ensures value-types aren't passed to a null checking method
{
return value ?? throw new ArgumentNullException(parameterName);

View File

@@ -7,10 +7,10 @@
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
xmlns:shcm="using:Snap.Hutao.Control.Markup"
xmlns:shv="using:Snap.Hutao.ViewModel"
xmlns:shvg="using:Snap.Hutao.ViewModel.Game"
mc:Ignorable="d">
<Grid Name="RootGrid" d:DataContext="{d:DesignInstance shv:LaunchGameViewModel}">
<Grid Name="RootGrid" d:DataContext="{d:DesignInstance shvg:LaunchGameViewModel}">
<mxi:Interaction.Behaviors>
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>

View File

@@ -4,7 +4,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml;
using Snap.Hutao.Core.Windowing;
using Snap.Hutao.ViewModel;
using Snap.Hutao.ViewModel.Game;
using Windows.Graphics;
using Windows.Win32.UI.WindowsAndMessaging;

View File

@@ -69,6 +69,7 @@ public static partial class Program
.AddDatabase()
.AddInjections()
.AddHttpClients()
// Discrete services
.AddSingleton<IMessenger>(WeakReferenceMessenger.Default)

View File

@@ -3921,6 +3921,15 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 打开截图文件夹 的本地化字符串。
/// </summary>
internal static string ViewPageOpenScreenshotFolderAction {
get {
return ResourceManager.GetString("ViewPageOpenScreenshotFolderAction", resourceCulture);
}
}
/// <summary>
/// 查找类似 关于 胡桃 的本地化字符串。
/// </summary>

View File

@@ -1404,6 +1404,9 @@
<data name="ViewPageLoginMihoyoUserTitle" xml:space="preserve">
<value>在下方登录米哈游通行证</value>
</data>
<data name="ViewPageOpenScreenshotFolderAction" xml:space="preserve">
<value>打开截图文件夹</value>
</data>
<data name="ViewPageSettingAboutHeader" xml:space="preserve">
<value>关于 胡桃</value>
</data>

View File

@@ -45,9 +45,9 @@ internal sealed class GachaStatisticsFactory : IGachaStatisticsFactory
Dictionary<string, Avatar> nameAvatarMap = await metadataService.GetNameToAvatarMapAsync().ConfigureAwait(false);
Dictionary<string, Weapon> nameWeaponMap = await metadataService.GetNameToWeaponMapAsync().ConfigureAwait(false);
List<GachaEvent> gachaevents = await metadataService.GetGachaEventsAsync().ConfigureAwait(false);
List<GachaEvent> gachaEvents = await metadataService.GetGachaEventsAsync().ConfigureAwait(false);
List<HistoryWishBuilder> historyWishBuilders = gachaevents.Select(g => new HistoryWishBuilder(g, nameAvatarMap, nameWeaponMap)).ToList();
List<HistoryWishBuilder> historyWishBuilders = gachaEvents.Select(g => new HistoryWishBuilder(g, nameAvatarMap, nameWeaponMap)).ToList();
SettingEntry entry = await appDbContext.Settings
.SingleOrAddAsync(SettingEntry.IsEmptyHistoryWishVisible, Core.StringLiterals.True)

View File

@@ -253,12 +253,12 @@ internal sealed class GachaLogService : IGachaLogService
{
state.ConfigType = configType;
long? dbEndId = null;
GachaLogQueryOptions configration = new(query, configType);
GachaLogQueryOptions options = new(query, configType);
List<GachaItem> itemsToAdd = new();
do
{
Response<GachaLogPage> response = await gachaInfoClient.GetGachaLogPageAsync(configration, token).ConfigureAwait(false);
Response<GachaLogPage> response = await gachaInfoClient.GetGachaLogPageAsync(options, token).ConfigureAwait(false);
if (response.IsOk())
{
@@ -277,7 +277,7 @@ internal sealed class GachaLogService : IGachaLogService
{
itemsToAdd.Add(GachaItem.Create(archive.InnerId, item, GetItemId(item)));
state.Items.Add(GetItemBaseByName(item.Name, item.ItemType));
configration.EndId = item.Id;
options.EndId = item.Id;
}
else
{
@@ -311,7 +311,7 @@ internal sealed class GachaLogService : IGachaLogService
}
token.ThrowIfCancellationRequested();
SaveGachaItems(itemsToAdd, isLazy, archive, configration.EndId);
SaveGachaItems(itemsToAdd, isLazy, archive, options.EndId);
await RandomDelayAsync(token).ConfigureAwait(false);
}

View File

@@ -8,7 +8,6 @@ using Snap.Hutao.Core;
using Snap.Hutao.Core.Database;
using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Core.IO.Ini;
using Snap.Hutao.Model.Binding.LaunchGame;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Database;
using Snap.Hutao.Service.Game.Locator;

View File

@@ -1,7 +1,6 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Binding.LaunchGame;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Service.Game.Package;
using System.Collections.ObjectModel;

View File

@@ -3,7 +3,7 @@
using System.Collections.Immutable;
namespace Snap.Hutao.Model.Binding.LaunchGame;
namespace Snap.Hutao.Service.Game;
/// <summary>
/// 启动方案

View File

@@ -4,7 +4,6 @@
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Core.IO;
using Snap.Hutao.Model.Binding.LaunchGame;
using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher;
using System.IO;
using System.IO.Compression;

View File

@@ -23,7 +23,6 @@ namespace Snap.Hutao.Service.Metadata;
internal sealed partial class MetadataService : IMetadataService, IMetadataServiceInitialization
{
private const string MetaFileName = "Meta.json";
private readonly string metadataFolderPath;
private readonly IInfoBarService infoBarService;
private readonly HttpClient httpClient;

View File

@@ -433,6 +433,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Control\Extension\" />
<Folder Include="Model\Binding\LaunchGame\" />
</ItemGroup>
<ItemGroup>
<Compile Update="Resource\Localization\SH.Designer.cs">

View File

@@ -2,7 +2,6 @@
x:Class="Snap.Hutao.View.Page.LaunchGamePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cwub="using:CommunityToolkit.WinUI.UI.Behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
@@ -11,10 +10,10 @@
xmlns:shc="using:Snap.Hutao.Control"
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
xmlns:shcm="using:Snap.Hutao.Control.Markup"
xmlns:shv="using:Snap.Hutao.ViewModel"
xmlns:shvc="using:Snap.Hutao.View.Control"
xmlns:shvg="using:Snap.Hutao.ViewModel.Game"
xmlns:wsc="using:WinUICommunity.SettingsUI.Controls"
d:DataContext="{d:DesignInstance shv:LaunchGameViewModel}"
d:DataContext="{d:DesignInstance shvg:LaunchGameViewModel}"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
@@ -25,6 +24,7 @@
<Page.Resources>
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
<Visibility x:Key="VisibilityCollapsed">Collapsed</Visibility>
<Style BasedOn="{StaticResource SettingButtonStyle}" TargetType="Button">
<Setter Property="MinWidth" Value="156"/>
</Style>
@@ -44,6 +44,10 @@
<Pivot>
<Pivot.RightHeader>
<CommandBar DefaultLabelPosition="Right">
<AppBarButton
Command="{Binding OpenScreenshotFolderCommand}"
Icon="{shcm:FontIcon Glyph=&#xED25;}"
Label="{shcm:ResourceString Name=ViewPageOpenScreenshotFolderAction}"/>
<AppBarButton
Command="{Binding LaunchCommand}"
Icon="{shcm:FontIcon Glyph=&#xE7FC;}"

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Control;
using Snap.Hutao.ViewModel;
using Snap.Hutao.ViewModel.Game;
namespace Snap.Hutao.View.Page;

View File

@@ -105,7 +105,6 @@
Header="{shcm:ResourceString Name=ViewPageSettingApperanceLanguageHeader}"
Icon="&#xF2B7;">
<ComboBox
MinWidth="180"
DisplayMemberPath="Name"
ItemsSource="{Binding Cultures}"
SelectedItem="{Binding SelectedCulture, Mode=TwoWay}"/>

View File

@@ -284,7 +284,7 @@ internal sealed class AvatarPropertyViewModel : Abstraction.ViewModel, IRecipien
try
{
Clipboard.SetBitmapStream(memory);
Clipboard.SetBitmap(memory);
clipboardOpened = true;
}
catch (COMException)

View File

@@ -1,6 +1,9 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo;
namespace Snap.Hutao.ViewModel.GachaLog;
/// <summary>

View File

@@ -15,4 +15,4 @@ internal sealed class StatisticsItem : Item
/// 获取物品的个数
/// </summary>
public int Count { get; set; }
}
}

View File

@@ -43,4 +43,4 @@ internal sealed class SummaryItem : Item
/// 获取时间
/// </summary>
internal DateTimeOffset Time { get; set; }
}
}

View File

@@ -7,9 +7,7 @@ using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Control.Extension;
using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Core.LifeCycle;
using Snap.Hutao.Model.Binding.LaunchGame;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Database;
using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.Service.Game;
using Snap.Hutao.Service.Navigation;
@@ -20,7 +18,7 @@ using Snap.Hutao.Web.Hoyolab.Takumi.Binding;
using System.Collections.ObjectModel;
using System.IO;
namespace Snap.Hutao.ViewModel;
namespace Snap.Hutao.ViewModel.Game;
/// <summary>
/// 启动游戏视图模型
@@ -61,6 +59,7 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
ModifyGameAccountCommand = new AsyncRelayCommand<GameAccount>(ModifyGameAccountAsync);
RemoveGameAccountCommand = new AsyncRelayCommand<GameAccount>(RemoveGameAccountAsync);
AttachGameAccountCommand = new RelayCommand<GameAccount>(AttachGameAccountToCurrentUserGameRole);
OpenScreenshotFolderCommand = new AsyncRelayCommand(OpenScreenshotFolderAsync);
}
/// <summary>
@@ -136,10 +135,14 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
/// </summary>
public ICommand AttachGameAccountCommand { get; }
/// <summary>
/// 打开截图文件夹命令
/// </summary>
public ICommand OpenScreenshotFolderCommand { get; }
/// <inheritdoc/>
protected override async Task OpenUIAsync()
{
await ThreadHelper.SwitchToBackgroundAsync();
if (File.Exists(gameService.GetGamePathSkipLocator()))
{
try
@@ -149,7 +152,6 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
MultiChannel multi = gameService.GetMultiChannel();
if (string.IsNullOrEmpty(multi.ConfigFilePath))
{
await ThreadHelper.SwitchToMainThreadAsync();
SelectedScheme = KnownSchemes.FirstOrDefault(s => s.Channel == multi.Channel && s.SubChannel == multi.SubChannel);
}
else
@@ -161,6 +163,7 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
await ThreadHelper.SwitchToMainThreadAsync();
GameAccounts = accounts;
// Sync uid
if (memoryCache.TryGetValue(DesiredUid, out object? value) && value is string uid)
{
@@ -294,4 +297,14 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
await gameService.RemoveGameAccountAsync(gameAccount).ConfigureAwait(false);
}
}
private async Task OpenScreenshotFolderAsync()
{
string game = gameService.GetGamePathSkipLocator();
string screenshot = Path.Combine(Path.GetDirectoryName(game)!, "ScreenShot");
if (Directory.Exists(screenshot))
{
await Windows.System.Launcher.LaunchFolderPathAsync(screenshot);
}
}
}

View File

@@ -0,0 +1,31 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Binding;
using Snap.Hutao.Service.Game;
using System.IO;
using System.Text;
namespace Snap.Hutao.ViewModel.Game;
/// <summary>
/// 截图
/// </summary>
internal sealed class Screenshot : INameIcon
{
/// <summary>
/// 构造一个新的截图
/// </summary>
/// <param name="path">路径</param>
public Screenshot(string path)
{
Name = $"{new FileInfo(path).CreationTime}";
Icon = path.ToUri();
}
/// <inheritdoc/>
public string Name { get; }
/// <inheritdoc/>
public Uri Icon { get; }
}

View File

@@ -0,0 +1,28 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Service.Game;
namespace Snap.Hutao.ViewModel.Game;
/// <summary>
/// 截图视图模型
/// </summary>
[Injection(InjectAs.Scoped)]
internal sealed class ScreenshotViewModel : Abstraction.ViewModel
{
/// <summary>
/// 构造一个新的截图视图模型
/// </summary>
/// <param name="gameService">游戏服务</param>
public ScreenshotViewModel(IGameService gameService)
{
}
/// <inheritdoc/>
protected override async Task OpenUIAsync()
{
}
}

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Service.Game;
using Snap.Hutao.Web.Hoyolab;
namespace Snap.Hutao.Web;
@@ -320,7 +321,7 @@ internal static class ApiEndpoints
/// </summary>
/// <param name="scheme">启动方案</param>
/// <returns>启动器资源字符串</returns>
public static string SdkStaticLauncherResource(Model.Binding.LaunchGame.LaunchScheme scheme)
public static string SdkStaticLauncherResource(LaunchScheme scheme)
{
return $"{SdkStaticLauncherApi}/resource?key={scheme.Key}&launcher_id={scheme.LauncherId}&channel_id={scheme.Channel}&sub_channel_id={scheme.SubChannel}";
}

View File

@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Service.Game;
namespace Snap.Hutao.Web;
/// <summary>
@@ -31,7 +33,7 @@ internal static class ApiOsEndpoints
/// </summary>
/// <param name="scheme">启动方案</param>
/// <returns>启动器资源字符串</returns>
public static string SdkOsStaticLauncherResource(Model.Binding.LaunchGame.LaunchScheme scheme)
public static string SdkOsStaticLauncherResource(LaunchScheme scheme)
{
return $"{SdkOsStaticLauncherApi}/resource?key={scheme.Key}&launcher_id={scheme.LauncherId}&channel_id={scheme.Channel}&sub_channel_id={scheme.SubChannel}";
}

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
using Snap.Hutao.Model.Binding.LaunchGame;
using Snap.Hutao.Service.Game;
using Snap.Hutao.Web.Response;
using System.Net.Http;