mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
Compare commits
9 Commits
1.7.14
...
UnsafeCore
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c03ce3486 | ||
|
|
83e187ea9e | ||
|
|
d86232f413 | ||
|
|
4e6691ac51 | ||
|
|
84ad39b192 | ||
|
|
ce50fc41e0 | ||
|
|
1d71048f56 | ||
|
|
08cf823156 | ||
|
|
cca65635a6 |
27
.github/ISSUE_TEMPLATE/CHS-feature-request.yml
vendored
27
.github/ISSUE_TEMPLATE/CHS-feature-request.yml
vendored
@@ -1,27 +0,0 @@
|
||||
name: 功能请求
|
||||
description: 通过这个议题来向开发团队分享你的想法
|
||||
title: "[Feat]: 在这里填写一个合适的标题"
|
||||
labels: ["功能", "priority:none"]
|
||||
assignees:
|
||||
- Lightczx
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
请按下方的要求填写完整的问题表单。
|
||||
|
||||
- type: textarea
|
||||
id: back
|
||||
attributes:
|
||||
label: 背景与动机
|
||||
description: 添加此功能的理由,如果你想要实现多个功能,请分别发起多个单独的议题
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: req
|
||||
attributes:
|
||||
label: 想要实现或优化的功能
|
||||
description: 详细的描述一下你想要的功能,描述的越具体,采纳的可能性越高
|
||||
validations:
|
||||
required: true
|
||||
27
.github/ISSUE_TEMPLATE/ENG-feature-request.yml
vendored
27
.github/ISSUE_TEMPLATE/ENG-feature-request.yml
vendored
@@ -1,27 +0,0 @@
|
||||
name: Feature Request [English Form]
|
||||
description: Tell us about your thought
|
||||
title: "[Feat]: Place your title here"
|
||||
labels: ["功能", "priority:none"]
|
||||
assignees:
|
||||
- Lightczx
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill the form below
|
||||
|
||||
- type: textarea
|
||||
id: back
|
||||
attributes:
|
||||
label: Background & Motivation
|
||||
description: Reason why this feature is needed. If multiple features is requested, please open multiple issues for each of them.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: req
|
||||
attributes:
|
||||
label: Detail of the Feature
|
||||
description: Descripbe the feaure in detail. The more detailed and convincing the desciprtion the more likyly feature will be accepted.
|
||||
validations:
|
||||
required: true
|
||||
79
.github/ISSUE_TEMPLATE/ENG-network-issue.yml
vendored
79
.github/ISSUE_TEMPLATE/ENG-network-issue.yml
vendored
@@ -1,79 +0,0 @@
|
||||
name: Network Issue [English Form]
|
||||
description: Submit this issue form when network issue affect your client experience
|
||||
title: "[Network]: Place your title here"
|
||||
labels: ["area-Network"]
|
||||
assignees:
|
||||
- Lightczx
|
||||
- Masterain98
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Please use one sentence to briefly describe your issue as title above**
|
||||
**Please follow the instruction below to fill the form, so we can locate the issue quickly**
|
||||
|
||||
- type: textarea
|
||||
id: network-diagnosis-report
|
||||
attributes:
|
||||
label: Submit Your Network Diagnosis Report
|
||||
description: |
|
||||
STOP HERE!
|
||||
**Please run our network diagnosis tool before filling this form**
|
||||
**The diagnosis tool will generate a report and add it into a password-protected archive. Drag the `.zip` archive to the box below so it can be uploaded.**
|
||||
- Use the following link to download the Network Diagnosis Tool:
|
||||
- [GitHub](https://github.com/Masterain98/network-diagnosis-tool/releases/latest/download/SH-Network-Diagnosis.exe)
|
||||
- [JIHu GitLab](https://jihulab.com/DGP-Studio/network-diagnosis-tool/-/jobs/11144011/artifacts/raw/SH-Network-Diagnosis.exe?inline=false)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: user-geo-location
|
||||
attributes:
|
||||
label: Your Geographical Location
|
||||
description: |
|
||||
Description accurate to country
|
||||
placeholder: USA
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: user-isp
|
||||
attributes:
|
||||
label: Your ISP Name
|
||||
description: |
|
||||
Name of your Internet service provider
|
||||
placeholder: AT&T
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: user-issue-category
|
||||
attributes:
|
||||
label: Issue Category
|
||||
description: Select an issue category
|
||||
options:
|
||||
- Cannot connect to server completely
|
||||
- Slow spped
|
||||
- Fetched wrong page or data
|
||||
- Image download error in the client
|
||||
- Image set pre-download error (client welcome wizard process)
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: Your Issue (cont.)
|
||||
description: If you selected `Other` in previous dropdown, please explain your issue in detail here.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist-final
|
||||
attributes:
|
||||
label: One Last Step
|
||||
description: Check your issue form
|
||||
options:
|
||||
- label: I confirm I have attached the network diagnosis report archive in the issue
|
||||
required: true
|
||||
65
.github/ISSUE_TEMPLATE/artifact-rating-rules.yml
vendored
Normal file
65
.github/ISSUE_TEMPLATE/artifact-rating-rules.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
name: 圣遗物评分细则建议
|
||||
description: 为圣遗物评分规则提供你的想法
|
||||
title: "[Artifact Rating] 请在这里填写角色名称"
|
||||
labels: area-AvatarInfo
|
||||
assignees: Lightczx
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
请按下方的要求填写完整的问题表单
|
||||
|
||||
- type: textarea
|
||||
id: your-suggested-rule
|
||||
attributes:
|
||||
label: 评分细则
|
||||
description: |
|
||||
请修改下方表格中的**角色名称**和**各属性权重**,并在表格后添加合适的说明
|
||||
你可以点击预览按钮(preview)来查看表格最终会显示出的内容
|
||||
value: |
|
||||
|项目|评分权重(0-100)|
|
||||
|-----|-----|
|
||||
|角色名称| 旅行者 |
|
||||
|生命值| 10 |
|
||||
|攻击力| 10 |
|
||||
|防御力| 10 |
|
||||
|暴击率| 10 |
|
||||
|暴击伤害| 10 |
|
||||
|元素精通| 10 |
|
||||
|充能效率| 10 |
|
||||
|治疗加成| 10 |
|
||||
|元素伤害| 10 |
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: no-duplicated-dropdown
|
||||
attributes:
|
||||
label: 我确认当前没有其它的该角色的圣遗物评分细则建议
|
||||
description: 如果有,你应该在已有的工单内回复以提出你的建议
|
||||
options:
|
||||
- 否
|
||||
- 是
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: title-filled-dropdown
|
||||
attributes:
|
||||
label: 我确认已设置合适的标题
|
||||
options:
|
||||
- 否
|
||||
- 是
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: all-filled-dropdown
|
||||
attributes:
|
||||
label: 我确认已完整填写表格
|
||||
options:
|
||||
- 否
|
||||
- 是
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,7 +1,7 @@
|
||||
name: BUG Report [English Form]
|
||||
description: Tell us what issue you get
|
||||
title: "[ENG][Bug]: Place your Issue Title Here"
|
||||
labels: ["BUG", "priority:none"]
|
||||
labels: ["BUG"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -50,8 +50,7 @@ body:
|
||||
label: Device ID
|
||||
description: |
|
||||
In Snap Hutao's settings page, you can find and copy your device ID
|
||||
If your issue is about program crash, please fill this so we can dump the log and locate the source easier
|
||||
If your program cannot startup, please download and run [this PowerShell script](https://github.com/DGP-Studio/ISSUE_TEMPLATES/releases/download/get_device_id/GetHutaoDeviceId.ps1), it will shows your device ID.
|
||||
If your issue is about program crash, please fill this so we can dump the log and locate the source easier
|
||||
validations:
|
||||
required: false
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: 问题反馈
|
||||
description: 通过这个议题向开发团队反馈你发现的程序中的问题
|
||||
description: 告诉我们你的问题
|
||||
title: "[Bug]: 在这里填写一个合适的标题"
|
||||
labels: ["BUG", "priority:none"]
|
||||
labels: ["BUG"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -14,7 +14,7 @@ body:
|
||||
attributes:
|
||||
label: 检查清单
|
||||
description: |-
|
||||
请确保你已完整执行检查清单,否则你的议题可能会被忽略
|
||||
请确保你已完整执行检查清单,否则你的 Issue 可能会被忽略
|
||||
options:
|
||||
- label: 我已阅读 Snap Hutao 文档中的[常见问题](https://hut.ao/advanced/FAQ.html)和[常见程序异常](https://hut.ao/advanced/exceptions.html),我的问题没有在文档中得到解答
|
||||
required: true
|
||||
@@ -51,7 +51,6 @@ body:
|
||||
description: |
|
||||
在胡桃工具箱的设置界面,你可以找到并复制你的设备 ID
|
||||
如果你的问题涉及程序崩溃,请填写该项,这将有助于我们定位问题
|
||||
如果你的程序已经无法启动,请下载并运行[此PowerShell脚本](https://github.com/DGP-Studio/ISSUE_TEMPLATES/releases/download/get_device_id/GetHutaoDeviceId.ps1),它将显示你的设备 ID
|
||||
validations:
|
||||
required: false
|
||||
|
||||
28
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
28
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Feature Request 功能请求
|
||||
description: Tell us about your thought 告诉我们你的想法
|
||||
title: "[Feat]: Place your title here 在这里填写一个合适的标题"
|
||||
labels: ["功能"]
|
||||
assignees:
|
||||
- Lightczx
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill the form below
|
||||
请按下方的要求填写完整的问题表单。
|
||||
|
||||
- type: textarea
|
||||
id: back
|
||||
attributes:
|
||||
label: Background & Motivation 背景与动机
|
||||
description: Reason why this feature is needed. If multiple features is requested, please open multiple issues for each of them. 添加此功能的理由,如果你想要实现多个功能,请分别发起多个单独的 Issue
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: req
|
||||
attributes:
|
||||
label: Detail of the Feature 想要实现或优化的功能
|
||||
description: Descripbe the feaure in detail. The more detailed and convincing the desciprtion the more likyly feature will be accepted. 详细的描述一下你想要的功能,描述的越具体,采纳的可能性越高
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,5 +1,5 @@
|
||||
name: 网络问题
|
||||
description: 通过这个议题来反馈网络问题
|
||||
description: 当网络问题影响到你的程序使用时
|
||||
title: "[Network]: 在这里填写一个合适的标题"
|
||||
labels: ["area-Network"]
|
||||
assignees:
|
||||
@@ -19,10 +19,10 @@ body:
|
||||
description: |
|
||||
停下!
|
||||
**在填写下面的问题之前请先使用我们的网络诊断工具**
|
||||
**这个工具将会生成一份报告并加密压缩,请将这份报告拖入下面的框中,让其与你的工单一起被上传提交**
|
||||
**这个工具将会生成一份报告,请将这份报告拖入下面的框中,让其与你的工单一起被上传提交**
|
||||
- 你可以点击下面的链接以下载网络诊断工具:
|
||||
- [GitHub](https://github.com/Masterain98/network-diagnosis-tool/releases/latest/download/SH-Network-Diagnosis.exe)
|
||||
- [极狐 GitLab](https://jihulab.com/DGP-Studio/network-diagnosis-tool/-/jobs/11144011/artifacts/raw/SH-Network-Diagnosis.exe?inline=false)
|
||||
- [胡桃资源站](https://d.hut.ao/d/tools/network-diagnosis-hutao.exe)
|
||||
- [GitHub](https://github.com/Masterain98/network-diagnosis-tool/releases/latest/download/network-diagnosis-hutao.exe)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -60,6 +60,7 @@ body:
|
||||
- 完全无法连接服务器
|
||||
- 连接速度慢
|
||||
- 获取到了不正确的页面或数据
|
||||
- 客户端提示 429 Error
|
||||
- 客户端图片下载错误
|
||||
- 客户端图片预下载错误
|
||||
- 其它
|
||||
@@ -73,12 +74,5 @@ body:
|
||||
description: 如果你在上一项中选择了`其它`或者你有更多信息需要提供,请在这里写下来
|
||||
validations:
|
||||
required: false
|
||||
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist-final
|
||||
attributes:
|
||||
label: 最后一步
|
||||
description: 检查你提交的议题
|
||||
options:
|
||||
- label: 我已经在该议题中上传了包含网络诊断报告的加密压缩包
|
||||
required: true
|
||||
26
.github/workflows/qodana_code_quality.yml
vendored
Normal file
26
.github/workflows/qodana_code_quality.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Qodana
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- '**.yml'
|
||||
- '**.resx'
|
||||
|
||||
jobs:
|
||||
qodana:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: 'Qodana Scan'
|
||||
uses: JetBrains/qodana-action@v2023.2
|
||||
with:
|
||||
pr-mode: false
|
||||
env:
|
||||
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -10,7 +10,6 @@ src/Snap.Hutao/_ReSharper.Caches
|
||||
|
||||
src/Snap.Hutao/Snap.Hutao/bin/
|
||||
src/Snap.Hutao/Snap.Hutao/obj/
|
||||
src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs
|
||||
src/Snap.Hutao/Snap.Hutao/Snap.Hutao_TemporaryKey.pfx
|
||||
|
||||
src/Snap.Hutao/Snap.Hutao.Win32/bin/
|
||||
|
||||
33
qodana.yaml
Normal file
33
qodana.yaml
Normal file
@@ -0,0 +1,33 @@
|
||||
#-------------------------------------------------------------------------------#
|
||||
# Qodana analysis is configured by qodana.yaml file #
|
||||
# https://www.jetbrains.com/help/qodana/qodana-yaml.html #
|
||||
#-------------------------------------------------------------------------------#
|
||||
version: "1.0"
|
||||
|
||||
#Specify inspection profile for code analysis
|
||||
profile:
|
||||
name: qodana.starter
|
||||
|
||||
#Enable inspections
|
||||
#include:
|
||||
# - name: <SomeEnabledInspectionId>
|
||||
|
||||
#Disable inspections
|
||||
exclude:
|
||||
- name: Test
|
||||
paths:
|
||||
- Snap.Hutao.Test
|
||||
- Snap.Hutao.SourceGeneration
|
||||
- name: All
|
||||
paths:
|
||||
- Snap.Hutao.SourceGeneration
|
||||
- Snap.Hutao.Test
|
||||
#Execute shell command before Qodana execution (Applied in CI/CD pipeline)
|
||||
#bootstrap: sh ./prepare-qodana.sh
|
||||
|
||||
#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline)
|
||||
#plugins:
|
||||
# - id: <plugin.id> #(plugin id can be found at https://plugins.jetbrains.com)
|
||||
|
||||
#Specify Qodana linter for analysis (Applied in CI/CD pipeline)
|
||||
linter: jetbrains/qodana-dotnet:2023.2-eap
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
@@ -11,18 +10,7 @@ namespace Snap.Hutao.SourceGeneration.Automation;
|
||||
[Generator(LanguageNames.CSharp)]
|
||||
internal sealed class SaltConstantGenerator : IIncrementalGenerator
|
||||
{
|
||||
private static readonly HttpClient httpClient;
|
||||
private static readonly Lazy<Response<SaltLatest>> lazySaltInfo;
|
||||
|
||||
static SaltConstantGenerator()
|
||||
{
|
||||
httpClient = new();
|
||||
lazySaltInfo = new Lazy<Response<SaltLatest>>(() =>
|
||||
{
|
||||
string body = httpClient.GetStringAsync("https://internal.snapgenshin.cn/Archive/Salt/Latest").GetAwaiter().GetResult();
|
||||
return JsonParser.FromJson<Response<SaltLatest>>(body)!;
|
||||
});
|
||||
}
|
||||
private static readonly HttpClient httpClient = new();
|
||||
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
@@ -31,7 +19,8 @@ internal sealed class SaltConstantGenerator : IIncrementalGenerator
|
||||
|
||||
private static void GenerateSaltContstants(IncrementalGeneratorPostInitializationContext context)
|
||||
{
|
||||
Response<SaltLatest> saltInfo = lazySaltInfo.Value;
|
||||
string body = httpClient.GetStringAsync("https://internal.snapgenshin.cn/Archive/Salt/Latest").GetAwaiter().GetResult();
|
||||
Response<SaltLatest> saltInfo = JsonParser.FromJson<Response<SaltLatest>>(body)!;
|
||||
string code = $$"""
|
||||
namespace Snap.Hutao.Web.Hoyolab;
|
||||
|
||||
|
||||
@@ -50,8 +50,6 @@ internal class LocalizedEnumGenerator : IIncrementalGenerator
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Globalization;
|
||||
|
||||
namespace Snap.Hutao.Resource.Localization;
|
||||
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{nameof(LocalizedEnumGenerator)}}", "1.0.0.0")]
|
||||
@@ -81,7 +79,7 @@ internal class LocalizedEnumGenerator : IIncrementalGenerator
|
||||
}
|
||||
else
|
||||
{
|
||||
return SH.ResourceManager.GetString(key, CultureInfo.CurrentCulture);
|
||||
return SH.ResourceManager.GetString(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +102,7 @@ internal class LocalizedEnumGenerator : IIncrementalGenerator
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
return SH.ResourceManager.GetString(key, CultureInfo.CurrentCulture);
|
||||
return SH.ResourceManager.GetString(key);
|
||||
}
|
||||
}
|
||||
""");
|
||||
|
||||
@@ -1,607 +0,0 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
|
||||
namespace Snap.Hutao.SourceGeneration.Resx;
|
||||
|
||||
[Generator]
|
||||
public sealed class ResxGenerator : IIncrementalGenerator
|
||||
{
|
||||
private static readonly DiagnosticDescriptor InvalidResx = new("SH401", "Couldn't parse Resx file", "Couldn't parse Resx file '{0}'", "ResxGenerator", DiagnosticSeverity.Warning, true);
|
||||
private static readonly DiagnosticDescriptor InvalidPropertiesForNamespace = new("SH402", "Couldn't compute namespace", "Couldn't compute namespace for file '{0}'", "ResxGenerator", DiagnosticSeverity.Warning, true);
|
||||
private static readonly DiagnosticDescriptor InvalidPropertiesForResourceName = new("SH403", "Couldn't compute resource name", "Couldn't compute resource name for file '{0}'", "ResxGenerator", DiagnosticSeverity.Warning, true);
|
||||
private static readonly DiagnosticDescriptor InconsistentProperties = new("SH404", "Inconsistent properties", "Property '{0}' values for '{1}' are inconsistent", "ResxGenerator", DiagnosticSeverity.Warning, true);
|
||||
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
IncrementalValueProvider<(string? AssemblyName, bool SupportNullableReferenceTypes)> compilationProvider = context.CompilationProvider
|
||||
.Select(static (compilation, cancellationToken) => (compilation.AssemblyName, SupportNullableReferenceTypes: compilation.GetTypeByMetadataName("System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute") is not null));
|
||||
|
||||
IncrementalValueProvider<ImmutableArray<AdditionalText>> resxProvider = context.AdditionalTextsProvider
|
||||
.Where(text => text.Path.EndsWith(".resx", StringComparison.OrdinalIgnoreCase))
|
||||
.Collect();
|
||||
|
||||
context.RegisterSourceOutput(
|
||||
source: context.AnalyzerConfigOptionsProvider.Combine(compilationProvider.Combine(resxProvider)),
|
||||
action: (ctx, source) => Execute(ctx, source.Left, source.Right.Left.AssemblyName, source.Right.Left.SupportNullableReferenceTypes, source.Right.Right));
|
||||
}
|
||||
|
||||
private static void Execute(SourceProductionContext context, AnalyzerConfigOptionsProvider options, string? assemblyName, bool supportNullableReferenceTypes, ImmutableArray<AdditionalText> files)
|
||||
{
|
||||
// Group additional file by resource kind ((a.resx, a.en.resx, a.en-us.resx), (b.resx, b.en-us.resx))
|
||||
List<IGrouping<string, AdditionalText>> resxGroups = files
|
||||
.GroupBy(file => GetResourceName(file.Path), StringComparer.OrdinalIgnoreCase)
|
||||
.OrderBy(x => x.Key, StringComparer.Ordinal)
|
||||
.ToList();
|
||||
|
||||
foreach (IGrouping<string, AdditionalText>? resxGroug in resxGroups)
|
||||
{
|
||||
string? rootNamespaceConfiguration = GetMetadataValue(context, options, "RootNamespace", resxGroug);
|
||||
string? projectDirConfiguration = GetMetadataValue(context, options, "ProjectDir", resxGroug);
|
||||
string? namespaceConfiguration = GetMetadataValue(context, options, "Namespace", "DefaultResourcesNamespace", resxGroug);
|
||||
string? resourceNameConfiguration = GetMetadataValue(context, options, "ResourceName", globalName: null, resxGroug);
|
||||
string? classNameConfiguration = GetMetadataValue(context, options, "ClassName", globalName: null, resxGroug);
|
||||
|
||||
string rootNamespace = rootNamespaceConfiguration ?? assemblyName ?? "";
|
||||
string projectDir = projectDirConfiguration ?? assemblyName ?? "";
|
||||
string? defaultResourceName = ComputeResourceName(rootNamespace, projectDir, resxGroug.Key);
|
||||
string? defaultNamespace = ComputeNamespace(rootNamespace, projectDir, resxGroug.Key);
|
||||
|
||||
string? ns = namespaceConfiguration ?? defaultNamespace;
|
||||
string? resourceName = resourceNameConfiguration ?? defaultResourceName;
|
||||
string className = classNameConfiguration ?? ToCSharpNameIdentifier(Path.GetFileName(resxGroug.Key));
|
||||
|
||||
if (ns == null)
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(InvalidPropertiesForNamespace, location: null, resxGroug.First().Path));
|
||||
}
|
||||
|
||||
if (resourceName == null)
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(InvalidPropertiesForResourceName, location: null, resxGroug.First().Path));
|
||||
}
|
||||
|
||||
List<ResxEntry>? entries = LoadResourceFiles(context, resxGroug);
|
||||
|
||||
string content = $"""
|
||||
// Debug info:
|
||||
// key: {resxGroug.Key}
|
||||
// files: {string.Join(", ", resxGroug.Select(f => f.Path))}
|
||||
// RootNamespace (metadata): {rootNamespaceConfiguration}
|
||||
// ProjectDir (metadata): {projectDirConfiguration}
|
||||
// Namespace / DefaultResourcesNamespace (metadata): {namespaceConfiguration}
|
||||
// ResourceName (metadata): {resourceNameConfiguration}
|
||||
// ClassName (metadata): {classNameConfiguration}
|
||||
// AssemblyName: {assemblyName}
|
||||
// RootNamespace (computed): {rootNamespace}
|
||||
// ProjectDir (computed): {projectDir}
|
||||
// defaultNamespace: {defaultNamespace}
|
||||
// defaultResourceName: {defaultResourceName}
|
||||
// Namespace: {ns}
|
||||
// ResourceName: {resourceName}
|
||||
// ClassName: {className}
|
||||
""";
|
||||
|
||||
if (resourceName != null && entries != null)
|
||||
{
|
||||
content += GenerateCode(ns, className, resourceName, entries, supportNullableReferenceTypes);
|
||||
}
|
||||
|
||||
context.AddSource($"{Path.GetFileName(resxGroug.Key)}.resx.g.cs", SourceText.From(content, Encoding.UTF8));
|
||||
}
|
||||
}
|
||||
|
||||
private static string GenerateCode(string? ns, string className, string resourceName, List<ResxEntry> entries, bool enableNullableAttributes)
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("#nullable enable");
|
||||
|
||||
if (ns != null)
|
||||
{
|
||||
sb.AppendLine($$"""
|
||||
|
||||
namespace {{ns}};
|
||||
|
||||
""");
|
||||
}
|
||||
|
||||
sb.AppendLine($$"""
|
||||
internal partial class {{className}}
|
||||
{
|
||||
private static global::System.Resources.ResourceManager? resourceMan;
|
||||
|
||||
public {{className}}()
|
||||
{
|
||||
}
|
||||
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if (resourceMan is null)
|
||||
{
|
||||
resourceMan = new global::System.Resources.ResourceManager("{{resourceName}}", typeof({{className}}).Assembly);
|
||||
}
|
||||
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo? Culture { get; set; }
|
||||
|
||||
[return:global::System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("defaultValue")]
|
||||
public static object? GetObject(global::System.Globalization.CultureInfo? culture, string name, object? defaultValue)
|
||||
{
|
||||
culture ??= Culture;
|
||||
object? obj = ResourceManager.GetObject(name, culture);
|
||||
if (obj == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static object? GetObject(global::System.Globalization.CultureInfo? culture, string name)
|
||||
{
|
||||
return GetObject(culture: culture, name: name, defaultValue: null);
|
||||
}
|
||||
|
||||
public static object? GetObject(string name)
|
||||
{
|
||||
return GetObject(culture: null, name: name, defaultValue: null);
|
||||
}
|
||||
|
||||
[return:global::System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("defaultValue")]
|
||||
public static object? GetObject(string name, object? defaultValue)
|
||||
{
|
||||
return GetObject(culture: null, name: name, defaultValue: defaultValue);
|
||||
}
|
||||
|
||||
public static global::System.IO.Stream? GetStream(string name)
|
||||
{
|
||||
return GetStream(culture: null, name: name);
|
||||
}
|
||||
|
||||
public static global::System.IO.Stream? GetStream(global::System.Globalization.CultureInfo? culture, string name)
|
||||
{
|
||||
culture ??= Culture;
|
||||
return ResourceManager.GetStream(name, culture);
|
||||
}
|
||||
|
||||
public static string? GetString(global::System.Globalization.CultureInfo? culture, string name)
|
||||
{
|
||||
return GetString(culture: culture, name: name, args: null);
|
||||
}
|
||||
|
||||
public static string? GetString(global::System.Globalization.CultureInfo? culture, string name, params object?[]? args)
|
||||
{
|
||||
culture ??= Culture;
|
||||
string? str = ResourceManager.GetString(name, culture);
|
||||
if (str == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (args != null)
|
||||
{
|
||||
return string.Format(culture, str, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
public static string? GetString(string name, params object?[]? args)
|
||||
{
|
||||
return GetString(culture: null, name: name, args: args);
|
||||
}
|
||||
|
||||
[return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("defaultValue")]
|
||||
public static string? GetString(string name, string? defaultValue)
|
||||
{
|
||||
return GetStringOrDefault(culture: null, name: name, defaultValue: defaultValue, args: null);
|
||||
}
|
||||
|
||||
public static string? GetString(string name)
|
||||
{
|
||||
return GetStringOrDefault(culture: null, name: name, defaultValue: null, args: null);
|
||||
}
|
||||
|
||||
[return:global::System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("defaultValue")]
|
||||
public static string? GetStringOrDefault(global::System.Globalization.CultureInfo? culture, string name, string? defaultValue)
|
||||
{
|
||||
return GetStringOrDefault(culture: culture, name: name, defaultValue: defaultValue, args: null);
|
||||
}
|
||||
|
||||
[return:global::System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("defaultValue")]
|
||||
public static string? GetStringOrDefault(global::System.Globalization.CultureInfo? culture, string name, string? defaultValue, params object?[]? args)
|
||||
{
|
||||
culture ??= Culture;
|
||||
string? str = ResourceManager.GetString(name, culture);
|
||||
if (str == null)
|
||||
{
|
||||
if (defaultValue == null || args == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Format(culture, defaultValue, args);
|
||||
}
|
||||
}
|
||||
|
||||
if (args != null)
|
||||
{
|
||||
return string.Format(culture, str, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
[return:global::System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("defaultValue")]
|
||||
public static string? GetStringOrDefault(string name, string? defaultValue, params object?[]? args)
|
||||
{
|
||||
return GetStringOrDefault(culture: null, name: name, defaultValue: defaultValue, args: args);
|
||||
}
|
||||
|
||||
[return:global::System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("defaultValue")]
|
||||
public static string? GetStringOrDefault(string name, string? defaultValue)
|
||||
{
|
||||
return GetStringOrDefault(culture: null, name: name, defaultValue: defaultValue, args: null);
|
||||
}
|
||||
""");
|
||||
|
||||
foreach (ResxEntry? entry in entries.OrderBy(e => e.Name, StringComparer.Ordinal))
|
||||
{
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.IsText)
|
||||
{
|
||||
XElement summary = new("summary", new XElement("para", $"Looks up a localized string for \"{entry.Name}\"."));
|
||||
if (!string.IsNullOrWhiteSpace(entry.Comment))
|
||||
{
|
||||
summary.Add(new XElement("para", entry.Comment));
|
||||
}
|
||||
|
||||
if (!entry.IsFileRef)
|
||||
{
|
||||
summary.Add(new XElement("para", $"Value: \"{entry.Value}\"."));
|
||||
}
|
||||
|
||||
string comment = summary.ToString().Replace("\r\n", "\r\n /// ", StringComparison.Ordinal);
|
||||
|
||||
sb.AppendLine($$"""
|
||||
/// {{comment}}
|
||||
public static string {{ToCSharpNameIdentifier(entry.Name!)}}
|
||||
{
|
||||
get => GetString("{{entry.Name}}")!;
|
||||
}
|
||||
|
||||
""");
|
||||
|
||||
if (entry.Value != null)
|
||||
{
|
||||
int args = Regex.Matches(entry.Value, "\\{(?<num>[0-9]+)(\\:[^}]*)?\\}", RegexOptions.ExplicitCapture | RegexOptions.CultureInvariant)
|
||||
.Cast<Match>()
|
||||
.Select(m => int.Parse(m.Groups["num"].Value, CultureInfo.InvariantCulture))
|
||||
.Distinct()
|
||||
.DefaultIfEmpty(-1)
|
||||
.Max();
|
||||
|
||||
if (args >= 0)
|
||||
{
|
||||
string inParams = string.Join(", ", Enumerable.Range(0, args + 1).Select(arg => "object? arg" + arg.ToString(CultureInfo.InvariantCulture)));
|
||||
string callParams = string.Join(", ", Enumerable.Range(0, args + 1).Select(arg => "arg" + arg.ToString(CultureInfo.InvariantCulture)));
|
||||
|
||||
sb.AppendLine($$"""
|
||||
/// {{comment}}
|
||||
public static string Format{{ToCSharpNameIdentifier(entry.Name!)}}(global::System.Globalization.CultureInfo? provider, {{inParams}})
|
||||
{
|
||||
return GetString(provider, "{{entry.Name}}", {{callParams}})!;
|
||||
}
|
||||
|
||||
/// {{comment}}
|
||||
public static string Format{{ToCSharpNameIdentifier(entry.Name!)}}({{inParams}})
|
||||
{
|
||||
return GetString("{{entry.Name}}", {{callParams}})!;
|
||||
}
|
||||
|
||||
""");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine($$"""
|
||||
public static global::{{entry.FullTypeName}}? {{ToCSharpNameIdentifier(entry.Name!)}}
|
||||
{
|
||||
get => (global::{{entry.FullTypeName}}?)GetObject("{{entry.Name}}");
|
||||
}
|
||||
|
||||
""");
|
||||
}
|
||||
}
|
||||
|
||||
sb.AppendLine($$"""
|
||||
}
|
||||
|
||||
internal partial class {{className}}Names
|
||||
{
|
||||
""");
|
||||
|
||||
foreach (ResxEntry entry in entries)
|
||||
{
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sb.AppendLine($$"""
|
||||
public const string {{ToCSharpNameIdentifier(entry.Name!)}} = "entry.Name";
|
||||
""");
|
||||
}
|
||||
|
||||
sb.AppendLine("}");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string? ComputeResourceName(string rootNamespace, string projectDir, string resourcePath)
|
||||
{
|
||||
string fullProjectDir = EnsureEndSeparator(Path.GetFullPath(projectDir));
|
||||
string fullResourcePath = Path.GetFullPath(resourcePath);
|
||||
|
||||
if (fullProjectDir == fullResourcePath)
|
||||
{
|
||||
return rootNamespace;
|
||||
}
|
||||
|
||||
if (fullResourcePath.StartsWith(fullProjectDir, StringComparison.Ordinal))
|
||||
{
|
||||
string relativePath = fullResourcePath.Substring(fullProjectDir.Length);
|
||||
return rootNamespace + '.' + relativePath.Replace('/', '.').Replace('\\', '.');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string? ComputeNamespace(string rootNamespace, string projectDir, string resourcePath)
|
||||
{
|
||||
string fullProjectDir = EnsureEndSeparator(Path.GetFullPath(projectDir));
|
||||
string fullResourcePath = EnsureEndSeparator(Path.GetDirectoryName(Path.GetFullPath(resourcePath))!);
|
||||
|
||||
if (fullProjectDir == fullResourcePath)
|
||||
{
|
||||
return rootNamespace;
|
||||
}
|
||||
|
||||
if (fullResourcePath.StartsWith(fullProjectDir, StringComparison.Ordinal))
|
||||
{
|
||||
string relativePath = fullResourcePath.Substring(fullProjectDir.Length);
|
||||
return rootNamespace + '.' + relativePath.Replace('/', '.').Replace('\\', '.').TrimEnd('.');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static List<ResxEntry>? LoadResourceFiles(SourceProductionContext context, IGrouping<string, AdditionalText> resxGroug)
|
||||
{
|
||||
List<ResxEntry> entries = new();
|
||||
foreach (AdditionalText? entry in resxGroug.OrderBy(file => file.Path, StringComparer.Ordinal))
|
||||
{
|
||||
SourceText? content = entry.GetText(context.CancellationToken);
|
||||
if (content == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
XDocument document = XDocument.Parse(content.ToString());
|
||||
foreach (XElement? element in document.XPathSelectElements("/root/data"))
|
||||
{
|
||||
string? name = element.Attribute("name")?.Value;
|
||||
string? type = element.Attribute("type")?.Value;
|
||||
string? comment = element.Attribute("comment")?.Value;
|
||||
string? value = element.Element("value")?.Value;
|
||||
|
||||
ResxEntry existingEntry = entries.Find(e => e.Name == name);
|
||||
if (existingEntry != null)
|
||||
{
|
||||
existingEntry.Comment ??= comment;
|
||||
}
|
||||
else
|
||||
{
|
||||
entries.Add(new ResxEntry { Name = name, Value = value, Comment = comment, Type = type });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(InvalidResx, location: null, entry.Path));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
private static string? GetMetadataValue(SourceProductionContext context, AnalyzerConfigOptionsProvider analyzerConfigOptionsProvider, string name, IEnumerable<AdditionalText> additionalFiles)
|
||||
{
|
||||
return GetMetadataValue(context, analyzerConfigOptionsProvider, name, name, additionalFiles);
|
||||
}
|
||||
|
||||
private static string? GetMetadataValue(SourceProductionContext context, AnalyzerConfigOptionsProvider analyzerConfigOptionsProvider, string name, string? globalName, IEnumerable<AdditionalText> additionalFiles)
|
||||
{
|
||||
string? result = null;
|
||||
foreach (AdditionalText file in additionalFiles)
|
||||
{
|
||||
if (analyzerConfigOptionsProvider.GetOptions(file).TryGetValue("build_metadata.AdditionalFiles." + name, out string? value))
|
||||
{
|
||||
if (result != null && value != result)
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(InconsistentProperties, location: null, name, file.Path));
|
||||
return null;
|
||||
}
|
||||
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (globalName != null && analyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property." + globalName, out string? globalValue) && !string.IsNullOrEmpty(globalValue))
|
||||
{
|
||||
return globalValue;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string ToCSharpNameIdentifier(string name)
|
||||
{
|
||||
// https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#identifiers
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.globalization.unicodecategory?view=net-5.0
|
||||
StringBuilder sb = new();
|
||||
foreach (char c in name)
|
||||
{
|
||||
UnicodeCategory category = char.GetUnicodeCategory(c);
|
||||
switch (category)
|
||||
{
|
||||
case UnicodeCategory.UppercaseLetter:
|
||||
case UnicodeCategory.LowercaseLetter:
|
||||
case UnicodeCategory.TitlecaseLetter:
|
||||
case UnicodeCategory.ModifierLetter:
|
||||
case UnicodeCategory.OtherLetter:
|
||||
case UnicodeCategory.LetterNumber:
|
||||
sb.Append(c);
|
||||
break;
|
||||
|
||||
case UnicodeCategory.DecimalDigitNumber:
|
||||
case UnicodeCategory.ConnectorPunctuation:
|
||||
case UnicodeCategory.Format:
|
||||
if (sb.Length == 0)
|
||||
{
|
||||
sb.Append('_');
|
||||
}
|
||||
sb.Append(c);
|
||||
break;
|
||||
|
||||
default:
|
||||
sb.Append('_');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string EnsureEndSeparator(string path)
|
||||
{
|
||||
if (path[path.Length - 1] == Path.DirectorySeparatorChar)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
return path + Path.DirectorySeparatorChar;
|
||||
}
|
||||
|
||||
private static string GetResourceName(string path)
|
||||
{
|
||||
string pathWithoutExtension = Path.Combine(Path.GetDirectoryName(path)!, Path.GetFileNameWithoutExtension(path));
|
||||
int indexOf = pathWithoutExtension.LastIndexOf('.');
|
||||
if (indexOf < 0)
|
||||
{
|
||||
return pathWithoutExtension;
|
||||
}
|
||||
|
||||
return Regex.IsMatch(pathWithoutExtension.Substring(indexOf + 1), "^[a-zA-Z]{2}(-[a-zA-Z]{2})?$", RegexOptions.ExplicitCapture | RegexOptions.CultureInvariant, TimeSpan.FromSeconds(1))
|
||||
? pathWithoutExtension.Substring(0, indexOf)
|
||||
: pathWithoutExtension;
|
||||
}
|
||||
|
||||
private sealed class ResxEntry
|
||||
{
|
||||
public string? Name { get; set; }
|
||||
public string? Value { get; set; }
|
||||
public string? Comment { get; set; }
|
||||
public string? Type { get; set; }
|
||||
|
||||
public bool IsText
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Type == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Value != null)
|
||||
{
|
||||
string[] parts = Value.Split(';');
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
string type = parts[1];
|
||||
if (type.StartsWith("System.String,", StringComparison.Ordinal))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public string? FullTypeName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
return "string";
|
||||
}
|
||||
|
||||
if (Value != null)
|
||||
{
|
||||
string[] parts = Value.Split(';');
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
string type = parts[1];
|
||||
return type.Split(',')[0];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsFileRef
|
||||
{
|
||||
get => Type != null && Type.StartsWith("System.Resources.ResXFileRef,", StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Snap.Hutao.SourceGeneration.Resx;
|
||||
|
||||
internal static class StringExtensions
|
||||
{
|
||||
public static string Replace(this string str, string oldValue, string newValue, StringComparison comparison)
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
|
||||
int previousIndex = 0;
|
||||
int index = str.IndexOf(oldValue, comparison);
|
||||
while (index is not -1)
|
||||
{
|
||||
sb.Append(str, previousIndex, index - previousIndex);
|
||||
sb.Append(newValue);
|
||||
index += oldValue.Length;
|
||||
|
||||
previousIndex = index;
|
||||
index = str.IndexOf(oldValue, index, comparison);
|
||||
}
|
||||
|
||||
sb.Append(str, previousIndex, str.Length - previousIndex);
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
|
||||
37
src/Snap.Hutao/Snap.Hutao.Win32/UnsafePInvoke.cs
Normal file
37
src/Snap.Hutao/Snap.Hutao.Win32/UnsafePInvoke.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Windows.UI.Core;
|
||||
using Windows.Win32.Foundation;
|
||||
|
||||
namespace Snap.Hutao.Win32;
|
||||
|
||||
internal static class UnsafePInvoke
|
||||
{
|
||||
private enum WINDOW_TYPE : uint
|
||||
{
|
||||
IMMERSIVE_BODY,
|
||||
IMMERSIVE_DOCK,
|
||||
IMMERSIVE_HOSTED,
|
||||
IMMERSIVE_TEST,
|
||||
IMMERSIVE_BODY_ACTIVE,
|
||||
IMMERSIVE_DOCK_ACTIVE,
|
||||
NOT_IMMERSIVE,
|
||||
}
|
||||
|
||||
[DllImport("Windows.UI.dll", CharSet = CharSet.None, EntryPoint = "#1500", ExactSpelling = false, SetLastError = true)]
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||
private static extern HRESULT PrivateCreateCoreWindow(WINDOW_TYPE WindowType, PWSTR pWindowTitle, int x, int y, uint uWidth, uint uHeight, uint dwAttributes, HWND hOwnerWindow, Guid riid, out nint ppv);
|
||||
|
||||
public static unsafe CoreWindow PrivateCreateCoreWindow(string title, HWND hOwnerWindow)
|
||||
{
|
||||
fixed(char* pTitle = title)
|
||||
{
|
||||
PrivateCreateCoreWindow(WINDOW_TYPE.NOT_IMMERSIVE, pTitle, 0, 0, 400, 400, 0, hOwnerWindow, typeof(ICoreWindow).GUID, out nint thisPtr);
|
||||
return CoreWindow.FromAbi(thisPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.WinUI.Behaviors;
|
||||
using Microsoft.UI.Xaml;
|
||||
|
||||
namespace Snap.Hutao.Control.Behavior;
|
||||
|
||||
/// <summary>
|
||||
/// 按给定比例自动调整高度的行为
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[DependencyProperty("TargetWidth", typeof(double), 1.0D)]
|
||||
[DependencyProperty("TargetHeight", typeof(double), 1.0D)]
|
||||
internal sealed partial class AutoHeightBehavior : BehaviorBase<FrameworkElement>
|
||||
{
|
||||
private readonly SizeChangedEventHandler sizeChangedEventHandler;
|
||||
|
||||
public AutoHeightBehavior()
|
||||
{
|
||||
sizeChangedEventHandler = OnSizeChanged;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool Initialize()
|
||||
{
|
||||
UpdateElement();
|
||||
AssociatedObject.SizeChanged += sizeChangedEventHandler;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool Uninitialize()
|
||||
{
|
||||
AssociatedObject.SizeChanged -= sizeChangedEventHandler;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
UpdateElement();
|
||||
}
|
||||
|
||||
private void UpdateElement()
|
||||
{
|
||||
AssociatedObject.Height = AssociatedObject.ActualWidth * (TargetHeight / TargetWidth);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.WinUI.Behaviors;
|
||||
using Microsoft.UI.Xaml;
|
||||
|
||||
namespace Snap.Hutao.Control.Behavior;
|
||||
|
||||
/// <summary>
|
||||
/// 按给定比例自动调整高度的行为
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[DependencyProperty("TargetWidth", typeof(double), 1.0D)]
|
||||
[DependencyProperty("TargetHeight", typeof(double), 1.0D)]
|
||||
internal sealed partial class AutoWidthBehavior : BehaviorBase<FrameworkElement>
|
||||
{
|
||||
private readonly SizeChangedEventHandler sizeChangedEventHandler;
|
||||
|
||||
public AutoWidthBehavior()
|
||||
{
|
||||
sizeChangedEventHandler = OnSizeChanged;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool Initialize()
|
||||
{
|
||||
UpdateElement();
|
||||
AssociatedObject.SizeChanged += sizeChangedEventHandler;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool Uninitialize()
|
||||
{
|
||||
AssociatedObject.SizeChanged -= sizeChangedEventHandler;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
UpdateElement();
|
||||
}
|
||||
|
||||
private void UpdateElement()
|
||||
{
|
||||
AssociatedObject.Width = AssociatedObject.Height * (TargetWidth / TargetHeight);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.WinUI;
|
||||
using CommunityToolkit.WinUI.Behaviors;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
@@ -13,7 +12,7 @@ internal sealed class SelectedItemInViewBehavior : BehaviorBase<ListViewBase>
|
||||
{
|
||||
if (AssociatedObject.SelectedItem is { } item)
|
||||
{
|
||||
AssociatedObject.SmoothScrollIntoViewWithItemAsync(item, ScrollItemPlacement.Center).SafeForget();
|
||||
AssociatedObject.ScrollIntoView(item);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
<x:Double x:Key="SettingsCardMinHeight">0</x:Double>
|
||||
<x:Double x:Key="SettingsCardWrapThreshold">0</x:Double>
|
||||
<x:Double x:Key="SettingsCardWrapNoIconThreshold">0</x:Double>
|
||||
|
||||
<x:Double x:Key="SettingsCardContentControlMinWidth">120</x:Double>
|
||||
|
||||
<Style
|
||||
x:Key="SettingsSectionHeaderTextBlockStyle"
|
||||
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
|
||||
@@ -19,17 +16,16 @@
|
||||
x:Key="SettingsContentComboBoxStyle"
|
||||
BasedOn="{StaticResource DefaultComboBoxStyle}"
|
||||
TargetType="ComboBox">
|
||||
<Setter Property="MinWidth" Value="{ThemeResource SettingsCardContentControlMinWidth}"/>
|
||||
<Setter Property="MinWidth" Value="120"/>
|
||||
</Style>
|
||||
<Style
|
||||
x:Key="SettingButtonStyle"
|
||||
BasedOn="{StaticResource DefaultButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}"/>
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardBorderBrush}"/>
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}"/>
|
||||
<Setter Property="Padding" Value="16,6,16,6"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="MinWidth" Value="{ThemeResource SettingsCardContentControlMinWidth}"/>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -27,7 +27,6 @@ internal sealed partial class ExceptionRecorder
|
||||
app.DebugSettings.XamlResourceReferenceFailed += OnXamlResourceReferenceFailed;
|
||||
}
|
||||
|
||||
[SuppressMessage("", "CA2012")]
|
||||
private void OnAppUnhandledException(object? sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
|
||||
{
|
||||
ValueTask<string?> task = serviceProvider
|
||||
|
||||
@@ -16,7 +16,7 @@ internal sealed class RuntimeEnvironmentException : Exception
|
||||
/// <param name="message">消息</param>
|
||||
/// <param name="innerException">内部错误</param>
|
||||
public RuntimeEnvironmentException(string message, Exception? innerException)
|
||||
: base($"{message}\n{innerException?.Message}", innerException)
|
||||
: base($"{message}\n{innerException.Message}", innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
|
||||
namespace Snap.Hutao.Core.LifeCycle;
|
||||
|
||||
internal static class CurrentWindowReferenceExtension
|
||||
{
|
||||
public static XamlRoot GetXamlRoot(this ICurrentWindowReference reference)
|
||||
{
|
||||
return reference.Window.Content.XamlRoot;
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,4 @@ namespace Snap.Hutao.Core.LifeCycle;
|
||||
internal interface ICurrentWindowReference
|
||||
{
|
||||
public Window Window { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,11 @@ using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Snap.Hutao.Core.Setting;
|
||||
using Snap.Hutao.Service;
|
||||
using Snap.Hutao.Win32;
|
||||
using System.IO;
|
||||
using Windows.Graphics;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Core;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.Graphics.Dwm;
|
||||
using Windows.Win32.UI.WindowsAndMessaging;
|
||||
@@ -39,12 +41,9 @@ internal sealed class WindowController
|
||||
|
||||
private static void TransformToCenterScreen(ref RectInt32 rect)
|
||||
{
|
||||
DisplayArea displayArea = DisplayArea.GetFromRect(rect, DisplayAreaFallback.Nearest);
|
||||
DisplayArea displayArea = DisplayArea.GetFromRect(rect, DisplayAreaFallback.Primary);
|
||||
RectInt32 workAreaRect = displayArea.WorkArea;
|
||||
|
||||
rect.Width = Math.Min(workAreaRect.Width, rect.Width);
|
||||
rect.Height = Math.Min(workAreaRect.Height, rect.Height);
|
||||
|
||||
rect.X = workAreaRect.X + ((workAreaRect.Width - rect.Width) / 2);
|
||||
rect.Y = workAreaRect.Y + ((workAreaRect.Height - rect.Height) / 2);
|
||||
}
|
||||
@@ -58,6 +57,7 @@ internal sealed class WindowController
|
||||
ExtendsContentIntoTitleBar();
|
||||
|
||||
RecoverOrInitWindowSize();
|
||||
CoreWindow coreWindow = UnsafePInvoke.PrivateCreateCoreWindow("Snap Hutao CoreWindow", options.Hwnd);
|
||||
UpdateImmersiveDarkMode(options.TitleBar, default!);
|
||||
|
||||
// appWindow.Show(true);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Snap.Hutao.Core.Windowing.HotKey;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.UI.Shell;
|
||||
|
||||
@@ -23,7 +23,7 @@ internal sealed partial class ContentDialogFactory : IContentDialogFactory
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
ContentDialog dialog = new()
|
||||
{
|
||||
XamlRoot = currentWindowReference.GetXamlRoot(),
|
||||
XamlRoot = currentWindowReference.Window.Content.XamlRoot,
|
||||
Title = title,
|
||||
Content = content,
|
||||
DefaultButton = ContentDialogButton.Primary,
|
||||
@@ -39,7 +39,7 @@ internal sealed partial class ContentDialogFactory : IContentDialogFactory
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
ContentDialog dialog = new()
|
||||
{
|
||||
XamlRoot = currentWindowReference.GetXamlRoot(),
|
||||
XamlRoot = currentWindowReference.Window.Content.XamlRoot,
|
||||
Title = title,
|
||||
Content = content,
|
||||
DefaultButton = defaultButton,
|
||||
@@ -56,7 +56,7 @@ internal sealed partial class ContentDialogFactory : IContentDialogFactory
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
ContentDialog dialog = new()
|
||||
{
|
||||
XamlRoot = currentWindowReference.GetXamlRoot(),
|
||||
XamlRoot = currentWindowReference.Window.Content.XamlRoot,
|
||||
Title = title,
|
||||
Content = new ProgressBar() { IsIndeterminate = true },
|
||||
};
|
||||
@@ -68,16 +68,12 @@ internal sealed partial class ContentDialogFactory : IContentDialogFactory
|
||||
where TContentDialog : ContentDialog
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
TContentDialog contentDialog = serviceProvider.CreateInstance<TContentDialog>(parameters);
|
||||
contentDialog.XamlRoot = currentWindowReference.GetXamlRoot();
|
||||
return contentDialog;
|
||||
return serviceProvider.CreateInstance<TContentDialog>(parameters);
|
||||
}
|
||||
|
||||
public TContentDialog CreateInstance<TContentDialog>(params object[] parameters)
|
||||
where TContentDialog : ContentDialog
|
||||
{
|
||||
TContentDialog contentDialog = serviceProvider.CreateInstance<TContentDialog>(parameters);
|
||||
contentDialog.XamlRoot = currentWindowReference.GetXamlRoot();
|
||||
return contentDialog;
|
||||
return serviceProvider.CreateInstance<TContentDialog>(parameters);
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
<Identity
|
||||
Name="60568DGPStudio.SnapHutao"
|
||||
Publisher="CN=35C8E923-85DF-49A7-9172-B39DC6312C52"
|
||||
Version="1.7.14.0" />
|
||||
Version="1.7.11.0" />
|
||||
|
||||
<Properties>
|
||||
<DisplayName>Snap Hutao</DisplayName>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 913 B |
7164
src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs
generated
Normal file
7164
src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -506,78 +506,6 @@
|
||||
<data name="MustSelectUserAndUid" xml:space="preserve">
|
||||
<value>You must select a user and a role first</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInsufficientRecordSlot" xml:space="preserve">
|
||||
<value>Reached max allowed number of wish history archives on Snap Hutao Cloud</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInsufficientTime" xml:space="preserve">
|
||||
<value>No valid wish history backup service privilege</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInvalidGachaLogData" xml:space="preserve">
|
||||
<value>Wish history data contains invalid item, unable to upload to Snap Hutao Cloud</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceServerDatabaseError" xml:space="preserve">
|
||||
<value>Found abnormal data, unable to upload to Snap Hutao Cloud. Please do not upload across accounts or you can attempt to delete cloud data and try again.</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceEmailHasNotRegistered" xml:space="preserve">
|
||||
<value>Current email adress is not registered</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceEmailHasRegistered" xml:space="preserve">
|
||||
<value>Current emaill address is registered</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceInternalException" xml:space="preserve">
|
||||
<value>Register failed, server error, please contact developer to fix it</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceUnregisterFailed" xml:space="preserve">
|
||||
<value>User does not exist, failed to delete account</value>
|
||||
</data>
|
||||
<data name="ServerPassportUserInfoNotExist" xml:space="preserve">
|
||||
<value>User does not exist, failed to fetch user's data</value>
|
||||
</data>
|
||||
<data name="ServerPassportUsernameOrPassportIncorrect" xml:space="preserve">
|
||||
<value>Wrong username or password</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyFailed" xml:space="preserve">
|
||||
<value>Verification failed</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyRequestSuccess" xml:space="preserve">
|
||||
<value>The verification code has been sent to your e-mail.</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyTooFrequent" xml:space="preserve">
|
||||
<value>Validation request is too frequent. Please try again in 1 minute.</value>
|
||||
</data>
|
||||
<data name="ServerRecordBannedUid" xml:space="preserve">
|
||||
<value>Failed to upload Sprial Abyss record, current UID is banned by Hutao Database</value>
|
||||
</data>
|
||||
<data name="ServerRecordComputingStatistics" xml:space="preserve">
|
||||
<value>Failed to upload Sprial Abyss record, server is calculating statistical data</value>
|
||||
</data>
|
||||
<data name="ServerRecordComputingStatistics2" xml:space="preserve">
|
||||
<value>Failed to fetch data, server is calculating statistical data</value>
|
||||
</data>
|
||||
<data name="ServerRecordInternalException" xml:space="preserve">
|
||||
<value>Failed to upload Sprial Abyss record, server error, please contact developer to fix it</value>
|
||||
</data>
|
||||
<data name="ServerRecordInvalidData" xml:space="preserve">
|
||||
<value>Failed to upload Sprial Abyss record, invalid data detected</value>
|
||||
</data>
|
||||
<data name="ServerRecordInvalidUid" xml:space="preserve">
|
||||
<value>Invalid UID</value>
|
||||
</data>
|
||||
<data name="ServerRecordNotCurrentSchedule" xml:space="preserve">
|
||||
<value>Failed to upload Spiral Abyss record. It is not data for the current schedule.</value>
|
||||
</data>
|
||||
<data name="ServerRecordPreviousRequestNotCompleted" xml:space="preserve">
|
||||
<value>Failed to upload Sprial Abyss record. The record for the current Uid is still being processed. Please do not repeat the operation.</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessAndGachaLogServiceTimeExtended" xml:space="preserve">
|
||||
<value>Uploaded Spiral Abyss record successfully. Received a privilege extension for Snap Hutao Cloud service.</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessButNoPassport" xml:space="preserve">
|
||||
<value>Uploaded abyss record successfully. No Snap Hutao Cloud privilege received as no Snap Hutao account logged in.</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessButNotFirstTimeAtCurrentSchedule" xml:space="preserve">
|
||||
<value>Uploaded abyss record successfully. No Snap Hutao Cloud privilege received as there is not first upload of current schedule.</value>
|
||||
</data>
|
||||
<data name="ServiceAchievementImportResultFormat" xml:space="preserve">
|
||||
<value>New: {0} Achievements | Updated: {1} Achievements | Delete: {2} Achievements</value>
|
||||
</data>
|
||||
@@ -1115,12 +1043,6 @@
|
||||
<data name="ViewDialogDailyNoteNotificationTransformerNotify" xml:space="preserve">
|
||||
<value>Parametric Transformer Notification</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlInputPlaceholder" xml:space="preserve">
|
||||
<value>Input URL</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlTitle" xml:space="preserve">
|
||||
<value>Realtime Note Webhook URL</value>
|
||||
</data>
|
||||
<data name="ViewDialogGachaLogImportTitle" xml:space="preserve">
|
||||
<value>Import wish history</value>
|
||||
</data>
|
||||
@@ -1166,18 +1088,6 @@
|
||||
<data name="ViewDialogGeetestCustomUrlTitle" xml:space="preserve">
|
||||
<value>Configure Geetest CAPTCHA Verficaition API</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportLoginTitle" xml:space="preserve">
|
||||
<value>Login to Snap Hutao Passport</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportRegisterTitle" xml:space="preserve">
|
||||
<value>Signup Snap Hutao Passport</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportResetPasswordTitle" xml:space="preserve">
|
||||
<value>Reset Password of Snap Hutao Passport</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportUnregisterTitle" xml:space="preserve">
|
||||
<value>Delete Snap Hutao Passport</value>
|
||||
</data>
|
||||
<data name="ViewDialogImportExportApp" xml:space="preserve">
|
||||
<value>Export App</value>
|
||||
</data>
|
||||
@@ -1361,9 +1271,6 @@
|
||||
<data name="ViewModelCultivationProjectInvalidName" xml:space="preserve">
|
||||
<value>Can't add plan with invalid name</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteConfigWebhookUrlComplete" xml:space="preserve">
|
||||
<value>Realtime Note Webhook URL successfully configured</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteHoyolabVerificationUnsupported" xml:space="preserve">
|
||||
<value>HoYoLab account does not support Realtime Notes verification</value>
|
||||
</data>
|
||||
@@ -1503,7 +1410,7 @@
|
||||
<value>Failed to create desktop shortcut</value>
|
||||
</data>
|
||||
<data name="ViewModelSettingGeetestCustomUrlSucceed" xml:space="preserve">
|
||||
<value>CAPTCHA Verification composite URL successfully configured</value>
|
||||
<value>无感验证复合 Url 配置成功</value>
|
||||
</data>
|
||||
<data name="ViewModelSettingSetDataFolderSuccess" xml:space="preserve">
|
||||
<value>Set data directory successfully. Restart to apply changes.</value>
|
||||
@@ -1688,18 +1595,6 @@
|
||||
<data name="ViewPageDailyNoteAddEntryToolTip" xml:space="preserve">
|
||||
<value>Add</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteAttendanceStatusInfo" xml:space="preserve">
|
||||
<value>Encounter Points Status</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookDescription" xml:space="preserve">
|
||||
<value>Push data to specific webhook after refreshing Realtime Note</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookHeader" xml:space="preserve">
|
||||
<value>Config Webhook</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteDataInteropHeader" xml:space="preserve">
|
||||
<value>Data Interoperability</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteNotificationHeader" xml:space="preserve">
|
||||
<value>Notification</value>
|
||||
</data>
|
||||
@@ -1940,9 +1835,6 @@
|
||||
<data name="ViewPageHutaoPassportResetPasswordHeader" xml:space="preserve">
|
||||
<value>Reset Password</value>
|
||||
</data>
|
||||
<data name="ViewPageHutaoPassportResetPasswordHint" xml:space="preserve">
|
||||
<value>Delete Snap Hutao Passport will cause your data to lose without any recovery option</value>
|
||||
</data>
|
||||
<data name="ViewPageHutaoPassportUserNameHint" xml:space="preserve">
|
||||
<value>Enter your email</value>
|
||||
</data>
|
||||
@@ -1991,21 +1883,12 @@
|
||||
<data name="ViewPageLaunchGameAppearanceScreenWidthHeader" xml:space="preserve">
|
||||
<value>Width</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameArgumentsDescription" xml:space="preserve">
|
||||
<value>Modify its default behavior at game startup</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameArgumentsHeader" xml:space="preserve">
|
||||
<value>Start-up Arguments</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameCommonHeader" xml:space="preserve">
|
||||
<value>General</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameConfigurationSaveHint" xml:space="preserve">
|
||||
<value>All options will be saved only after the game is launched successfully.</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameFileHeader" xml:space="preserve">
|
||||
<value>File</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameMonitorsDescription" xml:space="preserve">
|
||||
<value>Run the software on the selected display</value>
|
||||
</data>
|
||||
@@ -2021,12 +1904,6 @@
|
||||
<data name="ViewPageLaunchGameOptionsHeader" xml:space="preserve">
|
||||
<value>Game Options</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameProcessHeader" xml:space="preserve">
|
||||
<value>Progress</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameRegistryHeader" xml:space="preserve">
|
||||
<value>Registry</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameResourceDiffHeader" xml:space="preserve">
|
||||
<value>OTA Package</value>
|
||||
</data>
|
||||
@@ -2225,50 +2102,8 @@
|
||||
<data name="ViewpageSettingHomeHeader" xml:space="preserve">
|
||||
<value>Home</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportDangerZoneDescription" xml:space="preserve">
|
||||
<value>Proceed with caution</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportDangerZoneHeader" xml:space="preserve">
|
||||
<value>Danger Zone</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportGachaLogExpiredAtHeader" xml:space="preserve">
|
||||
<value>Snap Hutao Cloud Expiring in</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportHeader" xml:space="preserve">
|
||||
<value>Snap Hutao Passport</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLicensedDeveloperDescription" xml:space="preserve">
|
||||
<value>You are unlimited in any Snap Hutao Cloud features</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLicensedDeveloperHeader" xml:space="preserve">
|
||||
<value>Certificated Developer</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLoginAction" xml:space="preserve">
|
||||
<value>Sign in</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLogoutAction" xml:space="preserve">
|
||||
<value>Sign out</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportMaintainerDescription" xml:space="preserve">
|
||||
<value>You are unlimited in any testing feature</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportMaintainerHeader" xml:space="preserve">
|
||||
<value>Snap Hutao developer and maintainer</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRedeemCodeDescription" xml:space="preserve">
|
||||
<value>We sometimes give away Snap Hutao Cloud redemption codes to some users</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRedeemCodeHeader" xml:space="preserve">
|
||||
<value>Use Redemption Code</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRegisterAction" xml:space="preserve">
|
||||
<value>Register</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportResetPasswordAction" xml:space="preserve">
|
||||
<value>Change Password</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportUnregisterAction" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
<value>Snap Hutao Account</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingIsAdvancedLaunchOptionsEnabledDescription" xml:space="preserve">
|
||||
<value>After a full reading of the Genshin Impact and Snap Hutao user agreements, I choose to enable「Game Launcher - Advanced Features」.</value>
|
||||
@@ -2585,27 +2420,6 @@
|
||||
<data name="WebAnnouncementTimeHoursEndFormat" xml:space="preserve">
|
||||
<value>End in {0} hours</value>
|
||||
</data>
|
||||
<data name="WebBridgeShareCopyToClipboardSuccess" xml:space="preserve">
|
||||
<value>Copied to clipboard</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusFinishedNonReward" xml:space="preserve">
|
||||
<value>Finished</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusForbid" xml:space="preserve">
|
||||
<value>Forbid to Claim</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusInvalid" xml:space="preserve">
|
||||
<value>Invalid</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusTakenAward" xml:space="preserve">
|
||||
<value>Claimed</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusUnfinished" xml:space="preserve">
|
||||
<value>Unfinished</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusWaitTaken" xml:space="preserve">
|
||||
<value>Ready to claim</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteExpeditionRemainHoursFormat" xml:space="preserve">
|
||||
<value>{0} hrs</value>
|
||||
</data>
|
||||
|
||||
@@ -506,78 +506,6 @@
|
||||
<data name="MustSelectUserAndUid" xml:space="preserve">
|
||||
<value>ユーザーとUIDを選択する必要があります</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInsufficientRecordSlot" xml:space="preserve">
|
||||
<value>胡桃クラウドへ保存された祈願履歴の数が現在のアカウントの上限に達しました。</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInsufficientTime" xml:space="preserve">
|
||||
<value>祈願履歴のアップロードサービスが無効か、有効期限が切れています。</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInvalidGachaLogData" xml:space="preserve">
|
||||
<value>祈願データに無効な項目があるため、胡桃クラウドに保存できません。</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceServerDatabaseError" xml:space="preserve">
|
||||
<value>データが異常なため、胡桃クラウドにアップロードできません。 複数のアカウントに跨がってアップロードしないでください。アップロードしたい場合は、クラウド データを削除してもう一度試してください。</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceEmailHasNotRegistered" xml:space="preserve">
|
||||
<value>このメールアドレスは登録されていません。</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceEmailHasRegistered" xml:space="preserve">
|
||||
<value>このメールアドレスは登録済みです。</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceInternalException" xml:space="preserve">
|
||||
<value>登録に失敗しました。サーバーエラーです。解決しない場合は開発者に連絡してください。</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceUnregisterFailed" xml:space="preserve">
|
||||
<value>ユーザーが存在しないため、アカウントを削除できません。</value>
|
||||
</data>
|
||||
<data name="ServerPassportUserInfoNotExist" xml:space="preserve">
|
||||
<value>ユーザーが存在しないため、ユーザーデータを取得出来ません。</value>
|
||||
</data>
|
||||
<data name="ServerPassportUsernameOrPassportIncorrect" xml:space="preserve">
|
||||
<value>ユーザー名またはパスワードが正しくありません。</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyFailed" xml:space="preserve">
|
||||
<value>認証に失敗しました。</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyRequestSuccess" xml:space="preserve">
|
||||
<value>入力されたメールアドレスへ確認コードが送信されました</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyTooFrequent" xml:space="preserve">
|
||||
<value>認証リクエストが多すぎます。一分後にやり直してください。</value>
|
||||
</data>
|
||||
<data name="ServerRecordBannedUid" xml:space="preserve">
|
||||
<value>深境螺旋のデータをアップロードできません。このUIDは胡桃クラウドからBANされています。</value>
|
||||
</data>
|
||||
<data name="ServerRecordComputingStatistics" xml:space="preserve">
|
||||
<value>深境螺旋のデータをアップロードできません。サーバーが統計データを計算しています。</value>
|
||||
</data>
|
||||
<data name="ServerRecordComputingStatistics2" xml:space="preserve">
|
||||
<value>データの取得に失敗しました。サーバーが統計データを計算しています。</value>
|
||||
</data>
|
||||
<data name="ServerRecordInternalException" xml:space="preserve">
|
||||
<value>深境螺旋のデータをアップロードに失敗しました。サーバーエラーです。解決しない場合は開発者に連絡してください。</value>
|
||||
</data>
|
||||
<data name="ServerRecordInvalidData" xml:space="preserve">
|
||||
<value>深境螺旋のデータをアップロードできません。異常なデータを検知しました。</value>
|
||||
</data>
|
||||
<data name="ServerRecordInvalidUid" xml:space="preserve">
|
||||
<value>無効なUIDです。</value>
|
||||
</data>
|
||||
<data name="ServerRecordNotCurrentSchedule" xml:space="preserve">
|
||||
<value>深境螺旋のデータをアップロードできません。現行の期間のデータではありません。</value>
|
||||
</data>
|
||||
<data name="ServerRecordPreviousRequestNotCompleted" xml:space="preserve">
|
||||
<value>深境螺旋のデータをアップロードできません。現在このUIDのレコードを処理中です。繰り返しアップロードしないでください。</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessAndGachaLogServiceTimeExtended" xml:space="preserve">
|
||||
<value>深境螺旋のデータをアップロードしました。胡桃クラウドの利用期間延長特典を受け取りました。</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessButNoPassport" xml:space="preserve">
|
||||
<value>深境螺旋のデータをアップロードしましたが、胡桃クラウドへログインしていないため、利用期間特典を受け取ることは出来ません。</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessButNotFirstTimeAtCurrentSchedule" xml:space="preserve">
|
||||
<value>深境螺旋のデータをアップロードしました。今期は二回以上アップロードしているため、利用期間特典を受け取ることは出来ません。</value>
|
||||
</data>
|
||||
<data name="ServiceAchievementImportResultFormat" xml:space="preserve">
|
||||
<value>{0} つのアチーブメントを追加 | {1} つのアチーブメントを更新 |{2} つのアチーブメントを削除</value>
|
||||
</data>
|
||||
@@ -1115,12 +1043,6 @@
|
||||
<data name="ViewDialogDailyNoteNotificationTransformerNotify" xml:space="preserve">
|
||||
<value>参量物質変化器は使えるようになりました</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlInputPlaceholder" xml:space="preserve">
|
||||
<value>URLを入力</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlTitle" xml:space="preserve">
|
||||
<value>リアルタイムノートのWebhook URL</value>
|
||||
</data>
|
||||
<data name="ViewDialogGachaLogImportTitle" xml:space="preserve">
|
||||
<value>祈願記録をインポート</value>
|
||||
</data>
|
||||
@@ -1166,18 +1088,6 @@
|
||||
<data name="ViewDialogGeetestCustomUrlTitle" xml:space="preserve">
|
||||
<value>Geetest/CAPTCHA 認証APIの設定</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportLoginTitle" xml:space="preserve">
|
||||
<value>胡桃パスポートへログイン</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportRegisterTitle" xml:space="preserve">
|
||||
<value>胡桃パスポートの登録</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportResetPasswordTitle" xml:space="preserve">
|
||||
<value>胡桃パスポートのパスワードをリセット</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportUnregisterTitle" xml:space="preserve">
|
||||
<value>胡桃パスポート アカウントの削除</value>
|
||||
</data>
|
||||
<data name="ViewDialogImportExportApp" xml:space="preserve">
|
||||
<value>Appをエクスポート</value>
|
||||
</data>
|
||||
@@ -1361,9 +1271,6 @@
|
||||
<data name="ViewModelCultivationProjectInvalidName" xml:space="preserve">
|
||||
<value>育成計画名に無効な言葉が入っています</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteConfigWebhookUrlComplete" xml:space="preserve">
|
||||
<value>リアルタイムノートのWebhook URLの設定に成功しました。</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteHoyolabVerificationUnsupported" xml:space="preserve">
|
||||
<value>HoYoLabユーザーのリアルタイムノートはサポートしていません。</value>
|
||||
</data>
|
||||
@@ -1688,18 +1595,6 @@
|
||||
<data name="ViewPageDailyNoteAddEntryToolTip" xml:space="preserve">
|
||||
<value>追加</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteAttendanceStatusInfo" xml:space="preserve">
|
||||
<value>冒険ポイントのステータス</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookDescription" xml:space="preserve">
|
||||
<value>リアルタイムノートの更新時に、指定したWebhookへPOSTを送信します。</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookHeader" xml:space="preserve">
|
||||
<value>Webhookの設定</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteDataInteropHeader" xml:space="preserve">
|
||||
<value>データの相互運用</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteNotificationHeader" xml:space="preserve">
|
||||
<value>通知</value>
|
||||
</data>
|
||||
@@ -1940,9 +1835,6 @@
|
||||
<data name="ViewPageHutaoPassportResetPasswordHeader" xml:space="preserve">
|
||||
<value>パスワードを忘れました</value>
|
||||
</data>
|
||||
<data name="ViewPageHutaoPassportResetPasswordHint" xml:space="preserve">
|
||||
<value>削除されたアカウントのデータは永久的に削除され、復元することは出来ません。</value>
|
||||
</data>
|
||||
<data name="ViewPageHutaoPassportUserNameHint" xml:space="preserve">
|
||||
<value>メールアドレスを入力してください。</value>
|
||||
</data>
|
||||
@@ -1991,21 +1883,12 @@
|
||||
<data name="ViewPageLaunchGameAppearanceScreenWidthHeader" xml:space="preserve">
|
||||
<value>幅</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameArgumentsDescription" xml:space="preserve">
|
||||
<value>ゲーム開始時の動作を変更します。</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameArgumentsHeader" xml:space="preserve">
|
||||
<value>コマンドラインパラメーター</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameCommonHeader" xml:space="preserve">
|
||||
<value>一般</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameConfigurationSaveHint" xml:space="preserve">
|
||||
<value>これらの設定はゲームが正常に起動した時のみ保存されます。</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameFileHeader" xml:space="preserve">
|
||||
<value>ファイル</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameMonitorsDescription" xml:space="preserve">
|
||||
<value>指定したディスプレイで実行</value>
|
||||
</data>
|
||||
@@ -2021,12 +1904,6 @@
|
||||
<data name="ViewPageLaunchGameOptionsHeader" xml:space="preserve">
|
||||
<value>ゲームオプション</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameProcessHeader" xml:space="preserve">
|
||||
<value>プロセス</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameRegistryHeader" xml:space="preserve">
|
||||
<value>レジストリ</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameResourceDiffHeader" xml:space="preserve">
|
||||
<value>増分パック</value>
|
||||
</data>
|
||||
@@ -2225,51 +2102,9 @@
|
||||
<data name="ViewpageSettingHomeHeader" xml:space="preserve">
|
||||
<value>ホーム</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportDangerZoneDescription" xml:space="preserve">
|
||||
<value>考え直して!!</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportDangerZoneHeader" xml:space="preserve">
|
||||
<value>危険な操作</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportGachaLogExpiredAtHeader" xml:space="preserve">
|
||||
<value>胡桃クラウドサービスの有効期限</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportHeader" xml:space="preserve">
|
||||
<value>胡桃アカウント</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLicensedDeveloperDescription" xml:space="preserve">
|
||||
<value>胡桃クラウドのサービスをベースにした様々な機能が制限なく利用できます</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLicensedDeveloperHeader" xml:space="preserve">
|
||||
<value>認定済みの共同開発者</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLoginAction" xml:space="preserve">
|
||||
<value>ログイン</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLogoutAction" xml:space="preserve">
|
||||
<value>ログアウト</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportMaintainerDescription" xml:space="preserve">
|
||||
<value>テスト段階のあらゆる機能を使用できます。</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportMaintainerHeader" xml:space="preserve">
|
||||
<value>胡桃の運用と開発または保守</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRedeemCodeDescription" xml:space="preserve">
|
||||
<value>胡桃クラウドの引き替えコードを一部のユーザーに配布する事があります。</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRedeemCodeHeader" xml:space="preserve">
|
||||
<value>引き替えコードの使用</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRegisterAction" xml:space="preserve">
|
||||
<value>登録</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportResetPasswordAction" xml:space="preserve">
|
||||
<value>パスワードの変更</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportUnregisterAction" xml:space="preserve">
|
||||
<value>アカウントの削除</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingIsAdvancedLaunchOptionsEnabledDescription" xml:space="preserve">
|
||||
<value>原神およびSnap Hutaoの利用規約を全て熟読し、その後に『ゲームランチャー - 上級者向け設定』を有効にします。</value>
|
||||
</data>
|
||||
@@ -2585,27 +2420,6 @@
|
||||
<data name="WebAnnouncementTimeHoursEndFormat" xml:space="preserve">
|
||||
<value>{0} 時間後に終了</value>
|
||||
</data>
|
||||
<data name="WebBridgeShareCopyToClipboardSuccess" xml:space="preserve">
|
||||
<value>クリップボードにコピーしました。</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusFinishedNonReward" xml:space="preserve">
|
||||
<value>完了しました。</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusForbid" xml:space="preserve">
|
||||
<value>獲得の禁止</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusInvalid" xml:space="preserve">
|
||||
<value>無効</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusTakenAward" xml:space="preserve">
|
||||
<value>受け取り済み</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusUnfinished" xml:space="preserve">
|
||||
<value>未完了</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusWaitTaken" xml:space="preserve">
|
||||
<value>獲得可能</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteExpeditionRemainHoursFormat" xml:space="preserve">
|
||||
<value>{0} 時</value>
|
||||
</data>
|
||||
@@ -2670,7 +2484,7 @@
|
||||
<value>利用可能</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteTransformerReady" xml:space="preserve">
|
||||
<value>使用可能</value>
|
||||
<value>もうすぐ完成</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteTransformerSecondsFormat" xml:space="preserve">
|
||||
<value>{0} 秒</value>
|
||||
|
||||
@@ -506,78 +506,6 @@
|
||||
<data name="MustSelectUserAndUid" xml:space="preserve">
|
||||
<value>유저와 UID를 선택하세요</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInsufficientRecordSlot" xml:space="preserve">
|
||||
<value>胡桃云保存的祈愿记录存档数已达当前账号上限</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInsufficientTime" xml:space="preserve">
|
||||
<value>未开通祈愿记录上传服务或已到期</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInvalidGachaLogData" xml:space="preserve">
|
||||
<value>祈愿数据存在无效的物品,无法保存至胡桃云</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceServerDatabaseError" xml:space="preserve">
|
||||
<value>数据异常,无法保存至云端,请勿跨账号上传或尝试删除云端数据后重试</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceEmailHasNotRegistered" xml:space="preserve">
|
||||
<value>当前邮箱尚未注册</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceEmailHasRegistered" xml:space="preserve">
|
||||
<value>当前邮箱已被注册</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceInternalException" xml:space="preserve">
|
||||
<value>注册失败,服务器异常,请尽快联系开发者解决</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceUnregisterFailed" xml:space="preserve">
|
||||
<value>用户不存在,注销失败</value>
|
||||
</data>
|
||||
<data name="ServerPassportUserInfoNotExist" xml:space="preserve">
|
||||
<value>用户不存在,获取用户信息失败</value>
|
||||
</data>
|
||||
<data name="ServerPassportUsernameOrPassportIncorrect" xml:space="preserve">
|
||||
<value>用户名或密码错误</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyFailed" xml:space="preserve">
|
||||
<value>验证失败</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyRequestSuccess" xml:space="preserve">
|
||||
<value>验证码已发送至邮箱</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyTooFrequent" xml:space="preserve">
|
||||
<value>验证请求过快,请 1 分钟后再试</value>
|
||||
</data>
|
||||
<data name="ServerRecordBannedUid" xml:space="preserve">
|
||||
<value>上传深渊记录失败,当前 Uid 已被胡桃数据库封禁</value>
|
||||
</data>
|
||||
<data name="ServerRecordComputingStatistics" xml:space="preserve">
|
||||
<value>上传深渊记录失败,正在计算统计数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordComputingStatistics2" xml:space="preserve">
|
||||
<value>获取数据失败,正在计算统计数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordInternalException" xml:space="preserve">
|
||||
<value>上传深渊记录失败,服务器异常,请尽快联系开发者解决</value>
|
||||
</data>
|
||||
<data name="ServerRecordInvalidData" xml:space="preserve">
|
||||
<value>上传深渊记录失败,存在无效的数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordInvalidUid" xml:space="preserve">
|
||||
<value>无效的 Uid</value>
|
||||
</data>
|
||||
<data name="ServerRecordNotCurrentSchedule" xml:space="preserve">
|
||||
<value>上传深渊记录失败,不是本期数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordPreviousRequestNotCompleted" xml:space="preserve">
|
||||
<value>上传深渊记录失败,当前 Uid 的记录仍在处理中,请勿重复操作</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessAndGachaLogServiceTimeExtended" xml:space="preserve">
|
||||
<value>上传深渊记录成功,获赠祈愿记录上传服务时长</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessButNoPassport" xml:space="preserve">
|
||||
<value>上传深渊记录成功,但未登录胡桃账号,无法获赠祈愿记录上传服务时长</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessButNotFirstTimeAtCurrentSchedule" xml:space="preserve">
|
||||
<value>上传深渊记录成功,但不是本期首次提交,无法获赠祈愿记录上传服务时长</value>
|
||||
</data>
|
||||
<data name="ServiceAchievementImportResultFormat" xml:space="preserve">
|
||||
<value>新增:{0} 个成就 | 更新:{1} 个成就 | 删除:{2} 个成就</value>
|
||||
</data>
|
||||
@@ -1115,12 +1043,6 @@
|
||||
<data name="ViewDialogDailyNoteNotificationTransformerNotify" xml:space="preserve">
|
||||
<value>매개 변수 변환기 알림</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlInputPlaceholder" xml:space="preserve">
|
||||
<value>请输入 Url</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlTitle" xml:space="preserve">
|
||||
<value>实时便笺 Webhook Url</value>
|
||||
</data>
|
||||
<data name="ViewDialogGachaLogImportTitle" xml:space="preserve">
|
||||
<value>기원 기록 가져오기</value>
|
||||
</data>
|
||||
@@ -1166,18 +1088,6 @@
|
||||
<data name="ViewDialogGeetestCustomUrlTitle" xml:space="preserve">
|
||||
<value>配置无感验证接口</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportLoginTitle" xml:space="preserve">
|
||||
<value>登录胡桃通行证</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportRegisterTitle" xml:space="preserve">
|
||||
<value>注册胡桃通行证</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportResetPasswordTitle" xml:space="preserve">
|
||||
<value>重置胡桃通行证密码</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportUnregisterTitle" xml:space="preserve">
|
||||
<value>注销胡桃通行证账号</value>
|
||||
</data>
|
||||
<data name="ViewDialogImportExportApp" xml:space="preserve">
|
||||
<value>앱 내보내기</value>
|
||||
</data>
|
||||
@@ -1361,9 +1271,6 @@
|
||||
<data name="ViewModelCultivationProjectInvalidName" xml:space="preserve">
|
||||
<value>잘못된 이름을 가진 일정은 추가할 수 없습니다</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteConfigWebhookUrlComplete" xml:space="preserve">
|
||||
<value>实时便笺 Webhook Url 配置成功</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteHoyolabVerificationUnsupported" xml:space="preserve">
|
||||
<value>HoYoLab 계정은 실시간 메모 확인 기능을 지원하지 않습니다</value>
|
||||
</data>
|
||||
@@ -1688,18 +1595,6 @@
|
||||
<data name="ViewPageDailyNoteAddEntryToolTip" xml:space="preserve">
|
||||
<value>추가</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteAttendanceStatusInfo" xml:space="preserve">
|
||||
<value>历练点获取详情</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookDescription" xml:space="preserve">
|
||||
<value>在实时便笺刷新后推送到指定的 Webhook</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookHeader" xml:space="preserve">
|
||||
<value>配置 Webhook</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteDataInteropHeader" xml:space="preserve">
|
||||
<value>数据互操作</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteNotificationHeader" xml:space="preserve">
|
||||
<value>알림</value>
|
||||
</data>
|
||||
@@ -1940,9 +1835,6 @@
|
||||
<data name="ViewPageHutaoPassportResetPasswordHeader" xml:space="preserve">
|
||||
<value>비밀번호 재설정</value>
|
||||
</data>
|
||||
<data name="ViewPageHutaoPassportResetPasswordHint" xml:space="preserve">
|
||||
<value>注销账号的数据将永远丢失,无法恢复</value>
|
||||
</data>
|
||||
<data name="ViewPageHutaoPassportUserNameHint" xml:space="preserve">
|
||||
<value>이메일을 입력하세요</value>
|
||||
</data>
|
||||
@@ -1991,21 +1883,12 @@
|
||||
<data name="ViewPageLaunchGameAppearanceScreenWidthHeader" xml:space="preserve">
|
||||
<value>너비</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameArgumentsDescription" xml:space="preserve">
|
||||
<value>在游戏启动时修改其默认行为</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameArgumentsHeader" xml:space="preserve">
|
||||
<value>启动参数</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameCommonHeader" xml:space="preserve">
|
||||
<value>보통</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameConfigurationSaveHint" xml:space="preserve">
|
||||
<value>모든 설정은 게임을 성공적으로 실행한 후에 저장됩니다</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameFileHeader" xml:space="preserve">
|
||||
<value>文件</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameMonitorsDescription" xml:space="preserve">
|
||||
<value>지정한 모니터에서 실행</value>
|
||||
</data>
|
||||
@@ -2021,12 +1904,6 @@
|
||||
<data name="ViewPageLaunchGameOptionsHeader" xml:space="preserve">
|
||||
<value>게임 설정</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameProcessHeader" xml:space="preserve">
|
||||
<value>进程</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameRegistryHeader" xml:space="preserve">
|
||||
<value>注册表</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameResourceDiffHeader" xml:space="preserve">
|
||||
<value>증분 패키지</value>
|
||||
</data>
|
||||
@@ -2225,50 +2102,8 @@
|
||||
<data name="ViewpageSettingHomeHeader" xml:space="preserve">
|
||||
<value>主页</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportDangerZoneDescription" xml:space="preserve">
|
||||
<value>三思而后行</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportDangerZoneHeader" xml:space="preserve">
|
||||
<value>危险操作</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportGachaLogExpiredAtHeader" xml:space="preserve">
|
||||
<value>胡桃云服务到期时间</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportHeader" xml:space="preserve">
|
||||
<value>胡桃通行证账号</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLicensedDeveloperDescription" xml:space="preserve">
|
||||
<value>您可以无限制使用任何基于胡桃云服务的功能</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLicensedDeveloperHeader" xml:space="preserve">
|
||||
<value>已认证的合作开发者</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLoginAction" xml:space="preserve">
|
||||
<value>登录</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLogoutAction" xml:space="preserve">
|
||||
<value>退出登录</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportMaintainerDescription" xml:space="preserve">
|
||||
<value>您可以无限制的使用任何测试功能</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportMaintainerHeader" xml:space="preserve">
|
||||
<value>胡桃开发/运维</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRedeemCodeDescription" xml:space="preserve">
|
||||
<value>我们有时会向某些用户赠送胡桃云兑换码</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRedeemCodeHeader" xml:space="preserve">
|
||||
<value>使用兑换码</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRegisterAction" xml:space="preserve">
|
||||
<value>注册</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportResetPasswordAction" xml:space="preserve">
|
||||
<value>修改密码</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportUnregisterAction" xml:space="preserve">
|
||||
<value>注销账号</value>
|
||||
<value>호두 계정</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingIsAdvancedLaunchOptionsEnabledDescription" xml:space="preserve">
|
||||
<value>원신과 호두의 사용자 계약을 완전히 읽은 후, 「게임 고급 기능」을 사용</value>
|
||||
@@ -2585,27 +2420,6 @@
|
||||
<data name="WebAnnouncementTimeHoursEndFormat" xml:space="preserve">
|
||||
<value>{0}시간 후 종료</value>
|
||||
</data>
|
||||
<data name="WebBridgeShareCopyToClipboardSuccess" xml:space="preserve">
|
||||
<value>已复制到剪贴板</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusFinishedNonReward" xml:space="preserve">
|
||||
<value>已完成</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusForbid" xml:space="preserve">
|
||||
<value>禁止领取</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusInvalid" xml:space="preserve">
|
||||
<value>无效</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusTakenAward" xml:space="preserve">
|
||||
<value>已领取</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusUnfinished" xml:space="preserve">
|
||||
<value>尚未完成</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusWaitTaken" xml:space="preserve">
|
||||
<value>等待领取</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteExpeditionRemainHoursFormat" xml:space="preserve">
|
||||
<value>{0}시간</value>
|
||||
</data>
|
||||
|
||||
@@ -506,78 +506,6 @@
|
||||
<data name="MustSelectUserAndUid" xml:space="preserve">
|
||||
<value>必须先选择一个用户与角色</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInsufficientRecordSlot" xml:space="preserve">
|
||||
<value>胡桃云保存的祈愿记录存档数已达当前账号上限</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInsufficientTime" xml:space="preserve">
|
||||
<value>未开通祈愿记录上传服务或已到期</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInvalidGachaLogData" xml:space="preserve">
|
||||
<value>祈愿数据存在无效的物品,无法保存至胡桃云</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceServerDatabaseError" xml:space="preserve">
|
||||
<value>数据异常,无法保存至云端,请勿跨账号上传或尝试删除云端数据后重试</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceEmailHasNotRegistered" xml:space="preserve">
|
||||
<value>当前邮箱尚未注册</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceEmailHasRegistered" xml:space="preserve">
|
||||
<value>当前邮箱已被注册</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceInternalException" xml:space="preserve">
|
||||
<value>注册失败,服务器异常,请尽快联系开发者解决</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceUnregisterFailed" xml:space="preserve">
|
||||
<value>用户不存在,注销失败</value>
|
||||
</data>
|
||||
<data name="ServerPassportUserInfoNotExist" xml:space="preserve">
|
||||
<value>用户不存在,获取用户信息失败</value>
|
||||
</data>
|
||||
<data name="ServerPassportUsernameOrPassportIncorrect" xml:space="preserve">
|
||||
<value>用户名或密码错误</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyFailed" xml:space="preserve">
|
||||
<value>验证失败</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyRequestSuccess" xml:space="preserve">
|
||||
<value>验证码已发送至邮箱</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyTooFrequent" xml:space="preserve">
|
||||
<value>验证请求过快,请 1 分钟后再试</value>
|
||||
</data>
|
||||
<data name="ServerRecordBannedUid" xml:space="preserve">
|
||||
<value>上传深渊记录失败,当前 Uid 已被胡桃数据库封禁</value>
|
||||
</data>
|
||||
<data name="ServerRecordComputingStatistics" xml:space="preserve">
|
||||
<value>上传深渊记录失败,正在计算统计数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordComputingStatistics2" xml:space="preserve">
|
||||
<value>获取数据失败,正在计算统计数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordInternalException" xml:space="preserve">
|
||||
<value>上传深渊记录失败,服务器异常,请尽快联系开发者解决</value>
|
||||
</data>
|
||||
<data name="ServerRecordInvalidData" xml:space="preserve">
|
||||
<value>上传深渊记录失败,存在无效的数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordInvalidUid" xml:space="preserve">
|
||||
<value>无效的 Uid</value>
|
||||
</data>
|
||||
<data name="ServerRecordNotCurrentSchedule" xml:space="preserve">
|
||||
<value>上传深渊记录失败,不是本期数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordPreviousRequestNotCompleted" xml:space="preserve">
|
||||
<value>上传深渊记录失败,当前 Uid 的记录仍在处理中,请勿重复操作</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessAndGachaLogServiceTimeExtended" xml:space="preserve">
|
||||
<value>上传深渊记录成功,获赠祈愿记录上传服务时长</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessButNoPassport" xml:space="preserve">
|
||||
<value>上传深渊记录成功,但未登录胡桃账号,无法获赠祈愿记录上传服务时长</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessButNotFirstTimeAtCurrentSchedule" xml:space="preserve">
|
||||
<value>上传深渊记录成功,但不是本期首次提交,无法获赠祈愿记录上传服务时长</value>
|
||||
</data>
|
||||
<data name="ServiceAchievementImportResultFormat" xml:space="preserve">
|
||||
<value>新增:{0} 个成就 | 更新:{1} 个成就 | 删除:{2} 个成就</value>
|
||||
</data>
|
||||
@@ -1115,12 +1043,6 @@
|
||||
<data name="ViewDialogDailyNoteNotificationTransformerNotify" xml:space="preserve">
|
||||
<value>参量质变仪提醒</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlInputPlaceholder" xml:space="preserve">
|
||||
<value>请输入 Url</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlTitle" xml:space="preserve">
|
||||
<value>实时便笺 Webhook Url</value>
|
||||
</data>
|
||||
<data name="ViewDialogGachaLogImportTitle" xml:space="preserve">
|
||||
<value>导入祈愿记录</value>
|
||||
</data>
|
||||
@@ -1166,18 +1088,6 @@
|
||||
<data name="ViewDialogGeetestCustomUrlTitle" xml:space="preserve">
|
||||
<value>配置无感验证接口</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportLoginTitle" xml:space="preserve">
|
||||
<value>登录胡桃通行证</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportRegisterTitle" xml:space="preserve">
|
||||
<value>注册胡桃通行证</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportResetPasswordTitle" xml:space="preserve">
|
||||
<value>重置胡桃通行证密码</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportUnregisterTitle" xml:space="preserve">
|
||||
<value>注销胡桃通行证账号</value>
|
||||
</data>
|
||||
<data name="ViewDialogImportExportApp" xml:space="preserve">
|
||||
<value>导出 App</value>
|
||||
</data>
|
||||
@@ -1361,9 +1271,6 @@
|
||||
<data name="ViewModelCultivationProjectInvalidName" xml:space="preserve">
|
||||
<value>不能添加名称无效的计划</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteConfigWebhookUrlComplete" xml:space="preserve">
|
||||
<value>实时便笺 Webhook Url 配置成功</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteHoyolabVerificationUnsupported" xml:space="preserve">
|
||||
<value>HoYoLab 账号不支持验证实时便笺</value>
|
||||
</data>
|
||||
@@ -1688,18 +1595,6 @@
|
||||
<data name="ViewPageDailyNoteAddEntryToolTip" xml:space="preserve">
|
||||
<value>添加</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteAttendanceStatusInfo" xml:space="preserve">
|
||||
<value>历练点获取详情</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookDescription" xml:space="preserve">
|
||||
<value>在实时便笺刷新后推送到指定的 Webhook</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookHeader" xml:space="preserve">
|
||||
<value>配置 Webhook</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteDataInteropHeader" xml:space="preserve">
|
||||
<value>数据互操作</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteNotificationHeader" xml:space="preserve">
|
||||
<value>通知</value>
|
||||
</data>
|
||||
@@ -1940,9 +1835,6 @@
|
||||
<data name="ViewPageHutaoPassportResetPasswordHeader" xml:space="preserve">
|
||||
<value>重置密码</value>
|
||||
</data>
|
||||
<data name="ViewPageHutaoPassportResetPasswordHint" xml:space="preserve">
|
||||
<value>注销账号的数据将永远丢失,无法恢复</value>
|
||||
</data>
|
||||
<data name="ViewPageHutaoPassportUserNameHint" xml:space="preserve">
|
||||
<value>请输入邮箱</value>
|
||||
</data>
|
||||
@@ -1991,21 +1883,12 @@
|
||||
<data name="ViewPageLaunchGameAppearanceScreenWidthHeader" xml:space="preserve">
|
||||
<value>宽度</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameArgumentsDescription" xml:space="preserve">
|
||||
<value>在游戏启动时修改其默认行为</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameArgumentsHeader" xml:space="preserve">
|
||||
<value>启动参数</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameCommonHeader" xml:space="preserve">
|
||||
<value>常规</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameConfigurationSaveHint" xml:space="preserve">
|
||||
<value>所有选项仅会在启动游戏成功后保存</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameFileHeader" xml:space="preserve">
|
||||
<value>文件</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameMonitorsDescription" xml:space="preserve">
|
||||
<value>在指定的显示器上运行</value>
|
||||
</data>
|
||||
@@ -2021,12 +1904,6 @@
|
||||
<data name="ViewPageLaunchGameOptionsHeader" xml:space="preserve">
|
||||
<value>游戏选项</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameProcessHeader" xml:space="preserve">
|
||||
<value>进程</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameRegistryHeader" xml:space="preserve">
|
||||
<value>注册表</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameResourceDiffHeader" xml:space="preserve">
|
||||
<value>增量包</value>
|
||||
</data>
|
||||
@@ -2225,50 +2102,8 @@
|
||||
<data name="ViewpageSettingHomeHeader" xml:space="preserve">
|
||||
<value>主页</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportDangerZoneDescription" xml:space="preserve">
|
||||
<value>三思而后行</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportDangerZoneHeader" xml:space="preserve">
|
||||
<value>危险操作</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportGachaLogExpiredAtHeader" xml:space="preserve">
|
||||
<value>胡桃云服务到期时间</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportHeader" xml:space="preserve">
|
||||
<value>胡桃通行证账号</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLicensedDeveloperDescription" xml:space="preserve">
|
||||
<value>您可以无限制使用任何基于胡桃云服务的功能</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLicensedDeveloperHeader" xml:space="preserve">
|
||||
<value>已认证的合作开发者</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLoginAction" xml:space="preserve">
|
||||
<value>登录</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLogoutAction" xml:space="preserve">
|
||||
<value>退出登录</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportMaintainerDescription" xml:space="preserve">
|
||||
<value>您可以无限制的使用任何测试功能</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportMaintainerHeader" xml:space="preserve">
|
||||
<value>胡桃开发/运维</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRedeemCodeDescription" xml:space="preserve">
|
||||
<value>我们有时会向某些用户赠送胡桃云兑换码</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRedeemCodeHeader" xml:space="preserve">
|
||||
<value>使用兑换码</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRegisterAction" xml:space="preserve">
|
||||
<value>注册</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportResetPasswordAction" xml:space="preserve">
|
||||
<value>修改密码</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportUnregisterAction" xml:space="preserve">
|
||||
<value>注销账号</value>
|
||||
<value>胡桃账号</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingIsAdvancedLaunchOptionsEnabledDescription" xml:space="preserve">
|
||||
<value>在完整阅读原神和胡桃工具箱用户协议后,我选择启用「启动游戏-高级功能」</value>
|
||||
@@ -2585,27 +2420,6 @@
|
||||
<data name="WebAnnouncementTimeHoursEndFormat" xml:space="preserve">
|
||||
<value>{0} 小时后结束</value>
|
||||
</data>
|
||||
<data name="WebBridgeShareCopyToClipboardSuccess" xml:space="preserve">
|
||||
<value>已复制到剪贴板</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusFinishedNonReward" xml:space="preserve">
|
||||
<value>已完成</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusForbid" xml:space="preserve">
|
||||
<value>禁止领取</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusInvalid" xml:space="preserve">
|
||||
<value>无效</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusTakenAward" xml:space="preserve">
|
||||
<value>已领取</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusUnfinished" xml:space="preserve">
|
||||
<value>尚未完成</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusWaitTaken" xml:space="preserve">
|
||||
<value>等待领取</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteExpeditionRemainHoursFormat" xml:space="preserve">
|
||||
<value>{0} 时</value>
|
||||
</data>
|
||||
|
||||
@@ -506,78 +506,6 @@
|
||||
<data name="MustSelectUserAndUid" xml:space="preserve">
|
||||
<value>必須先選擇一個用戶與角色</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInsufficientRecordSlot" xml:space="preserve">
|
||||
<value>胡桃云保存的祈愿记录存档数已达当前账号上限</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInsufficientTime" xml:space="preserve">
|
||||
<value>未开通祈愿记录上传服务或已到期</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceInvalidGachaLogData" xml:space="preserve">
|
||||
<value>祈愿数据存在无效的物品,无法保存至胡桃云</value>
|
||||
</data>
|
||||
<data name="ServerGachaLogServiceServerDatabaseError" xml:space="preserve">
|
||||
<value>数据异常,无法保存至云端,请勿跨账号上传或尝试删除云端数据后重试</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceEmailHasNotRegistered" xml:space="preserve">
|
||||
<value>当前邮箱尚未注册</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceEmailHasRegistered" xml:space="preserve">
|
||||
<value>当前邮箱已被注册</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceInternalException" xml:space="preserve">
|
||||
<value>注册失败,服务器异常,请尽快联系开发者解决</value>
|
||||
</data>
|
||||
<data name="ServerPassportServiceUnregisterFailed" xml:space="preserve">
|
||||
<value>用户不存在,注销失败</value>
|
||||
</data>
|
||||
<data name="ServerPassportUserInfoNotExist" xml:space="preserve">
|
||||
<value>用户不存在,获取用户信息失败</value>
|
||||
</data>
|
||||
<data name="ServerPassportUsernameOrPassportIncorrect" xml:space="preserve">
|
||||
<value>用户名或密码错误</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyFailed" xml:space="preserve">
|
||||
<value>验证失败</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyRequestSuccess" xml:space="preserve">
|
||||
<value>验证码已发送至邮箱</value>
|
||||
</data>
|
||||
<data name="ServerPassportVerifyTooFrequent" xml:space="preserve">
|
||||
<value>验证请求过快,请 1 分钟后再试</value>
|
||||
</data>
|
||||
<data name="ServerRecordBannedUid" xml:space="preserve">
|
||||
<value>上传深渊记录失败,当前 Uid 已被胡桃数据库封禁</value>
|
||||
</data>
|
||||
<data name="ServerRecordComputingStatistics" xml:space="preserve">
|
||||
<value>上传深渊记录失败,正在计算统计数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordComputingStatistics2" xml:space="preserve">
|
||||
<value>获取数据失败,正在计算统计数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordInternalException" xml:space="preserve">
|
||||
<value>上传深渊记录失败,服务器异常,请尽快联系开发者解决</value>
|
||||
</data>
|
||||
<data name="ServerRecordInvalidData" xml:space="preserve">
|
||||
<value>上传深渊记录失败,存在无效的数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordInvalidUid" xml:space="preserve">
|
||||
<value>无效的 Uid</value>
|
||||
</data>
|
||||
<data name="ServerRecordNotCurrentSchedule" xml:space="preserve">
|
||||
<value>上传深渊记录失败,不是本期数据</value>
|
||||
</data>
|
||||
<data name="ServerRecordPreviousRequestNotCompleted" xml:space="preserve">
|
||||
<value>上传深渊记录失败,当前 Uid 的记录仍在处理中,请勿重复操作</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessAndGachaLogServiceTimeExtended" xml:space="preserve">
|
||||
<value>上传深渊记录成功,获赠祈愿记录上传服务时长</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessButNoPassport" xml:space="preserve">
|
||||
<value>上传深渊记录成功,但未登录胡桃账号,无法获赠祈愿记录上传服务时长</value>
|
||||
</data>
|
||||
<data name="ServerRecordUploadSuccessButNotFirstTimeAtCurrentSchedule" xml:space="preserve">
|
||||
<value>上传深渊记录成功,但不是本期首次提交,无法获赠祈愿记录上传服务时长</value>
|
||||
</data>
|
||||
<data name="ServiceAchievementImportResultFormat" xml:space="preserve">
|
||||
<value>新增:{0} 個成就 | 更新:{1} 個成就 | 删除:{2} 個成就</value>
|
||||
</data>
|
||||
@@ -1115,12 +1043,6 @@
|
||||
<data name="ViewDialogDailyNoteNotificationTransformerNotify" xml:space="preserve">
|
||||
<value>參數質變儀提醒</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlInputPlaceholder" xml:space="preserve">
|
||||
<value>请输入 Url</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlTitle" xml:space="preserve">
|
||||
<value>实时便笺 Webhook Url</value>
|
||||
</data>
|
||||
<data name="ViewDialogGachaLogImportTitle" xml:space="preserve">
|
||||
<value>匯入祈願記錄</value>
|
||||
</data>
|
||||
@@ -1166,18 +1088,6 @@
|
||||
<data name="ViewDialogGeetestCustomUrlTitle" xml:space="preserve">
|
||||
<value>配置無感驗證接口</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportLoginTitle" xml:space="preserve">
|
||||
<value>登录胡桃通行证</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportRegisterTitle" xml:space="preserve">
|
||||
<value>注册胡桃通行证</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportResetPasswordTitle" xml:space="preserve">
|
||||
<value>重置胡桃通行证密码</value>
|
||||
</data>
|
||||
<data name="ViewDialogHutaoPassportUnregisterTitle" xml:space="preserve">
|
||||
<value>注销胡桃通行证账号</value>
|
||||
</data>
|
||||
<data name="ViewDialogImportExportApp" xml:space="preserve">
|
||||
<value>匯出 App</value>
|
||||
</data>
|
||||
@@ -1361,9 +1271,6 @@
|
||||
<data name="ViewModelCultivationProjectInvalidName" xml:space="preserve">
|
||||
<value>不能新增名稱無效的計劃</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteConfigWebhookUrlComplete" xml:space="preserve">
|
||||
<value>实时便笺 Webhook Url 配置成功</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteHoyolabVerificationUnsupported" xml:space="preserve">
|
||||
<value>HoYoLAB 賬號不支持驗證實时便箋</value>
|
||||
</data>
|
||||
@@ -1688,18 +1595,6 @@
|
||||
<data name="ViewPageDailyNoteAddEntryToolTip" xml:space="preserve">
|
||||
<value>新增</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteAttendanceStatusInfo" xml:space="preserve">
|
||||
<value>历练点获取详情</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookDescription" xml:space="preserve">
|
||||
<value>在实时便笺刷新后推送到指定的 Webhook</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookHeader" xml:space="preserve">
|
||||
<value>配置 Webhook</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteDataInteropHeader" xml:space="preserve">
|
||||
<value>数据互操作</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteNotificationHeader" xml:space="preserve">
|
||||
<value>通知</value>
|
||||
</data>
|
||||
@@ -1940,9 +1835,6 @@
|
||||
<data name="ViewPageHutaoPassportResetPasswordHeader" xml:space="preserve">
|
||||
<value>重設密碼</value>
|
||||
</data>
|
||||
<data name="ViewPageHutaoPassportResetPasswordHint" xml:space="preserve">
|
||||
<value>注销账号的数据将永远丢失,无法恢复</value>
|
||||
</data>
|
||||
<data name="ViewPageHutaoPassportUserNameHint" xml:space="preserve">
|
||||
<value>請輸入電郵地址</value>
|
||||
</data>
|
||||
@@ -1991,21 +1883,12 @@
|
||||
<data name="ViewPageLaunchGameAppearanceScreenWidthHeader" xml:space="preserve">
|
||||
<value>寬度</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameArgumentsDescription" xml:space="preserve">
|
||||
<value>在游戏启动时修改其默认行为</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameArgumentsHeader" xml:space="preserve">
|
||||
<value>启动参数</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameCommonHeader" xml:space="preserve">
|
||||
<value>一般</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameConfigurationSaveHint" xml:space="preserve">
|
||||
<value>所有選項盡會在啓動游戲成功後保存</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameFileHeader" xml:space="preserve">
|
||||
<value>文件</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameMonitorsDescription" xml:space="preserve">
|
||||
<value>在指定的屏幕上運行</value>
|
||||
</data>
|
||||
@@ -2021,12 +1904,6 @@
|
||||
<data name="ViewPageLaunchGameOptionsHeader" xml:space="preserve">
|
||||
<value>遊戲選項</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameProcessHeader" xml:space="preserve">
|
||||
<value>进程</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameRegistryHeader" xml:space="preserve">
|
||||
<value>注册表</value>
|
||||
</data>
|
||||
<data name="ViewPageLaunchGameResourceDiffHeader" xml:space="preserve">
|
||||
<value>增量包</value>
|
||||
</data>
|
||||
@@ -2225,50 +2102,8 @@
|
||||
<data name="ViewpageSettingHomeHeader" xml:space="preserve">
|
||||
<value>主頁</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportDangerZoneDescription" xml:space="preserve">
|
||||
<value>三思而后行</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportDangerZoneHeader" xml:space="preserve">
|
||||
<value>危险操作</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportGachaLogExpiredAtHeader" xml:space="preserve">
|
||||
<value>胡桃云服务到期时间</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportHeader" xml:space="preserve">
|
||||
<value>胡桃通行证账号</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLicensedDeveloperDescription" xml:space="preserve">
|
||||
<value>您可以无限制使用任何基于胡桃云服务的功能</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLicensedDeveloperHeader" xml:space="preserve">
|
||||
<value>已认证的合作开发者</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLoginAction" xml:space="preserve">
|
||||
<value>登录</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportLogoutAction" xml:space="preserve">
|
||||
<value>退出登录</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportMaintainerDescription" xml:space="preserve">
|
||||
<value>您可以无限制的使用任何测试功能</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportMaintainerHeader" xml:space="preserve">
|
||||
<value>胡桃开发/运维</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRedeemCodeDescription" xml:space="preserve">
|
||||
<value>我们有时会向某些用户赠送胡桃云兑换码</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRedeemCodeHeader" xml:space="preserve">
|
||||
<value>使用兑换码</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportRegisterAction" xml:space="preserve">
|
||||
<value>注册</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportResetPasswordAction" xml:space="preserve">
|
||||
<value>修改密码</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingHutaoPassportUnregisterAction" xml:space="preserve">
|
||||
<value>注销账号</value>
|
||||
<value>Snap Hutao 賬號</value>
|
||||
</data>
|
||||
<data name="ViewPageSettingIsAdvancedLaunchOptionsEnabledDescription" xml:space="preserve">
|
||||
<value>在完整閱讀原神和胡桃工具箱使用者協定後,我選擇啟用「啟動遊戲 - 高級功能」</value>
|
||||
@@ -2585,27 +2420,6 @@
|
||||
<data name="WebAnnouncementTimeHoursEndFormat" xml:space="preserve">
|
||||
<value>{0} 小時後結束</value>
|
||||
</data>
|
||||
<data name="WebBridgeShareCopyToClipboardSuccess" xml:space="preserve">
|
||||
<value>已复制到剪贴板</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusFinishedNonReward" xml:space="preserve">
|
||||
<value>已完成</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusForbid" xml:space="preserve">
|
||||
<value>禁止领取</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusInvalid" xml:space="preserve">
|
||||
<value>无效</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusTakenAward" xml:space="preserve">
|
||||
<value>已领取</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusUnfinished" xml:space="preserve">
|
||||
<value>尚未完成</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteAttendanceRewardStatusWaitTaken" xml:space="preserve">
|
||||
<value>等待领取</value>
|
||||
</data>
|
||||
<data name="WebDailyNoteExpeditionRemainHoursFormat" xml:space="preserve">
|
||||
<value>{0} 時</value>
|
||||
</data>
|
||||
|
||||
@@ -153,7 +153,7 @@ internal abstract partial class DbStoreOptions : ObservableObject, IOptions<DbSt
|
||||
/// <param name="key">键</param>
|
||||
/// <param name="value">值</param>
|
||||
/// <param name="propertyName">属性名称</param>
|
||||
protected void SetOption(ref string? storage, string key, string? value, [CallerMemberName] string? propertyName = null)
|
||||
protected void SetOption(ref string? storage, string key, string value, [CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
if (!SetProperty(ref storage, value, propertyName))
|
||||
{
|
||||
|
||||
@@ -27,7 +27,6 @@ internal sealed partial class DailyNoteOptions : DbStoreOptions
|
||||
private NameValue<int>? selectedRefreshTime;
|
||||
private bool? isReminderNotification;
|
||||
private bool? isSilentWhenPlayingGame;
|
||||
private string? webhookUrl;
|
||||
|
||||
/// <summary>
|
||||
/// 刷新时间
|
||||
@@ -77,7 +76,7 @@ internal sealed partial class DailyNoteOptions : DbStoreOptions
|
||||
{
|
||||
if (runtimeOptions.IsElevated)
|
||||
{
|
||||
// leave untouched when we are running in elevated privilege
|
||||
// leave below untouched if we are running in elevated privilege
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -88,7 +87,7 @@ internal sealed partial class DailyNoteOptions : DbStoreOptions
|
||||
{
|
||||
if (runtimeOptions.IsElevated)
|
||||
{
|
||||
// leave untouched when we are running in elevated privilege
|
||||
// leave below untouched if we are running in elevated privilege
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -123,10 +122,4 @@ internal sealed partial class DailyNoteOptions : DbStoreOptions
|
||||
get => GetOption(ref isSilentWhenPlayingGame, SettingEntry.DailyNoteSilentWhenPlayingGame);
|
||||
set => SetOption(ref isSilentWhenPlayingGame, SettingEntry.DailyNoteSilentWhenPlayingGame, value);
|
||||
}
|
||||
|
||||
public string? WebhookUrl
|
||||
{
|
||||
get => GetOption(ref webhookUrl, SettingEntry.DailyNoteSilentWhenPlayingGame);
|
||||
set => SetOption(ref webhookUrl, SettingEntry.DailyNoteSilentWhenPlayingGame, value);
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,12 @@
|
||||
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Snap.Hutao.Core.DependencyInjection.Abstraction;
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Message;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.ViewModel.User;
|
||||
using Snap.Hutao.Web.Hoyolab;
|
||||
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord;
|
||||
using Snap.Hutao.Web.Request.Builder;
|
||||
using Snap.Hutao.Web.Request.Builder.Abstraction;
|
||||
using System.Collections.ObjectModel;
|
||||
using WebDailyNote = Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.DailyNote.DailyNote;
|
||||
|
||||
@@ -111,8 +108,6 @@ internal sealed partial class DailyNoteService : IDailyNoteService, IRecipient<U
|
||||
|
||||
private async ValueTask RefreshDailyNotesCoreAsync(bool forceRefresh)
|
||||
{
|
||||
DailyNoteWebhookOperation dailyNoteWebhookOperation = serviceProvider.GetRequiredService<DailyNoteWebhookOperation>();
|
||||
|
||||
foreach (DailyNoteEntry entry in await dailyNoteDbService.GetDailyNoteEntryIncludeUserListAsync().ConfigureAwait(false))
|
||||
{
|
||||
if (!forceRefresh && entry.DailyNote is not null)
|
||||
@@ -149,7 +144,6 @@ internal sealed partial class DailyNoteService : IDailyNoteService, IRecipient<U
|
||||
// database
|
||||
entry.UpdateDailyNote(dailyNote);
|
||||
await dailyNoteDbService.UpdateDailyNoteEntryAsync(entry).ConfigureAwait(false);
|
||||
await dailyNoteWebhookOperation.TryPostDailyNoteToWebhookAsync(dailyNote).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Web.Request.Builder;
|
||||
using Snap.Hutao.Web.Request.Builder.Abstraction;
|
||||
using System.Net.Http;
|
||||
using WebDailyNote = Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.DailyNote.DailyNote;
|
||||
|
||||
namespace Snap.Hutao.Service.DailyNote;
|
||||
|
||||
[ConstructorGenerated(ResolveHttpClient = true)]
|
||||
[HttpClient(HttpClientConfiguration.Default)]
|
||||
internal sealed partial class DailyNoteWebhookOperation
|
||||
{
|
||||
private readonly IHttpRequestMessageBuilderFactory httpRequestMessageBuilderFactory;
|
||||
private readonly ILogger<DailyNoteWebhookOperation> logger;
|
||||
private readonly DailyNoteOptions dailyNoteOptions;
|
||||
private readonly HttpClient httpClient;
|
||||
|
||||
public async ValueTask TryPostDailyNoteToWebhookAsync(WebDailyNote dailyNote, CancellationToken token = default)
|
||||
{
|
||||
string? targetUrl = dailyNoteOptions.WebhookUrl;
|
||||
if (string.IsNullOrEmpty(targetUrl) || !Uri.TryCreate(targetUrl, UriKind.Absolute, out Uri? targetUri))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(targetUri)
|
||||
.PostJson(dailyNote);
|
||||
|
||||
await builder.TryCatchSendAsync(httpClient, logger, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
using Snap.Hutao.Web.Hutao.GachaLog;
|
||||
using Snap.Hutao.Web.Response;
|
||||
|
||||
@@ -55,7 +54,7 @@ internal readonly struct TypedWishSummaryBuilderContext
|
||||
return new(taskContext, gachaLogClient, SH.ServiceGachaLogFactoryWeaponWishName, 80, 10, IsWeaponEventWish, GachaDistributionType.WeaponEvent);
|
||||
}
|
||||
|
||||
public ValueTask<HutaoResponse<GachaDistribution>> GetGachaDistributionAsync()
|
||||
public ValueTask<Response<GachaDistribution>> GetGachaDistributionAsync()
|
||||
{
|
||||
return GachaLogClient.GetGachaDistributionAsync(DistributionType);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ using Snap.Hutao.Service.GachaLog.Factory;
|
||||
using Snap.Hutao.Service.Metadata;
|
||||
using Snap.Hutao.ViewModel.GachaLog;
|
||||
using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
using Snap.Hutao.Web.Hutao.GachaLog;
|
||||
using Snap.Hutao.Web.Response;
|
||||
|
||||
@@ -28,7 +27,7 @@ internal sealed partial class GachaLogHutaoCloudService : IGachaLogHutaoCloudSer
|
||||
private readonly IGachaLogDbService gachaLogDbService;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ValueTask<HutaoResponse<List<GachaEntry>>> GetGachaEntriesAsync(CancellationToken token = default)
|
||||
public ValueTask<Response<List<GachaEntry>>> GetGachaEntriesAsync(CancellationToken token = default)
|
||||
{
|
||||
return homaGachaLogClient.GetGachaEntriesAsync(token);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.ViewModel.GachaLog;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
using Snap.Hutao.Web.Hutao.GachaLog;
|
||||
using Snap.Hutao.Web.Response;
|
||||
|
||||
@@ -29,7 +28,7 @@ internal interface IGachaLogHutaoCloudService
|
||||
/// <returns>祈愿统计信息</returns>
|
||||
ValueTask<ValueResult<bool, HutaoStatistics>> GetCurrentEventStatisticsAsync(CancellationToken token = default);
|
||||
|
||||
ValueTask<HutaoResponse<List<GachaEntry>>> GetGachaEntriesAsync(CancellationToken token = default);
|
||||
ValueTask<Response<List<GachaEntry>>> GetGachaEntriesAsync(CancellationToken token = default);
|
||||
|
||||
/// <summary>
|
||||
/// 异步获取祈愿记录
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
using Snap.Hutao.Core;
|
||||
using Snap.Hutao.Core.ExceptionService;
|
||||
using Snap.Hutao.Core.IO.Ini;
|
||||
using Snap.Hutao.Factory.Abstraction;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Service.Game.Locator;
|
||||
using Snap.Hutao.Service.Game.Package;
|
||||
@@ -26,7 +25,6 @@ namespace Snap.Hutao.Service.Game;
|
||||
[Injection(InjectAs.Singleton, typeof(IGameService))]
|
||||
internal sealed partial class GameService : IGameService
|
||||
{
|
||||
private readonly IContentDialogFactory contentDialogFactory;
|
||||
private readonly PackageConverter packageConverter;
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private readonly IGameDbService gameDbService;
|
||||
@@ -208,7 +206,10 @@ internal sealed partial class GameService : IGameService
|
||||
}
|
||||
}
|
||||
|
||||
await packageConverter.EnsureDeprecatedFilesAndSdkAsync(resource, gameFolder).ConfigureAwait(false);
|
||||
if (!launchScheme.IsOversea)
|
||||
{
|
||||
await packageConverter.EnsureDeprecatedFilesAndSdkAsync(resource, gameFolder).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -224,8 +225,8 @@ internal sealed partial class GameService : IGameService
|
||||
return false;
|
||||
}
|
||||
|
||||
return Process.GetProcessesByName(YuanShenProcessName).Any()
|
||||
|| Process.GetProcessesByName(GenshinImpactProcessName).Any();
|
||||
return Process.GetProcessesByName(YuanShenProcessName) is [_, ..]
|
||||
|| Process.GetProcessesByName(GenshinImpactProcessName) is [_, ..];
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -244,7 +245,6 @@ internal sealed partial class GameService : IGameService
|
||||
{
|
||||
try
|
||||
{
|
||||
Interlocked.Increment(ref runningGamesCounter);
|
||||
game.Start();
|
||||
progress.Report(new(LaunchPhase.ProcessStarted, SH.ServiceGameLaunchPhaseProcessStarted));
|
||||
|
||||
@@ -302,7 +302,7 @@ internal sealed partial class GameService : IGameService
|
||||
{
|
||||
// ContentDialog must be created by main thread.
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
LaunchGameAccountNameDialog dialog = await contentDialogFactory.CreateInstanceAsync<LaunchGameAccountNameDialog>().ConfigureAwait(false);
|
||||
LaunchGameAccountNameDialog dialog = serviceProvider.CreateInstance<LaunchGameAccountNameDialog>();
|
||||
(bool isOk, string name) = await dialog.GetInputNameAsync().ConfigureAwait(false);
|
||||
|
||||
if (isOk)
|
||||
|
||||
@@ -53,7 +53,13 @@ internal sealed class LaunchOptions : DbStoreOptions
|
||||
public bool IsFullScreen
|
||||
{
|
||||
get => GetOption(ref isFullScreen, SettingEntry.LaunchIsFullScreen);
|
||||
set => SetOption(ref isFullScreen, SettingEntry.LaunchIsFullScreen, value);
|
||||
set
|
||||
{
|
||||
if (SetOption(ref isFullScreen, SettingEntry.LaunchIsFullScreen, value) && value)
|
||||
{
|
||||
IsBorderless = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -62,7 +68,14 @@ internal sealed class LaunchOptions : DbStoreOptions
|
||||
public bool IsBorderless
|
||||
{
|
||||
get => GetOption(ref isBorderless, SettingEntry.LaunchIsBorderless);
|
||||
set => SetOption(ref isBorderless, SettingEntry.LaunchIsBorderless, value);
|
||||
set
|
||||
{
|
||||
if (SetOption(ref isBorderless, SettingEntry.LaunchIsBorderless, value) && value)
|
||||
{
|
||||
IsExclusive = false;
|
||||
IsFullScreen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -71,7 +84,13 @@ internal sealed class LaunchOptions : DbStoreOptions
|
||||
public bool IsExclusive
|
||||
{
|
||||
get => GetOption(ref isExclusive, SettingEntry.LaunchIsExclusive);
|
||||
set => SetOption(ref isExclusive, SettingEntry.LaunchIsExclusive, value);
|
||||
set
|
||||
{
|
||||
if (SetOption(ref isExclusive, SettingEntry.LaunchIsExclusive, value) && value)
|
||||
{
|
||||
IsFullScreen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -134,7 +153,7 @@ internal sealed class LaunchOptions : DbStoreOptions
|
||||
private static void InitializeMonitors(List<NameValue<int>> monitors)
|
||||
{
|
||||
// This list can't use foreach
|
||||
// https://github.com/microsoft/CsWinRT/issues/747
|
||||
// https://github.com/microsoft/microsoft-ui-xaml/issues/6454
|
||||
IReadOnlyList<DisplayArea> displayAreas = DisplayArea.FindAll();
|
||||
for (int i = 0; i < displayAreas.Count; i++)
|
||||
{
|
||||
@@ -146,15 +165,12 @@ internal sealed class LaunchOptions : DbStoreOptions
|
||||
|
||||
private static void InitializeScreenFps(out int fps)
|
||||
{
|
||||
HDC hDC = default;
|
||||
try
|
||||
HDC hDC = GetDC(HWND.Null);
|
||||
fps = GetDeviceCaps(hDC, GET_DEVICE_CAPS_INDEX.VREFRESH);
|
||||
if (ReleaseDC(HWND.Null, hDC) == 0)
|
||||
{
|
||||
hDC = GetDC(HWND.Null);
|
||||
fps = GetDeviceCaps(hDC, GET_DEVICE_CAPS_INDEX.VREFRESH);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_ = ReleaseDC(HWND.Null, hDC);
|
||||
// not released
|
||||
throw new Win32Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,15 +103,6 @@ internal sealed partial class LaunchScheme
|
||||
IsOversea = true,
|
||||
};
|
||||
|
||||
private static readonly LaunchScheme ServerGlobalChannelOfficialSubChannelOfficial = new()
|
||||
{
|
||||
LauncherId = SdkStaticLauncherGlobalId,
|
||||
Key = SdkStaticLauncherGlobalKey,
|
||||
Channel = ChannelType.Official,
|
||||
SubChannel = SubChannelType.Official,
|
||||
IsOversea = true,
|
||||
};
|
||||
|
||||
private static readonly LaunchScheme ServerGlobalChannelOfficialSubChannelEpic = new()
|
||||
{
|
||||
LauncherId = SdkStaticLauncherGlobalId,
|
||||
@@ -152,7 +143,6 @@ internal sealed partial class LaunchScheme
|
||||
// 国际服
|
||||
ServerGlobalChannelDefaultSubChannelDefaultCompatOnly,
|
||||
ServerGlobalChannelOfficialSubChannelDefault,
|
||||
ServerGlobalChannelOfficialSubChannelOfficial,
|
||||
ServerGlobalChannelOfficialSubChannelEpic,
|
||||
ServerGlobalChannelOfficialSubChannelGoogle,
|
||||
};
|
||||
|
||||
@@ -72,7 +72,10 @@ internal sealed class GameFpsUnlocker : IGameFpsUnlocker
|
||||
{
|
||||
ulong temp = 0;
|
||||
bool result = ReadProcessMemory((HANDLE)process.Handle, (void*)baseAddress, (byte*)&temp, 8);
|
||||
Verify.Operation(result, SH.ServiceGameUnlockerReadProcessMemoryPointerAddressFailed);
|
||||
if (!result)
|
||||
{
|
||||
ThrowHelper.InvalidOperation(SH.ServiceGameUnlockerReadProcessMemoryPointerAddressFailed, null);
|
||||
}
|
||||
|
||||
value = (nuint)temp;
|
||||
return result;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
using Snap.Hutao.Web.Hutao.SpiralAbyss;
|
||||
using Snap.Hutao.Web.Response;
|
||||
|
||||
@@ -65,7 +64,7 @@ internal sealed partial class HutaoSpiralAbyssService : IHutaoSpiralAbyssService
|
||||
return FromCacheOrWebAsync(nameof(TeamAppearance), homaClient.GetTeamCombinationsAsync);
|
||||
}
|
||||
|
||||
private async ValueTask<T> FromCacheOrWebAsync<T>(string typeName, Func<CancellationToken, ValueTask<HutaoResponse<T>>> taskFunc)
|
||||
private async ValueTask<T> FromCacheOrWebAsync<T>(string typeName, Func<CancellationToken, ValueTask<Response<T>>> taskFunc)
|
||||
where T : class, new()
|
||||
{
|
||||
string key = $"{nameof(HutaoSpiralAbyssService)}.Cache.{typeName}";
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -22,7 +21,6 @@ internal sealed class HutaoUserOptions : ObservableObject, IOptions<HutaoUserOpt
|
||||
private bool isHutaoCloudServiceAllowed;
|
||||
private bool isLicensedDeveloper;
|
||||
private string? gachaLogExpireAt;
|
||||
private string? gachaLogExpireAtSlim;
|
||||
private bool isMaintainer;
|
||||
|
||||
/// <summary>
|
||||
@@ -57,37 +55,20 @@ internal sealed class HutaoUserOptions : ObservableObject, IOptions<HutaoUserOpt
|
||||
/// </summary>
|
||||
public string? GachaLogExpireAt { get => gachaLogExpireAt; set => SetProperty(ref gachaLogExpireAt, value); }
|
||||
|
||||
public string? GachaLogExpireAtSlim { get => gachaLogExpireAtSlim; set => SetProperty(ref gachaLogExpireAtSlim, value); }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public HutaoUserOptions Value { get => this; }
|
||||
|
||||
public async ValueTask<bool> PostLoginSucceedAsync(HomaPassportClient passportClient, ITaskContext taskContext, string username, string? token)
|
||||
/// <summary>
|
||||
/// 登录
|
||||
/// </summary>
|
||||
/// <param name="userName">用户名</param>
|
||||
/// <param name="token">令牌</param>
|
||||
public void LoginSucceed(string userName, string? token)
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
UserName = username;
|
||||
UserName = userName;
|
||||
this.token = token;
|
||||
IsLoggedIn = true;
|
||||
initializedTaskCompletionSource.TrySetResult();
|
||||
|
||||
await taskContext.SwitchToBackgroundAsync();
|
||||
Web.Response.Response<UserInfo> userInfoResponse = await passportClient.GetUserInfoAsync(default).ConfigureAwait(false);
|
||||
if (userInfoResponse.IsOk())
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
UpdateUserInfo(userInfoResponse.Data);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void LogoutOrUnregister()
|
||||
{
|
||||
UserName = null;
|
||||
token = null;
|
||||
IsLoggedIn = false;
|
||||
ClearUserInfo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -113,7 +94,6 @@ internal sealed class HutaoUserOptions : ObservableObject, IOptions<HutaoUserOpt
|
||||
IsLicensedDeveloper = userInfo.IsLicensedDeveloper;
|
||||
IsMaintainer = userInfo.IsMaintainer;
|
||||
GachaLogExpireAt = Regex.Unescape(SH.ServiceHutaoUserGachaLogExpiredAt).Format(userInfo.GachaLogExpireAt);
|
||||
GachaLogExpireAtSlim = $"{userInfo.GachaLogExpireAt:yyyy.MM.dd HH:mm:ss}";
|
||||
IsCloudServiceAllowed = IsLicensedDeveloper || userInfo.GachaLogExpireAt > DateTimeOffset.Now;
|
||||
}
|
||||
|
||||
@@ -122,13 +102,4 @@ internal sealed class HutaoUserOptions : ObservableObject, IOptions<HutaoUserOpt
|
||||
await initializedTaskCompletionSource.Task.ConfigureAwait(false);
|
||||
return token;
|
||||
}
|
||||
|
||||
private void ClearUserInfo()
|
||||
{
|
||||
IsLicensedDeveloper = false;
|
||||
IsMaintainer = false;
|
||||
GachaLogExpireAt = null;
|
||||
GachaLogExpireAtSlim = null;
|
||||
IsCloudServiceAllowed = false;
|
||||
}
|
||||
}
|
||||
@@ -44,8 +44,15 @@ internal sealed partial class HutaoUserService : IHutaoUserService, IHutaoUserSe
|
||||
|
||||
if (response.IsOk())
|
||||
{
|
||||
if (await options.PostLoginSucceedAsync(passportClient, taskContext, userName, response.Data).ConfigureAwait(false))
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
options.LoginSucceed(userName, response.Data);
|
||||
|
||||
await taskContext.SwitchToBackgroundAsync();
|
||||
Web.Response.Response<UserInfo> userInfoResponse = await passportClient.GetUserInfoAsync(token).ConfigureAwait(false);
|
||||
if (userInfoResponse.IsOk())
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
options.UpdateUserInfo(userInfoResponse.Data);
|
||||
isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ internal sealed partial class DocumentationProvider : IDocumentationProvider
|
||||
[typeof(CultivationPage)] = "https://hut.ao/features/develop-plan.html",
|
||||
[typeof(DailyNotePage)] = "https://hut.ao/features/real-time-notes.html",
|
||||
[typeof(GachaLogPage)] = "https://hut.ao/features/wish-export.html",
|
||||
[typeof(HutaoPassportPage)] = "https://hut.ao/zh/features/hutao-settings.html#%E8%83%A1%E6%A1%83%E5%B8%90%E5%8F%B7",
|
||||
[typeof(LaunchGamePage)] = "https://hut.ao/features/game-launcher.html",
|
||||
[typeof(LoginHoyoverseUserPage)] = "https://hut.ao/features/mhy-account-switch.html",
|
||||
[typeof(LoginMihoyoUserPage)] = "https://hut.ao/features/mhy-account-switch.html",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
@@ -100,7 +100,6 @@
|
||||
<None Remove="Resource\Icon\UI_AchievementIcon_3_3.png" />
|
||||
<None Remove="Resource\Icon\UI_GachaShowPanel_Bg_Weapon.png" />
|
||||
<None Remove="Resource\Icon\UI_Icon_Fetter.png" />
|
||||
<None Remove="Resource\Icon\UI_Icon_Gift.png" />
|
||||
<None Remove="Resource\Icon\UI_Icon_Locked.png" />
|
||||
<None Remove="Resource\Icon\UI_Icon_Tower_Star.png" />
|
||||
<None Remove="Resource\Icon\UI_ItemIcon_201.png" />
|
||||
@@ -145,15 +144,10 @@
|
||||
<None Remove="View\Dialog\CultivatePromotionDeltaBatchDialog.xaml" />
|
||||
<None Remove="View\Dialog\CultivatePromotionDeltaDialog.xaml" />
|
||||
<None Remove="View\Dialog\DailyNoteNotificationDialog.xaml" />
|
||||
<None Remove="View\Dialog\DailyNoteWebhookDialog.xaml" />
|
||||
<None Remove="View\Dialog\GachaLogImportDialog.xaml" />
|
||||
<None Remove="View\Dialog\GachaLogRefreshProgressDialog.xaml" />
|
||||
<None Remove="View\Dialog\GachaLogUrlDialog.xaml" />
|
||||
<None Remove="View\Dialog\GeetestCustomUrlDialog.xaml" />
|
||||
<None Remove="View\Dialog\HutaoPassportLoginDialog.xaml" />
|
||||
<None Remove="View\Dialog\HutaoPassportRegisterDialog.xaml" />
|
||||
<None Remove="View\Dialog\HutaoPassportResetPasswordDialog.xaml" />
|
||||
<None Remove="View\Dialog\HutaoPassportUnregisterDialog.xaml" />
|
||||
<None Remove="View\Dialog\LaunchGameAccountNameDialog.xaml" />
|
||||
<None Remove="View\Dialog\LaunchGamePackageConvertDialog.xaml" />
|
||||
<None Remove="View\Dialog\UserDialog.xaml" />
|
||||
@@ -167,6 +161,7 @@
|
||||
<None Remove="View\Page\CultivationPage.xaml" />
|
||||
<None Remove="View\Page\DailyNotePage.xaml" />
|
||||
<None Remove="View\Page\GachaLogPage.xaml" />
|
||||
<None Remove="View\Page\HutaoPassportPage.xaml" />
|
||||
<None Remove="View\Page\LaunchGamePage.xaml" />
|
||||
<None Remove="View\Page\LoginMihoyoUserPage.xaml" />
|
||||
<None Remove="View\Page\SettingPage.xaml" />
|
||||
@@ -231,7 +226,6 @@
|
||||
<Content Include="Resource\Icon\UI_AchievementIcon_3_3.png" />
|
||||
<Content Include="Resource\Icon\UI_GachaShowPanel_Bg_Weapon.png" />
|
||||
<Content Include="Resource\Icon\UI_Icon_Fetter.png" />
|
||||
<Content Include="Resource\Icon\UI_Icon_Gift.png" />
|
||||
<Content Include="Resource\Icon\UI_Icon_Locked.png" />
|
||||
<Content Include="Resource\Icon\UI_Icon_Tower_Star.png" />
|
||||
<Content Include="Resource\Icon\UI_ItemIcon_201.png" />
|
||||
@@ -259,7 +253,7 @@
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.Shimmer" Version="0.1.230830" />
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.TokenView" Version="0.1.230830" />
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.TransitionHelper" Version="0.1.230830" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2-build.2" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.0.230907" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Collections" Version="8.0.230907" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.HeaderedControls" Version="8.0.230907" />
|
||||
@@ -268,8 +262,8 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.0.230907" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.0.230907" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.13" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.13">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.12" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.12">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
@@ -302,39 +296,20 @@
|
||||
<ItemGroup>
|
||||
<None Include="..\.editorconfig" Link=".editorconfig" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="Resource\Localization\SH.resx" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Dialog\HutaoPassportUnregisterDialog.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Dialog\HutaoPassportResetPasswordDialog.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Dialog\HutaoPassportRegisterDialog.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Dialog\HutaoPassportLoginDialog.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Compile Update="Resource\Localization\SH.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>SH.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Dialog\DailyNoteWebhookDialog.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<EmbeddedResource Update="Resource\Localization\SH.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>SH.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -516,6 +491,12 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\HutaoPassportPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Pages -->
|
||||
<ItemGroup>
|
||||
|
||||
@@ -51,7 +51,6 @@ internal sealed partial class AnnouncementContentViewer : UserControl
|
||||
/// </summary>
|
||||
public AnnouncementContentViewer()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("WEBVIEW2_DEFAULT_BACKGROUND_COLOR", "00000000");
|
||||
InitializeComponent();
|
||||
|
||||
loadEventHandler = OnLoaded;
|
||||
|
||||
@@ -195,23 +195,7 @@
|
||||
Value="{Binding LastPurplePull}"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
<Grid Margin="-12,-2" ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<MenuFlyoutSeparator Grid.Column="0"/>
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Opacity="0.6"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding TimeSpanFormatted}"/>
|
||||
<MenuFlyoutSeparator Grid.Column="2"/>
|
||||
</Grid>
|
||||
|
||||
<MenuFlyoutSeparator Margin="-12,0"/>
|
||||
<shvcont:StatisticsSegmented
|
||||
x:Name="StatisticsSegmented"
|
||||
Margin="0,12,0,0"
|
||||
@@ -225,20 +209,15 @@
|
||||
<cwcont:Case Value="{shcm:Int32 Value=0}">
|
||||
<StackPanel Spacing="2">
|
||||
<Grid>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeAveragePullText}"/>
|
||||
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeAveragePullText}"/>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Right"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{Binding AverageOrangePullFormatted}"/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<!-- 高度占位符 -->
|
||||
<TextBlock/>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{shcm:ResourceString Name=ViewControlStatisticsCardUpAveragePullText}"
|
||||
Visibility="{x:Bind ShowUpPull, Converter={StaticResource BoolToVisibilityConverter}}"/>
|
||||
@@ -258,14 +237,12 @@
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{Binding MinOrangePullFormatted}"/>
|
||||
</Grid>
|
||||
<Grid/>
|
||||
</StackPanel>
|
||||
</cwcont:Case>
|
||||
<cwcont:Case Value="{shcm:Int32 Value=1}">
|
||||
<StackPanel Spacing="2">
|
||||
<Grid>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
Foreground="{StaticResource OrangeColorBrush}"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeText}"/>
|
||||
@@ -278,7 +255,6 @@
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
Foreground="{StaticResource PurpleColorBrush}"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{shcm:ResourceString Name=ViewControlStatisticsCardPurpleText}"/>
|
||||
@@ -291,7 +267,6 @@
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
Foreground="{StaticResource BlueColorBrush}"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{shcm:ResourceString Name=ViewControlStatisticsCardBlueText}"/>
|
||||
|
||||
@@ -27,7 +27,6 @@ internal partial class WebViewer : UserControl, IRecipient<UserChangedMessage>
|
||||
|
||||
public WebViewer()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("WEBVIEW2_DEFAULT_BACKGROUND_COLOR", "00000000");
|
||||
InitializeComponent();
|
||||
serviceProvider = Ioc.Default;
|
||||
infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
|
||||
|
||||
@@ -21,6 +21,7 @@ internal sealed partial class AchievementArchiveCreateDialog : ContentDialog
|
||||
public AchievementArchiveCreateDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ internal sealed partial class AchievementImportDialog : ContentDialog
|
||||
public AchievementImportDialog(IServiceProvider serviceProvider, UIAF uiaf)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
UIAF = uiaf;
|
||||
|
||||
@@ -24,6 +24,7 @@ internal sealed partial class CultivateProjectDialog : ContentDialog
|
||||
public CultivateProjectDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ internal sealed partial class CultivatePromotionDeltaBatchDialog : ContentDialog
|
||||
public CultivatePromotionDeltaBatchDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ internal sealed partial class CultivatePromotionDeltaDialog : ContentDialog
|
||||
public CultivatePromotionDeltaDialog(IServiceProvider serviceProvider, CalculableOptions options)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ internal sealed partial class DailyNoteNotificationDialog : ContentDialog
|
||||
public DailyNoteNotificationDialog(IServiceProvider serviceProvider, DailyNoteEntry entry)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
|
||||
DataContext = entry;
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<ContentDialog
|
||||
x:Class="Snap.Hutao.View.Dialog.DailyNoteWebhookDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
Title="{shcm:ResourceString Name=ViewDialogDailyNoteWebhookUrlTitle}"
|
||||
CloseButtonText="{shcm:ResourceString Name=ContentDialogCancelCloseButtonText}"
|
||||
DefaultButton="Primary"
|
||||
PrimaryButtonText="{shcm:ResourceString Name=ContentDialogConfirmPrimaryButtonText}"
|
||||
Style="{StaticResource DefaultContentDialogStyle}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewDialogDailyNoteWebhookUrlInputPlaceholder}" Text="{x:Bind Text, Mode=TwoWay}"/>
|
||||
</Grid>
|
||||
</ContentDialog>
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Snap.Hutao.View.Dialog;
|
||||
|
||||
[DependencyProperty("Text", typeof(string))]
|
||||
internal sealed partial class DailyNoteWebhookDialog : ContentDialog
|
||||
{
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
public DailyNoteWebhookDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取输入的Url
|
||||
/// </summary>
|
||||
/// <returns>输入的结果</returns>
|
||||
public async ValueTask<ValueResult<bool, string>> GetInputUrlAsync()
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
ContentDialogResult result = await ShowAsync();
|
||||
|
||||
return new(result == ContentDialogResult.Primary, Text);
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ internal sealed partial class GachaLogImportDialog : ContentDialog
|
||||
public GachaLogImportDialog(IServiceProvider serviceProvider, UIGF uigf)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
UIGF = uigf;
|
||||
|
||||
@@ -21,6 +21,7 @@ internal sealed partial class GachaLogRefreshProgressDialog : ContentDialog
|
||||
public GachaLogRefreshProgressDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewDialogGachaLogUrlInputPlaceholder}" Text="{x:Bind Text, Mode=TwoWay}"/>
|
||||
<TextBox x:Name="InputText" PlaceholderText="{shcm:ResourceString Name=ViewDialogGachaLogUrlInputPlaceholder}"/>
|
||||
</Grid>
|
||||
</ContentDialog>
|
||||
|
||||
@@ -9,7 +9,6 @@ namespace Snap.Hutao.View.Dialog;
|
||||
/// 祈愿记录Url对话框
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[DependencyProperty("Text", typeof(string))]
|
||||
internal sealed partial class GachaLogUrlDialog : ContentDialog
|
||||
{
|
||||
private readonly ITaskContext taskContext;
|
||||
@@ -21,6 +20,7 @@ internal sealed partial class GachaLogUrlDialog : ContentDialog
|
||||
public GachaLogUrlDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
}
|
||||
@@ -33,8 +33,8 @@ internal sealed partial class GachaLogUrlDialog : ContentDialog
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
ContentDialogResult result = await ShowAsync();
|
||||
string url = Text.TrimEnd("#/log");
|
||||
string url = InputText.Text.TrimEnd("#/log");
|
||||
|
||||
return new(result == ContentDialogResult.Primary, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ internal sealed partial class GeetestCustomUrlDialog : ContentDialog
|
||||
public GeetestCustomUrlDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
Text = serviceProvider.GetRequiredService<AppOptions>().GeetestCustomCompositeUrl;
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<ContentDialog
|
||||
x:Class="Snap.Hutao.View.Dialog.HutaoPassportLoginDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
Title="{shcm:ResourceString Name=ViewDialogHutaoPassportLoginTitle}"
|
||||
CloseButtonText="{shcm:ResourceString Name=ContentDialogCancelCloseButtonText}"
|
||||
DefaultButton="Primary"
|
||||
PrimaryButtonText="{shcm:ResourceString Name=ContentDialogConfirmPrimaryButtonText}"
|
||||
Style="{StaticResource DefaultContentDialogStyle}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<StackPanel Margin="0,8,0,0">
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportUserNameHint}" Text="{x:Bind UserName, Mode=TwoWay}"/>
|
||||
<PasswordBox
|
||||
Margin="0,16,0,0"
|
||||
Password="{x:Bind Password, Mode=TwoWay}"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordHint}"/>
|
||||
</StackPanel>
|
||||
</ContentDialog>
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Snap.Hutao.View.Dialog;
|
||||
|
||||
[DependencyProperty("UserName", typeof(string))]
|
||||
[DependencyProperty("Password", typeof(string))]
|
||||
internal sealed partial class HutaoPassportLoginDialog : ContentDialog
|
||||
{
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
public HutaoPassportLoginDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
}
|
||||
|
||||
public async ValueTask<ValueResult<bool, (string UserName, string Passport)>> GetInputAsync()
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
ContentDialogResult result = await ShowAsync();
|
||||
|
||||
return new(result is ContentDialogResult.Primary, (UserName, Password));
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
<ContentDialog
|
||||
x:Class="Snap.Hutao.View.Dialog.HutaoPassportRegisterDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
Title="{shcm:ResourceString Name=ViewDialogHutaoPassportRegisterTitle}"
|
||||
CloseButtonText="{shcm:ResourceString Name=ContentDialogCancelCloseButtonText}"
|
||||
DefaultButton="Primary"
|
||||
PrimaryButtonText="{shcm:ResourceString Name=ContentDialogConfirmPrimaryButtonText}"
|
||||
Style="{StaticResource DefaultContentDialogStyle}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<StackPanel Margin="0,8,0,0">
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportUserNameHint}" Text="{x:Bind UserName, Mode=TwoWay}"/>
|
||||
<Grid Margin="0,16,0,0" ColumnSpacing="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportVerifyCodeHint}" Text="{x:Bind VerifyCode, Mode=TwoWay}"/>
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Stretch"
|
||||
Command="{x:Bind VerifyCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageHutaoPassportVerifyCodeAction}"/>
|
||||
</Grid>
|
||||
<PasswordBox
|
||||
Margin="0,16,0,0"
|
||||
IsEnabled="{x:Bind VerifyCode, Converter={StaticResource StringBoolConverter}}"
|
||||
Password="{x:Bind Password, Mode=TwoWay}"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordHint}"/>
|
||||
<TextBlock
|
||||
Margin="0,4,0,0"
|
||||
Opacity="0.7"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordRequirementHint}"/>
|
||||
</StackPanel>
|
||||
</ContentDialog>
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Common;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
|
||||
namespace Snap.Hutao.View.Dialog;
|
||||
|
||||
[DependencyProperty("UserName", typeof(string))]
|
||||
[DependencyProperty("Password", typeof(string))]
|
||||
[DependencyProperty("VerifyCode", typeof(string))]
|
||||
internal sealed partial class HutaoPassportRegisterDialog : ContentDialog
|
||||
{
|
||||
private readonly HomaPassportClient homaPassportClient;
|
||||
private readonly IInfoBarService infoBarService;
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
public HutaoPassportRegisterDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
homaPassportClient = serviceProvider.GetRequiredService<HomaPassportClient>();
|
||||
infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
|
||||
}
|
||||
|
||||
public async ValueTask<ValueResult<bool, (string UserName, string Password, string VerifyCode)>> GetInputAsync()
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
ContentDialogResult result = await ShowAsync();
|
||||
|
||||
return new(result is ContentDialogResult.Primary, (UserName, Password, VerifyCode));
|
||||
}
|
||||
|
||||
[Command("VerifyCommand")]
|
||||
private async Task VerifyAsync()
|
||||
{
|
||||
if (string.IsNullOrEmpty(UserName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UserName.IsEmail())
|
||||
{
|
||||
infoBarService.Warning(SH.ViewModelHutaoPassportEmailNotValidHint);
|
||||
return;
|
||||
}
|
||||
|
||||
HutaoResponse response = await homaPassportClient.VerifyAsync(UserName, false).ConfigureAwait(false);
|
||||
infoBarService.Information(response.GetLocalizationMessage());
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
<ContentDialog
|
||||
x:Class="Snap.Hutao.View.Dialog.HutaoPassportResetPasswordDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
Title="{shcm:ResourceString Name=ViewDialogHutaoPassportResetPasswordTitle}"
|
||||
CloseButtonText="{shcm:ResourceString Name=ContentDialogCancelCloseButtonText}"
|
||||
DefaultButton="Primary"
|
||||
PrimaryButtonText="{shcm:ResourceString Name=ContentDialogConfirmPrimaryButtonText}"
|
||||
Style="{StaticResource DefaultContentDialogStyle}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<StackPanel>
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportUserNameHint}" Text="{x:Bind UserName, Mode=TwoWay}"/>
|
||||
<Grid Margin="0,16,0,0" ColumnSpacing="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportVerifyCodeHint}" Text="{x:Bind VerifyCode, Mode=TwoWay}"/>
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Stretch"
|
||||
Command="{x:Bind VerifyCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageHutaoPassportVerifyCodeAction}"/>
|
||||
</Grid>
|
||||
<PasswordBox
|
||||
Margin="0,16,0,0"
|
||||
IsEnabled="{x:Bind VerifyCode, Converter={StaticResource StringBoolConverter}}"
|
||||
Password="{x:Bind Password, Mode=TwoWay}"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordHint}"/>
|
||||
<TextBlock
|
||||
Margin="0,4,0,0"
|
||||
Opacity="0.7"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordRequirementHint}"/>
|
||||
</StackPanel>
|
||||
</ContentDialog>
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Common;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
|
||||
namespace Snap.Hutao.View.Dialog;
|
||||
|
||||
[DependencyProperty("UserName", typeof(string))]
|
||||
[DependencyProperty("Password", typeof(string))]
|
||||
[DependencyProperty("VerifyCode", typeof(string))]
|
||||
internal sealed partial class HutaoPassportResetPasswordDialog : ContentDialog
|
||||
{
|
||||
private readonly HomaPassportClient homaPassportClient;
|
||||
private readonly IInfoBarService infoBarService;
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
public HutaoPassportResetPasswordDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
homaPassportClient = serviceProvider.GetRequiredService<HomaPassportClient>();
|
||||
infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
|
||||
}
|
||||
|
||||
public async ValueTask<ValueResult<bool, (string UserName, string Passport, string VerifyCode)>> GetInputAsync()
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
ContentDialogResult result = await ShowAsync();
|
||||
|
||||
return new(result is ContentDialogResult.Primary, (UserName, Password, VerifyCode));
|
||||
}
|
||||
|
||||
[Command("VerifyCommand")]
|
||||
private async Task VerifyAsync()
|
||||
{
|
||||
if (string.IsNullOrEmpty(UserName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UserName.IsEmail())
|
||||
{
|
||||
infoBarService.Warning(SH.ViewModelHutaoPassportEmailNotValidHint);
|
||||
return;
|
||||
}
|
||||
|
||||
HutaoResponse response = await homaPassportClient.VerifyAsync(UserName, false).ConfigureAwait(false);
|
||||
infoBarService.Information(response.GetLocalizationMessage());
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
<ContentDialog
|
||||
x:Class="Snap.Hutao.View.Dialog.HutaoPassportUnregisterDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
Title="{shcm:ResourceString Name=ViewDialogHutaoPassportUnregisterTitle}"
|
||||
CloseButtonText="{shcm:ResourceString Name=ContentDialogCancelCloseButtonText}"
|
||||
DefaultButton="Primary"
|
||||
PrimaryButtonText="{shcm:ResourceString Name=ContentDialogConfirmPrimaryButtonText}"
|
||||
Style="{StaticResource DefaultContentDialogStyle}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<StackPanel Margin="0,8,0,0">
|
||||
<InfoBar
|
||||
Title="{shcm:ResourceString Name=ViewPageHutaoPassportResetPasswordHint}"
|
||||
IsClosable="False"
|
||||
IsOpen="True"
|
||||
Severity="Error"/>
|
||||
<TextBox
|
||||
Margin="0,16,0,0"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportUserNameHint}"
|
||||
Text="{x:Bind UserName, Mode=TwoWay}"/>
|
||||
<PasswordBox
|
||||
Margin="0,16,0,0"
|
||||
Password="{x:Bind Password, Mode=TwoWay}"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordHint}"/>
|
||||
</StackPanel>
|
||||
</ContentDialog>
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Snap.Hutao.View.Dialog;
|
||||
|
||||
[DependencyProperty("UserName", typeof(string))]
|
||||
[DependencyProperty("Password", typeof(string))]
|
||||
internal sealed partial class HutaoPassportUnregisterDialog : ContentDialog
|
||||
{
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
public HutaoPassportUnregisterDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
}
|
||||
|
||||
public async ValueTask<ValueResult<bool, (string UserName, string Passport)>> GetInputAsync()
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
ContentDialogResult result = await ShowAsync();
|
||||
|
||||
return new(result is ContentDialogResult.Primary, (UserName, Password));
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ internal sealed partial class LaunchGameAccountNameDialog : ContentDialog
|
||||
public LaunchGameAccountNameDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ internal sealed partial class LaunchGamePackageConvertDialog : ContentDialog
|
||||
public LaunchGamePackageConvertDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ internal sealed partial class UserDialog : ContentDialog
|
||||
public UserDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<!-- Image Layer -->
|
||||
<Border cw:UIElementExtensions.ClipToBounds="True" CornerRadius="{ThemeResource ControlCornerRadiusTop}">
|
||||
<Border cw:UIElementExtensions.ClipToBounds="True" CornerRadius="{ThemeResource ControlCornerRadius}">
|
||||
<Border VerticalAlignment="Top" cw:VisualExtensions.NormalizedCenterPoint="0.5">
|
||||
<cww:ConstrainedBox AspectRatio="1080:390" CornerRadius="{ThemeResource ControlCornerRadiusTop}">
|
||||
<cww:ConstrainedBox AspectRatio="1080:390" CornerRadius="{ThemeResource ControlCornerRadius}">
|
||||
<shci:CachedImage Source="{Binding Banner}" Stretch="UniformToFill"/>
|
||||
</cww:ConstrainedBox>
|
||||
<cwa:Explicit.Animations>
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
xmlns:shci="using:Snap.Hutao.Control.Image"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
xmlns:shvc="using:Snap.Hutao.View.Control"
|
||||
xmlns:shvcp="using:Snap.Hutao.View.Card.Primitive"
|
||||
xmlns:shvd="using:Snap.Hutao.ViewModel.DailyNote"
|
||||
d:DataContext="{d:DesignInstance shvd:DailyNoteViewModel}"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
@@ -160,6 +159,7 @@
|
||||
</StackPanel>
|
||||
</cwc:HeaderedContentControl>
|
||||
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageDailyNoteNotificationHeader}"/>
|
||||
<cwc:SettingsCard
|
||||
Description="{shcm:ResourceString Name=ViewPageDailyNoteSlientModeDescription}"
|
||||
@@ -173,14 +173,6 @@
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}">
|
||||
<ToggleSwitch Margin="24,0,0,0" IsOn="{Binding Options.IsReminderNotification, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageDailyNoteDataInteropHeader}"/>
|
||||
<cwc:SettingsCard
|
||||
Command="{Binding ConfigDailyNoteWebhookUrlCommand}"
|
||||
Description="{shcm:ResourceString Name=ViewPageDailyNoteConfigWebhookDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageDailyNoteConfigWebhookHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}"
|
||||
IsClickEnabled="True"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</SplitView.Pane>
|
||||
@@ -370,10 +362,9 @@
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ProgressBar
|
||||
Grid.ColumnSpan="3"
|
||||
Grid.ColumnSpan="2"
|
||||
Height="40"
|
||||
MinHeight="48"
|
||||
Background="{x:Null}"
|
||||
@@ -403,40 +394,6 @@
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="NoWrap"/>
|
||||
</StackPanel>
|
||||
<Button
|
||||
Grid.Column="2"
|
||||
Width="32"
|
||||
Height="32"
|
||||
Margin="0,0,8,0"
|
||||
Padding="6"
|
||||
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageDailyNoteAttendanceStatusInfo}"
|
||||
Visibility="{Binding DailyNote.DailyTask.AttendanceVisible, Mode=OneWay}">
|
||||
<BitmapIcon ShowAsMonochrome="True" UriSource="ms-appx:///Resource/Icon/UI_Icon_Gift.png"/>
|
||||
<Button.Flyout>
|
||||
<Flyout Placement="BottomEdgeAlignedRight">
|
||||
<Flyout.FlyoutPresenterStyle>
|
||||
<Style BasedOn="{StaticResource DefaultFlyoutPresenterStyle}" TargetType="FlyoutPresenter">
|
||||
<Setter Property="Padding" Value="6"/>
|
||||
</Style>
|
||||
</Flyout.FlyoutPresenterStyle>
|
||||
<ItemsControl Margin="0,-3,0,0" ItemsSource="{Binding DailyNote.DailyTask.AttendanceRewards}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<shvcp:CardProgressBar
|
||||
MinWidth="120"
|
||||
MinHeight="32"
|
||||
Margin="0,3,0,0"
|
||||
Description="{Binding Progress}"
|
||||
Header="{Binding StatusFormatted}"
|
||||
Maximum="2000"
|
||||
ProgressForeground="{ThemeResource HyperlinkButtonForeground}"
|
||||
Value="{Binding Progress}"/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid Style="{ThemeResource GridCardStyle}">
|
||||
<Grid.ColumnDefinitions>
|
||||
|
||||
@@ -315,11 +315,25 @@
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<TextBlock
|
||||
<StackPanel
|
||||
Grid.Row="2"
|
||||
Margin="0,6,0,8"
|
||||
Opacity="0.6"
|
||||
Text="{Binding TimeSpanFormatted}"/>
|
||||
Orientation="Horizontal">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{Binding FromFormatted}"/>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text=" - "/>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{Binding ToFormatted}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
|
||||
115
src/Snap.Hutao/Snap.Hutao/View/Page/HutaoPassportPage.xaml
Normal file
115
src/Snap.Hutao/Snap.Hutao/View/Page/HutaoPassportPage.xaml
Normal file
@@ -0,0 +1,115 @@
|
||||
<shc:ScopedPage
|
||||
x:Class="Snap.Hutao.View.Page.HutaoPassportPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:shc="using:Snap.Hutao.Control"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
xmlns:shv="using:Snap.Hutao.ViewModel"
|
||||
d:DataContext="{d:DesignInstance shv:HutaoPassportViewModel}"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextBlock
|
||||
Style="{StaticResource SubtitleTextBlockStyle}"
|
||||
Text="{shcm:ResourceString Name=ViewPageSettingHutaoPassportHeader}"
|
||||
TextAlignment="Center"/>
|
||||
<Border
|
||||
Margin="0,16,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource BorderCardStyle}">
|
||||
<Pivot
|
||||
Width="360"
|
||||
Background="{StaticResource CardBackgroundFillColorDefaultBrush}"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}">
|
||||
<PivotItem Header="{shcm:ResourceString Name=ViewPageHutaoPassportLoginHeader}">
|
||||
<StackPanel Margin="16">
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportUserNameHint}" Text="{Binding UserName, Mode=TwoWay}"/>
|
||||
<PasswordBox
|
||||
Margin="0,16,0,0"
|
||||
Password="{Binding Password, Mode=TwoWay}"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordHint}"/>
|
||||
<Button
|
||||
Margin="0,16,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
Command="{Binding LoginCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageHutaoPassportLoginHeader}"
|
||||
Style="{ThemeResource AccentButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</PivotItem>
|
||||
<PivotItem Header="{shcm:ResourceString Name=ViewPageHutaoPassportRegisterHeader}">
|
||||
<StackPanel Margin="16">
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportUserNameHint}" Text="{Binding UserName, Mode=TwoWay}"/>
|
||||
<Grid Margin="0,16,0,0" ColumnSpacing="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportVerifyCodeHint}" Text="{Binding VerifyCode, Mode=TwoWay}"/>
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Stretch"
|
||||
Command="{Binding RegisterVerifyCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageHutaoPassportVerifyCodeAction}"/>
|
||||
</Grid>
|
||||
<PasswordBox
|
||||
Margin="0,16,0,0"
|
||||
IsEnabled="{Binding VerifyCode, Converter={StaticResource StringBoolConverter}}"
|
||||
Password="{Binding Password, Mode=TwoWay}"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordHint}"/>
|
||||
<TextBlock
|
||||
Margin="0,4,0,0"
|
||||
Opacity="0.7"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordRequirementHint}"/>
|
||||
<Button
|
||||
Margin="0,16,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
Command="{Binding RegisterCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageHutaoPassportRegisterHeader}"
|
||||
IsEnabled="{Binding VerifyCode, Converter={StaticResource StringBoolConverter}}"
|
||||
Style="{ThemeResource AccentButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</PivotItem>
|
||||
<PivotItem Header="{shcm:ResourceString Name=ViewPageHutaoPassportResetPasswordHeader}">
|
||||
<StackPanel Margin="16">
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportUserNameHint}" Text="{Binding UserName, Mode=TwoWay}"/>
|
||||
<Grid Margin="0,16,0,0" ColumnSpacing="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportVerifyCodeHint}" Text="{Binding VerifyCode, Mode=TwoWay}"/>
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Stretch"
|
||||
Command="{Binding ResetPasswordVerifyCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageHutaoPassportVerifyCodeAction}"/>
|
||||
</Grid>
|
||||
<PasswordBox
|
||||
Margin="0,16,0,0"
|
||||
IsEnabled="{Binding VerifyCode, Converter={StaticResource StringBoolConverter}}"
|
||||
Password="{Binding Password, Mode=TwoWay}"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordHint}"/>
|
||||
<TextBlock
|
||||
Margin="0,4,0,0"
|
||||
Opacity="0.7"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordRequirementHint}"/>
|
||||
<Button
|
||||
Margin="0,16,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
Command="{Binding ResetPasswordCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageHutaoPassportResetPasswordHeader}"
|
||||
IsEnabled="{Binding VerifyCode, Converter={StaticResource StringBoolConverter}}"
|
||||
Style="{ThemeResource AccentButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</PivotItem>
|
||||
</Pivot>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</shc:ScopedPage>
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Control;
|
||||
using Snap.Hutao.ViewModel;
|
||||
|
||||
namespace Snap.Hutao.View.Page;
|
||||
|
||||
/// <summary>
|
||||
/// 胡桃通行证页面
|
||||
/// </summary>
|
||||
internal sealed partial class HutaoPassportPage : ScopedPage
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造一个新的胡桃通行证页面
|
||||
/// </summary>
|
||||
public HutaoPassportPage()
|
||||
{
|
||||
InitializeWith<HutaoPassportViewModel>();
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -68,8 +68,7 @@
|
||||
IsOpen="True"
|
||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameConfigurationSaveHint}"
|
||||
Severity="Informational"/>
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageLaunchGameFileHeader}"/>
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageLaunchGameCommonHeader}"/>
|
||||
<cwc:SettingsCard
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}"
|
||||
@@ -94,8 +93,6 @@
|
||||
Style="{StaticResource DefaultComboBoxStyle}"/>
|
||||
</StackPanel>
|
||||
</cwc:SettingsCard>
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageLaunchGameRegistryHeader}"/>
|
||||
<cwc:SettingsCard
|
||||
ActionIconToolTip="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountDetectAction}"
|
||||
Command="{Binding DetectGameAccountCommand}"
|
||||
@@ -185,68 +182,81 @@
|
||||
</ListView>
|
||||
</Border>
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageLaunchGameProcessHeader}"/>
|
||||
<cwc:SettingsExpander
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameArgumentsDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameArgumentsHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}"
|
||||
IsExpanded="True">
|
||||
<cwc:SettingsExpander.Items>
|
||||
<cwc:SettingsCard Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceExclusiveDescription}" Header="-window-mode exclusive">
|
||||
<ToggleSwitch Width="156" IsOn="{Binding Options.IsExclusive, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
<cwc:SettingsCard Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceFullscreenDescription}" Header="-screen-fullscreen">
|
||||
<ToggleSwitch Width="156" IsOn="{Binding Options.IsFullScreen, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
<cwc:SettingsCard Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceBorderlessDescription}" Header="-popupwindow">
|
||||
<ToggleSwitch Width="156" IsOn="{Binding Options.IsBorderless, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
<cwc:SettingsCard Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenWidthDescription}" Header="-screen-width">
|
||||
<NumberBox
|
||||
Width="156"
|
||||
Padding="10,6,0,0"
|
||||
Value="{Binding Options.ScreenWidth, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
<cwc:SettingsCard Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenHeightDescription}" Header="-screen-height">
|
||||
<NumberBox
|
||||
Width="156"
|
||||
Padding="10,6,0,0"
|
||||
Value="{Binding Options.ScreenHeight, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
<cwc:SettingsCard Description="{shcm:ResourceString Name=ViewPageLaunchGameMonitorsDescription}" Header="-monitor">
|
||||
<ComboBox
|
||||
Width="156"
|
||||
DisplayMemberPath="Name"
|
||||
ItemsSource="{Binding Options.Monitors}"
|
||||
SelectedItem="{Binding Options.Monitor, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
</cwc:SettingsExpander.Items>
|
||||
</cwc:SettingsExpander>
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceHeader}"/>
|
||||
<cwc:SettingsCard
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}"
|
||||
IsEnabled="{Binding HutaoOptions.IsElevated}"
|
||||
Visibility="{Binding AppOptions.IsAdvancedLaunchOptionsEnabled, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<shvc:Elevation Margin="0,0,36,0" Visibility="{Binding HutaoOptions.IsElevated, Converter={StaticResource BoolToVisibilityRevertConverter}}"/>
|
||||
<NumberBox
|
||||
MinWidth="156"
|
||||
Padding="10,8,0,0"
|
||||
Maximum="720"
|
||||
Minimum="60"
|
||||
SpinButtonPlacementMode="Inline"
|
||||
Value="{Binding Options.TargetFps, Mode=TwoWay}"/>
|
||||
<ToggleSwitch
|
||||
Width="120"
|
||||
IsOn="{Binding Options.UnlockFps, Mode=TwoWay}"
|
||||
OffContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOff}"
|
||||
OnContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOn}"/>
|
||||
</StackPanel>
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceExclusiveDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceExclusiveHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}">
|
||||
<ToggleSwitch Width="120" IsOn="{Binding Options.IsExclusive, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
<cwc:SettingsCard
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceFullscreenDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceFullscreenHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}">
|
||||
<ToggleSwitch Width="120" IsOn="{Binding Options.IsFullScreen, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
<cwc:SettingsCard
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceBorderlessDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceBorderlessHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}">
|
||||
<ToggleSwitch Width="120" IsOn="{Binding Options.IsBorderless, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
|
||||
<cwc:SettingsCard
|
||||
Margin="0,6,0,0"
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenWidthDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenWidthHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}">
|
||||
<NumberBox
|
||||
Width="156"
|
||||
Padding="10,6,0,0"
|
||||
Value="{Binding Options.ScreenWidth, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
<cwc:SettingsCard
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenHeightDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenHeightHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}">
|
||||
<NumberBox
|
||||
Width="156"
|
||||
Padding="10,6,0,0"
|
||||
Value="{Binding Options.ScreenHeight, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}"/>
|
||||
<cwc:SettingsCard
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameMonitorsDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameMonitorsHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}">
|
||||
<ComboBox
|
||||
Width="156"
|
||||
DisplayMemberPath="Name"
|
||||
ItemsSource="{Binding Options.Monitors}"
|
||||
SelectedItem="{Binding Options.Monitor, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}" Visibility="{Binding AppOptions.IsAdvancedLaunchOptionsEnabled, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHeader}"/>
|
||||
<cwc:SettingsCard
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}"
|
||||
IsEnabled="{Binding HutaoOptions.IsElevated}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<shvc:Elevation Margin="0,0,36,0" Visibility="{Binding HutaoOptions.IsElevated, Converter={StaticResource BoolToVisibilityRevertConverter}}"/>
|
||||
<NumberBox
|
||||
MinWidth="156"
|
||||
Padding="10,8,0,0"
|
||||
Maximum="720"
|
||||
Minimum="60"
|
||||
SpinButtonPlacementMode="Inline"
|
||||
Value="{Binding Options.TargetFps, Mode=TwoWay}"/>
|
||||
<ToggleSwitch
|
||||
Width="120"
|
||||
IsOn="{Binding Options.UnlockFps, Mode=TwoWay}"
|
||||
OffContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOff}"
|
||||
OnContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOn}"/>
|
||||
</StackPanel>
|
||||
</cwc:SettingsCard>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:shc="using:Snap.Hutao.Control"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
xmlns:shv="using:Snap.Hutao.ViewModel"
|
||||
xmlns:shvc="using:Snap.Hutao.View.Control"
|
||||
xmlns:shvs="using:Snap.Hutao.ViewModel.Setting"
|
||||
d:DataContext="{d:DesignInstance shvs:SettingViewModel}"
|
||||
d:DataContext="{d:DesignInstance shv:SettingViewModel}"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
mc:Ignorable="d">
|
||||
<ScrollViewer>
|
||||
@@ -71,10 +71,11 @@
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Margin="0,4"
|
||||
Text="Copyright © 2022 - 2024 DGP Studio. All Rights Reserved."
|
||||
Text="Copyright © 2022 - 2023 DGP Studio. All Rights Reserved."
|
||||
TextWrapping="Wrap"/>
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageSettingAboutHeader}"/>
|
||||
@@ -94,62 +95,13 @@
|
||||
<cwc:SettingsCard Description="{Binding HutaoOptions.WebView2Version}" Header="{shcm:ResourceString Name=ViewPageSettingWebview2Header}"/>
|
||||
</cwc:SettingsExpander.Items>
|
||||
</cwc:SettingsExpander>
|
||||
<cwc:SettingsExpander
|
||||
<cwc:SettingsCard
|
||||
Command="{Binding NavigateToHutaoPassportCommand}"
|
||||
Description="{Binding UserOptions.UserName}"
|
||||
Header="{shcm:ResourceString Name=ViewPageSettingHutaoPassportHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}"
|
||||
IsExpanded="True">
|
||||
<StackPanel Orientation="Horizontal" Spacing="16">
|
||||
<Button
|
||||
Command="{Binding Passport.LoginCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageSettingHutaoPassportLoginAction}"
|
||||
Style="{ThemeResource SettingButtonStyle}"
|
||||
Visibility="{Binding UserOptions.IsLoggedIn, Converter={StaticResource BoolToVisibilityRevertConverter}}"/>
|
||||
<Button
|
||||
Command="{Binding Passport.RegisterCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageSettingHutaoPassportRegisterAction}"
|
||||
Style="{ThemeResource SettingButtonStyle}"
|
||||
Visibility="{Binding UserOptions.IsLoggedIn, Converter={StaticResource BoolToVisibilityRevertConverter}}"/>
|
||||
<Button
|
||||
Command="{Binding Passport.LogoutCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageSettingHutaoPassportLogoutAction}"
|
||||
Style="{ThemeResource SettingButtonStyle}"
|
||||
Visibility="{Binding UserOptions.IsLoggedIn, Converter={StaticResource BoolToVisibilityConverter}}"/>
|
||||
</StackPanel>
|
||||
<cwc:SettingsExpander.Items>
|
||||
<cwc:SettingsCard
|
||||
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}}"/>
|
||||
<cwc:SettingsCard Description="{Binding UserOptions.GachaLogExpireAtSlim}" Header="{shcm:ResourceString Name=ViewPageSettingHutaoPassportGachaLogExpiredAtHeader}"/>
|
||||
<cwc:SettingsCard
|
||||
Command="{Binding Passport.OpenRedeemWebsiteCommand}"
|
||||
Description="{shcm:ResourceString Name=ViewPageSettingHutaoPassportRedeemCodeDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageSettingHutaoPassportRedeemCodeHeader}"
|
||||
IsClickEnabled="True"/>
|
||||
<cwc:SettingsCard
|
||||
Background="{ThemeResource SystemFillColorCriticalBackgroundBrush}"
|
||||
Description="{shcm:ResourceString Name=ViewPageSettingHutaoPassportDangerZoneDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageSettingHutaoPassportDangerZoneHeader}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="16">
|
||||
<Button
|
||||
Command="{Binding Passport.ResetPasswordCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageSettingHutaoPassportResetPasswordAction}"
|
||||
Style="{ThemeResource SettingButtonStyle}"/>
|
||||
<Button
|
||||
Command="{Binding Passport.UnregisterCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageSettingHutaoPassportUnregisterAction}"
|
||||
Style="{ThemeResource SettingButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</cwc:SettingsCard>
|
||||
</cwc:SettingsExpander.Items>
|
||||
</cwc:SettingsExpander>
|
||||
IsClickEnabled="True"/>
|
||||
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageSettingGeetestVerificationHeader}"/>
|
||||
<cwc:SettingsCard
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Control;
|
||||
using Snap.Hutao.ViewModel.Setting;
|
||||
using Snap.Hutao.ViewModel;
|
||||
|
||||
namespace Snap.Hutao.View.Page;
|
||||
|
||||
|
||||
@@ -126,48 +126,49 @@
|
||||
<Border.Background>
|
||||
<ImageBrush ImageSource="ms-appx:///Resource/Icon/UI_GachaShowPanel_Bg_Weapon.png"/>
|
||||
</Border.Background>
|
||||
<cwc:ConstrainedBox AspectRatio="2048:1024">
|
||||
<Grid>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<mxi:Interaction.Behaviors>
|
||||
<shcb:AutoHeightBehavior TargetHeight="1024" TargetWidth="2048"/>
|
||||
</mxi:Interaction.Behaviors>
|
||||
<Border Grid.ColumnSpan="2" Background="{ThemeResource DarkOnlyOverlayMaskColorBrush}"/>
|
||||
<ScrollViewer
|
||||
Grid.Column="0"
|
||||
Margin="16"
|
||||
VerticalScrollBarVisibility="Hidden">
|
||||
<StackPanel>
|
||||
<shvc:BottomTextControl MaxWidth="80" Text="{shcm:ResourceString Name=ViewPageWiKiWeaponBeforeAscensionTitle}">
|
||||
<shvc:ItemIcon Icon="{Binding Selected.Icon, Converter={StaticResource EquipIconConverter}}" Quality="{Binding Selected.RankLevel}"/>
|
||||
</shvc:BottomTextControl>
|
||||
|
||||
<shvc:BottomTextControl Margin="0,16,0,0" Text="{shcm:ResourceString Name=ViewPageWiKiWeaponAfterAscensionTitle}">
|
||||
<shvc:ItemIcon Icon="{Binding Selected.AwakenIcon, Converter={StaticResource EquipIconConverter}}" Quality="{Binding Selected.RankLevel}"/>
|
||||
</shvc:BottomTextControl>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<Grid Grid.ColumnSpan="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="176*"/>
|
||||
<ColumnDefinition Width="848*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.ColumnSpan="2" Background="{ThemeResource DarkOnlyOverlayMaskColorBrush}"/>
|
||||
<ScrollViewer
|
||||
Grid.Column="0"
|
||||
Margin="16"
|
||||
VerticalScrollBarVisibility="Hidden">
|
||||
<StackPanel>
|
||||
<shvc:BottomTextControl MaxWidth="80" Text="{shcm:ResourceString Name=ViewPageWiKiWeaponBeforeAscensionTitle}">
|
||||
<shvc:ItemIcon Icon="{Binding Selected.Icon, Converter={StaticResource EquipIconConverter}}" Quality="{Binding Selected.RankLevel}"/>
|
||||
</shvc:BottomTextControl>
|
||||
|
||||
<shvc:BottomTextControl Margin="0,16,0,0" Text="{shcm:ResourceString Name=ViewPageWiKiWeaponAfterAscensionTitle}">
|
||||
<shvc:ItemIcon Icon="{Binding Selected.AwakenIcon, Converter={StaticResource EquipIconConverter}}" Quality="{Binding Selected.RankLevel}"/>
|
||||
</shvc:BottomTextControl>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<Grid Grid.ColumnSpan="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="176*"/>
|
||||
<ColumnDefinition Width="848*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<shci:CachedImage
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Stretch"
|
||||
Source="{Binding Selected.Icon, Converter={StaticResource GachaEquipIconConverter}}"/>
|
||||
</Grid>
|
||||
<TextBlock
|
||||
<shci:CachedImage
|
||||
Grid.Column="1"
|
||||
Margin="16"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}"
|
||||
Text="{Binding Selected.Name}"/>
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Stretch"
|
||||
Source="{Binding Selected.Icon, Converter={StaticResource GachaEquipIconConverter}}"/>
|
||||
</Grid>
|
||||
</cwc:ConstrainedBox>
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
Margin="16"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}"
|
||||
Text="{Binding Selected.Name}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Border>
|
||||
|
||||
|
||||
@@ -280,6 +280,7 @@
|
||||
Text="{shcm:ResourceString Name=ViewUserUser}"/>
|
||||
<ListView
|
||||
Grid.Row="1"
|
||||
MaxHeight="224"
|
||||
Margin="4"
|
||||
ItemsSource="{Binding Users}"
|
||||
SelectedItem="{Binding SelectedUser, Mode=TwoWay}"
|
||||
|
||||
@@ -123,19 +123,4 @@ internal sealed partial class DailyNoteViewModel : Abstraction.ViewModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Command("ConfigDailyNoteWebhookUrlCommand")]
|
||||
private async Task ConfigDailyNoteWebhookUrlAsync()
|
||||
{
|
||||
DailyNoteWebhookDialog dialog = await contentDialogFactory.CreateInstanceAsync<DailyNoteWebhookDialog>().ConfigureAwait(true);
|
||||
dialog.Text = options.WebhookUrl;
|
||||
(bool isOk, string url) = await dialog.GetInputUrlAsync().ConfigureAwait(false);
|
||||
|
||||
if (isOk)
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
options.WebhookUrl = url;
|
||||
infoBarService.Information(SH.ViewModelDailyNoteConfigWebhookUrlComplete);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,20 @@ internal abstract class Wish
|
||||
/// </summary>
|
||||
public int TotalCount { get; set; }
|
||||
|
||||
public string TimeSpanFormatted
|
||||
/// <summary>
|
||||
/// 统计开始时间
|
||||
/// </summary>
|
||||
public string FromFormatted
|
||||
{
|
||||
get => $"{From:yyyy.MM.dd} - {To:yyyy.MM.dd}";
|
||||
get => $"{From:yyyy.MM.dd}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 统计开始时间
|
||||
/// </summary>
|
||||
public string ToFormatted
|
||||
{
|
||||
get => $"{To:yyyy.MM.dd}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
154
src/Snap.Hutao/Snap.Hutao/ViewModel/HutaoPassportViewModel.cs
Normal file
154
src/Snap.Hutao/Snap.Hutao/ViewModel/HutaoPassportViewModel.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Common;
|
||||
using Snap.Hutao.Core.Setting;
|
||||
using Snap.Hutao.Service.Hutao;
|
||||
using Snap.Hutao.Service.Navigation;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
using Snap.Hutao.Web.Response;
|
||||
|
||||
namespace Snap.Hutao.ViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// 胡桃通行证视图模型
|
||||
/// </summary>
|
||||
[ConstructorGenerated]
|
||||
[Injection(InjectAs.Scoped)]
|
||||
internal sealed partial class HutaoPassportViewModel : Abstraction.ViewModel
|
||||
{
|
||||
private readonly HomaPassportClient homaPassportClient;
|
||||
private readonly INavigationService navigationService;
|
||||
private readonly HutaoUserOptions hutaoUserOptions;
|
||||
private readonly IInfoBarService infoBarService;
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
private string? userName;
|
||||
private string? password;
|
||||
private string? verifyCode;
|
||||
|
||||
/// <summary>
|
||||
/// 用户名
|
||||
/// </summary>
|
||||
public string? UserName { get => userName; set => SetProperty(ref userName, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
public string? Password { get => password; set => SetProperty(ref password, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 验证码
|
||||
/// </summary>
|
||||
public string? VerifyCode { get => verifyCode; set => SetProperty(ref verifyCode, value); }
|
||||
|
||||
[Command("RegisterVerifyCommand")]
|
||||
private Task RegisterVerifyAsync()
|
||||
{
|
||||
return VerifyAsync(false).AsTask();
|
||||
}
|
||||
|
||||
[Command("RegisterCommand")]
|
||||
private async Task RegisterAsync()
|
||||
{
|
||||
if (UserName is null || Password is null || VerifyCode is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Response<string> response = await homaPassportClient.RegisterAsync(UserName, Password, VerifyCode).ConfigureAwait(false);
|
||||
|
||||
if (response.IsOk())
|
||||
{
|
||||
SaveUserNameAndPassword();
|
||||
infoBarService.Information(response.Message);
|
||||
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
hutaoUserOptions.LoginSucceed(UserName, response.Data);
|
||||
|
||||
await navigationService
|
||||
.NavigateAsync<View.Page.SettingPage>(INavigationAwaiter.Default, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
[Command("ResetPasswordVerifyCommand")]
|
||||
private Task ResetPasswordVerifyAsync()
|
||||
{
|
||||
return VerifyAsync(true).AsTask();
|
||||
}
|
||||
|
||||
[Command("ResetPasswordCommand")]
|
||||
private async Task ResetPasswordAsync()
|
||||
{
|
||||
if (UserName is null || Password is null || VerifyCode is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Response<string> response = await homaPassportClient.ResetPasswordAsync(UserName, Password, VerifyCode).ConfigureAwait(false);
|
||||
|
||||
if (response.IsOk())
|
||||
{
|
||||
SaveUserNameAndPassword();
|
||||
infoBarService.Information(response.Message);
|
||||
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
hutaoUserOptions.LoginSucceed(UserName, response.Data);
|
||||
|
||||
await navigationService
|
||||
.NavigateAsync<View.Page.SettingPage>(INavigationAwaiter.Default, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
[Command("LoginCommand")]
|
||||
private async Task LoginAsync()
|
||||
{
|
||||
if (UserName is null || Password is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Response<string> response = await homaPassportClient.LoginAsync(UserName, Password).ConfigureAwait(false);
|
||||
|
||||
if (response.IsOk())
|
||||
{
|
||||
SaveUserNameAndPassword();
|
||||
infoBarService.Information(response.Message);
|
||||
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
hutaoUserOptions.LoginSucceed(UserName, response.Data);
|
||||
|
||||
await navigationService
|
||||
.NavigateAsync<View.Page.SettingPage>(INavigationAwaiter.Default, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask VerifyAsync(bool isResetPassword)
|
||||
{
|
||||
if (string.IsNullOrEmpty(UserName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UserName.IsEmail())
|
||||
{
|
||||
infoBarService.Warning(SH.ViewModelHutaoPassportEmailNotValidHint);
|
||||
}
|
||||
|
||||
Response response = await homaPassportClient.VerifyAsync(UserName, isResetPassword).ConfigureAwait(false);
|
||||
infoBarService.Information(response.Message);
|
||||
}
|
||||
|
||||
private void SaveUserNameAndPassword()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password))
|
||||
{
|
||||
LocalSetting.Set(SettingKeys.PassportUserName, UserName);
|
||||
LocalSetting.Set(SettingKeys.PassportPassword, Password);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.Setting;
|
||||
using Snap.Hutao.Factory.Abstraction;
|
||||
using Snap.Hutao.Service.Hutao;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.View.Dialog;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using Windows.System;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.Setting;
|
||||
|
||||
/// <summary>
|
||||
/// 胡桃通行证视图模型
|
||||
/// </summary>
|
||||
[ConstructorGenerated]
|
||||
[Injection(InjectAs.Scoped)]
|
||||
internal sealed partial class HutaoPassportViewModel : Abstraction.ViewModel
|
||||
{
|
||||
private readonly IContentDialogFactory contentDialogFactory;
|
||||
private readonly HomaPassportClient homaPassportClient;
|
||||
private readonly HutaoUserOptions hutaoUserOptions;
|
||||
private readonly IInfoBarService infoBarService;
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
[Command("OpenRedeemWebsiteCommand")]
|
||||
private static async Task OpenRedeemWebsiteAsync()
|
||||
{
|
||||
await Launcher.LaunchUriAsync("https://homa.snapgenshin.com/redeem.html".ToUri());
|
||||
}
|
||||
|
||||
private static void SaveUserNameAndPassword(string username, string password)
|
||||
{
|
||||
LocalSetting.Set(SettingKeys.PassportUserName, username);
|
||||
LocalSetting.Set(SettingKeys.PassportPassword, password);
|
||||
}
|
||||
|
||||
[Command("RegisterCommand")]
|
||||
private async Task RegisterAsync()
|
||||
{
|
||||
HutaoPassportRegisterDialog dialog = await contentDialogFactory.CreateInstanceAsync<HutaoPassportRegisterDialog>().ConfigureAwait(false);
|
||||
ValueResult<bool, (string UserName, string Password, string VerifyCode)> result = await dialog.GetInputAsync().ConfigureAwait(false);
|
||||
|
||||
if (result.IsOk)
|
||||
{
|
||||
(string username, string password, string verifyCode) = result.Value;
|
||||
|
||||
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(verifyCode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Response<string> response = await homaPassportClient.RegisterAsync(username, password, verifyCode).ConfigureAwait(false);
|
||||
|
||||
if (response.IsOk())
|
||||
{
|
||||
SaveUserNameAndPassword(username, password);
|
||||
infoBarService.Information(response.Message);
|
||||
await hutaoUserOptions.PostLoginSucceedAsync(homaPassportClient, taskContext, username, response.Data).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Command("UnregisterCommand")]
|
||||
private async Task UnregisterAsync()
|
||||
{
|
||||
HutaoPassportUnregisterDialog dialog = await contentDialogFactory.CreateInstanceAsync<HutaoPassportUnregisterDialog>().ConfigureAwait(false);
|
||||
ValueResult<bool, (string UserName, string Password)> result = await dialog.GetInputAsync().ConfigureAwait(false);
|
||||
|
||||
if (result.IsOk)
|
||||
{
|
||||
(string username, string password) = result.Value;
|
||||
|
||||
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Response response = await homaPassportClient.UnregisterAsync(username, password).ConfigureAwait(false);
|
||||
|
||||
if (response.IsOk())
|
||||
{
|
||||
infoBarService.Information(response.Message);
|
||||
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
hutaoUserOptions.LogoutOrUnregister();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Command("LoginCommand")]
|
||||
private async Task LoginAsync()
|
||||
{
|
||||
HutaoPassportLoginDialog dialog = await contentDialogFactory.CreateInstanceAsync<HutaoPassportLoginDialog>().ConfigureAwait(false);
|
||||
ValueResult<bool, (string UserName, string Password)> result = await dialog.GetInputAsync().ConfigureAwait(false);
|
||||
|
||||
if (result.IsOk)
|
||||
{
|
||||
(string username, string password) = result.Value;
|
||||
|
||||
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Response<string> response = await homaPassportClient.LoginAsync(username, password).ConfigureAwait(false);
|
||||
|
||||
if (response.IsOk())
|
||||
{
|
||||
SaveUserNameAndPassword(username, password);
|
||||
infoBarService.Information(response.Message);
|
||||
|
||||
await hutaoUserOptions.PostLoginSucceedAsync(homaPassportClient, taskContext, username, response.Data).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Command("LogoutCommand")]
|
||||
private void LogoutAsync()
|
||||
{
|
||||
hutaoUserOptions.LogoutOrUnregister();
|
||||
}
|
||||
|
||||
[Command("ResetPasswordCommand")]
|
||||
private async Task ResetPasswordAsync()
|
||||
{
|
||||
HutaoPassportResetPasswordDialog dialog = await contentDialogFactory.CreateInstanceAsync<HutaoPassportResetPasswordDialog>().ConfigureAwait(false);
|
||||
ValueResult<bool, (string UserName, string Password, string VerifyCode)> result = await dialog.GetInputAsync().ConfigureAwait(false);
|
||||
|
||||
if (result.IsOk)
|
||||
{
|
||||
(string username, string password, string verifyCode) = result.Value;
|
||||
|
||||
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(verifyCode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Response<string> response = await homaPassportClient.ResetPasswordAsync(username, password, verifyCode).ConfigureAwait(false);
|
||||
|
||||
if (response.IsOk())
|
||||
{
|
||||
SaveUserNameAndPassword(username, password);
|
||||
infoBarService.Information(response.Message);
|
||||
|
||||
await hutaoUserOptions.PostLoginSucceedAsync(homaPassportClient, taskContext, username, response.Data).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ using System.Runtime.InteropServices;
|
||||
using Windows.Storage.Pickers;
|
||||
using Windows.System;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.Setting;
|
||||
namespace Snap.Hutao.ViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// 设置视图模型
|
||||
@@ -45,7 +45,6 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
|
||||
private readonly INavigationService navigationService;
|
||||
private readonly IClipboardInterop clipboardInterop;
|
||||
private readonly IShellLinkInterop shellLinkInterop;
|
||||
private readonly HutaoPassportViewModel hutaoPassportViewModel;
|
||||
private readonly HutaoUserOptions hutaoUserOptions;
|
||||
private readonly IInfoBarService infoBarService;
|
||||
private readonly RuntimeOptions runtimeOptions;
|
||||
@@ -74,8 +73,6 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
|
||||
|
||||
public HomeCardOptions HomeCardOptions { get => homeCardOptions; }
|
||||
|
||||
public HutaoPassportViewModel Passport { get => hutaoPassportViewModel; }
|
||||
|
||||
/// <summary>
|
||||
/// 选中的背景类型
|
||||
/// </summary>
|
||||
@@ -230,6 +227,12 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
[Command("NavigateToHutaoPassportCommand")]
|
||||
private void NavigateToHutaoPassport()
|
||||
{
|
||||
navigationService.Navigate<View.Page.HutaoPassportPage>(INavigationAwaiter.Default);
|
||||
}
|
||||
|
||||
[Command("OpenCacheFolderCommand")]
|
||||
private Task OpenCacheFolderAsync()
|
||||
{
|
||||
@@ -8,7 +8,6 @@ using Snap.Hutao.Service.SpiralAbyss;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.ViewModel.Complex;
|
||||
using Snap.Hutao.ViewModel.User;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
using Snap.Hutao.Web.Hutao.SpiralAbyss;
|
||||
using Snap.Hutao.Web.Hutao.SpiralAbyss.Post;
|
||||
using System.Collections.ObjectModel;
|
||||
@@ -135,17 +134,11 @@ internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel
|
||||
|
||||
if (response is { ReturnCode: 0 })
|
||||
{
|
||||
if (response is ILocalizableResponse localizableResponse)
|
||||
{
|
||||
infoBarService.Success(localizableResponse.GetLocalizationMessage());
|
||||
}
|
||||
infoBarService.Success(response.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (response is ILocalizableResponse localizableResponse)
|
||||
{
|
||||
infoBarService.Warning(localizableResponse.GetLocalizationMessage());
|
||||
}
|
||||
infoBarService.Warning(response.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,4 +148,5 @@ internal sealed class SpiralAbyssView : IEntityOnly<SpiralAbyssEntry?>,
|
||||
{
|
||||
return ranks.Where(r => r.AvatarId != 0U).Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).SingleOrDefault();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,6 @@ using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Snap.Hutao.Core;
|
||||
using Snap.Hutao.Core.ExceptionService;
|
||||
using Snap.Hutao.Core.IO.DataTransfer;
|
||||
using Snap.Hutao.Factory.Abstraction;
|
||||
using Snap.Hutao.Service.Navigation;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.SignIn;
|
||||
@@ -29,7 +28,6 @@ namespace Snap.Hutao.ViewModel.User;
|
||||
[Injection(InjectAs.Singleton)]
|
||||
internal sealed partial class UserViewModel : ObservableObject
|
||||
{
|
||||
private readonly IContentDialogFactory contentDialogFactory;
|
||||
private readonly IDocumentationProvider documentationProvider;
|
||||
private readonly INavigationService navigationService;
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
@@ -133,7 +131,7 @@ internal sealed partial class UserViewModel : ObservableObject
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
|
||||
// Get cookie from user input
|
||||
UserDialog dialog = await contentDialogFactory.CreateInstanceAsync<UserDialog>().ConfigureAwait(false);
|
||||
UserDialog dialog = serviceProvider.CreateInstance<UserDialog>();
|
||||
ValueResult<bool, string> result = await dialog.GetInputCookieAsync().ConfigureAwait(false);
|
||||
|
||||
// User confirms the input
|
||||
|
||||
@@ -168,7 +168,7 @@ internal static class ApiEndpoints
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ApiTakumiEventBbsSignReward
|
||||
#region
|
||||
|
||||
/// <summary>
|
||||
/// 签到活动Id
|
||||
@@ -367,19 +367,6 @@ internal static class ApiEndpoints
|
||||
public const string AccountCreateActionTicket = $"{PassportApi}/account/ma-cn-verifier/app/createActionTicketByToken";
|
||||
#endregion
|
||||
|
||||
#region PublicDataApi
|
||||
|
||||
/// <summary>
|
||||
/// 获取 fingerprint
|
||||
/// </summary>
|
||||
public const string DeviceFpGetFp = $"{PublicDataApiDeviceFpApi}/getFp";
|
||||
|
||||
public static string DeviceFpGetExtList(int platform)
|
||||
{
|
||||
return $"{PublicDataApiDeviceFpApi}/getExtList?platform={platform:D}";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SdkStaticLauncherApi
|
||||
|
||||
/// <summary>
|
||||
@@ -431,9 +418,6 @@ internal static class ApiEndpoints
|
||||
private const string PassportApiAuthApi = $"{PassportApi}/account/auth/api";
|
||||
private const string PassportApiV4 = "https://passport-api-v4.mihoyo.com";
|
||||
|
||||
private const string PublicDataApi = "https://public-data-api.mihoyo.com";
|
||||
private const string PublicDataApiDeviceFpApi = $"{PublicDataApi}/device-fp/api";
|
||||
|
||||
private const string SdkStatic = "https://sdk-static.mihoyo.com";
|
||||
private const string SdkStaticLauncherApi = $"{SdkStatic}/hk4e_cn/mdk/launcher/api";
|
||||
|
||||
|
||||
@@ -51,13 +51,13 @@ internal class MiHoYoJSInterface
|
||||
private readonly TypedEventHandler<CoreWebView2, CoreWebView2DOMContentLoadedEventArgs> domContentLoadedEventHandler;
|
||||
private readonly TypedEventHandler<CoreWebView2, CoreWebView2NavigationStartingEventArgs> navigationStartingEventHandler;
|
||||
|
||||
private CoreWebView2 coreWebView2;
|
||||
private CoreWebView2 webView;
|
||||
|
||||
public MiHoYoJSInterface(CoreWebView2 coreWebView2, UserAndUid userAndUid)
|
||||
public MiHoYoJSInterface(CoreWebView2 webView, UserAndUid userAndUid)
|
||||
{
|
||||
// 由于Webview2 的作用域特殊性,我们在此处直接使用根服务
|
||||
serviceProvider = Ioc.Default;
|
||||
this.coreWebView2 = coreWebView2;
|
||||
this.webView = webView;
|
||||
this.userAndUid = userAndUid;
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
@@ -67,9 +67,9 @@ internal class MiHoYoJSInterface
|
||||
domContentLoadedEventHandler = OnDOMContentLoaded;
|
||||
navigationStartingEventHandler = OnNavigationStarting;
|
||||
|
||||
coreWebView2.WebMessageReceived += webMessageReceivedEventHandler;
|
||||
coreWebView2.DOMContentLoaded += domContentLoadedEventHandler;
|
||||
coreWebView2.NavigationStarting += navigationStartingEventHandler;
|
||||
webView.WebMessageReceived += webMessageReceivedEventHandler;
|
||||
webView.DOMContentLoaded += domContentLoadedEventHandler;
|
||||
webView.NavigationStarting += navigationStartingEventHandler;
|
||||
}
|
||||
|
||||
public event Action? ClosePageRequested;
|
||||
@@ -227,7 +227,7 @@ internal class MiHoYoJSInterface
|
||||
}
|
||||
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
coreWebView2.SetCookie(userAndUid.User.CookieToken, userAndUid.User.LToken);
|
||||
webView.SetCookie(userAndUid.User.CookieToken, userAndUid.User.LToken);
|
||||
|
||||
ArgumentNullException.ThrowIfNull(userAndUid.User.CookieToken);
|
||||
return new() { Data = new() { [Cookie.COOKIE_TOKEN] = userAndUid.User.CookieToken[Cookie.COOKIE_TOKEN] } };
|
||||
@@ -241,9 +241,9 @@ internal class MiHoYoJSInterface
|
||||
public virtual async ValueTask<IJsResult?> ClosePageAsync(JsParam param)
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
if (coreWebView2.CanGoBack)
|
||||
if (webView.CanGoBack)
|
||||
{
|
||||
coreWebView2.GoBack();
|
||||
webView.GoBack();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -276,7 +276,7 @@ internal class MiHoYoJSInterface
|
||||
public virtual async ValueTask<IJsResult?> PushPageAsync(JsParam<PushPagePayload> param)
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
coreWebView2.Navigate(param.Payload.Page);
|
||||
webView.Navigate(param.Payload.Page);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -299,17 +299,6 @@ internal class MiHoYoJSInterface
|
||||
};
|
||||
}
|
||||
|
||||
public virtual IJsResult? Share(JsParam<SharePayload> param)
|
||||
{
|
||||
return new JsResult<Dictionary<string, string>>()
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
["type"] = param.Payload.Type,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public virtual ValueTask<IJsResult?> ShowAlertDialogAsync(JsParam param)
|
||||
{
|
||||
return ValueTask.FromException<IJsResult?>(new NotSupportedException());
|
||||
@@ -357,10 +346,10 @@ internal class MiHoYoJSInterface
|
||||
|
||||
public void Detach()
|
||||
{
|
||||
coreWebView2.WebMessageReceived -= webMessageReceivedEventHandler;
|
||||
coreWebView2.DOMContentLoaded -= domContentLoadedEventHandler;
|
||||
coreWebView2.NavigationStarting -= navigationStartingEventHandler;
|
||||
coreWebView2 = default!;
|
||||
webView.WebMessageReceived -= webMessageReceivedEventHandler;
|
||||
webView.DOMContentLoaded -= domContentLoadedEventHandler;
|
||||
webView.NavigationStarting -= navigationStartingEventHandler;
|
||||
webView = default!;
|
||||
}
|
||||
|
||||
private async ValueTask<string> ExecuteCallbackScriptAsync(string callback, string? payload = null)
|
||||
@@ -386,9 +375,9 @@ internal class MiHoYoJSInterface
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
try
|
||||
{
|
||||
if (coreWebView2 is not null)
|
||||
if (webView is not null)
|
||||
{
|
||||
return await coreWebView2.ExecuteScriptAsync(js);
|
||||
return await webView.ExecuteScriptAsync(js);
|
||||
}
|
||||
}
|
||||
catch (COMException)
|
||||
@@ -447,7 +436,6 @@ internal class MiHoYoJSInterface
|
||||
"hideLoading" => null,
|
||||
"login" => null,
|
||||
"pushPage" => await PushPageAsync(param).ConfigureAwait(false),
|
||||
"share" => Share(param),
|
||||
"showLoading" => null,
|
||||
_ => LogUnhandledMessage("Unhandled Message Type: {method}", param.Method),
|
||||
};
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Bridge.Model;
|
||||
|
||||
internal sealed class ShareContent
|
||||
{
|
||||
[JsonPropertyName("preview")]
|
||||
public bool Preview { get; set; }
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user