Compare commits

..

9 Commits

Author SHA1 Message Date
DismissedLight
7c03ce3486 1.7.11 hotfix package 2023-10-18 19:54:55 +08:00
DismissedLight
83e187ea9e fix launch args 2023-10-18 19:54:55 +08:00
Lightczx
d86232f413 fix #1028 2023-10-18 19:54:55 +08:00
Masterain
4e6691ac51 Update FUNDING.yml 2023-10-18 19:54:55 +08:00
Masterain
84ad39b192 Update FUNDING.yml 2023-10-18 19:54:55 +08:00
DismissedLight
ce50fc41e0 1.7.10 package 2023-10-17 22:14:50 +08:00
Masterain
1d71048f56 New Crowdin updates (#1019) 2023-10-17 22:14:50 +08:00
DismissedLight
08cf823156 auto select existed account when detecting 2023-10-17 22:14:50 +08:00
Lightczx
cca65635a6 investigate into CoreWindow 2023-10-17 14:52:38 +08:00
138 changed files with 10268 additions and 5104 deletions

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View 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

View File

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

View 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
View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>

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

View File

@@ -12,7 +12,6 @@
<ResourceDictionary Source="ms-appx:///Control/Theme/Color.xaml"/>
<ResourceDictionary Source="ms-appx:///Control/Theme/Converter.xaml"/>
<ResourceDictionary Source="ms-appx:///Control/Theme/CornerRadius.xaml"/>
<ResourceDictionary Source="ms-appx:///Control/Theme/FlyoutStyle.xaml"/>
<ResourceDictionary Source="ms-appx:///Control/Theme/FontStyle.xaml"/>
<ResourceDictionary Source="ms-appx:///Control/Theme/Glyph.xaml"/>
<ResourceDictionary Source="ms-appx:///Control/Theme/InfoBarOverride.xaml"/>

View File

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

View File

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

View File

@@ -1,46 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using CommunityToolkit.Labs.WinUI.MarqueeTextRns;
using CommunityToolkit.WinUI.Behaviors;
using Microsoft.UI.Xaml.Input;
namespace Snap.Hutao.Control.Behavior;
internal sealed class MarqueeTextBehavior : BehaviorBase<MarqueeText>
{
private readonly PointerEventHandler pointerEnteredEventHandler;
private readonly PointerEventHandler pointerExitedEventHandler;
public MarqueeTextBehavior()
{
pointerEnteredEventHandler = OnPointerEntered;
pointerExitedEventHandler = OnPointerExited;
}
protected override bool Initialize()
{
AssociatedObject.PointerEntered += pointerEnteredEventHandler;
AssociatedObject.PointerExited += pointerExitedEventHandler;
return true;
}
protected override bool Uninitialize()
{
AssociatedObject.PointerEntered -= pointerEnteredEventHandler;
AssociatedObject.PointerExited -= pointerExitedEventHandler;
return true;
}
private void OnPointerEntered(object sender, PointerRoutedEventArgs e)
{
AssociatedObject.StartMarquee();
}
private void OnPointerExited(object sender, PointerRoutedEventArgs e)
{
AssociatedObject.StopMarquee();
}
}

View File

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

View File

@@ -1,31 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using CommunityToolkit.WinUI.Animations;
using Microsoft.UI.Xaml;
using Microsoft.Xaml.Interactivity;
namespace Snap.Hutao.Control.Behavior;
[DependencyProperty("Animation", typeof(AnimationSet))]
[DependencyProperty("TargetObject", typeof(UIElement))]
internal sealed partial class StartAnimationActionNoThrow : DependencyObject, IAction
{
/// <inheritdoc/>
public object Execute(object sender, object parameter)
{
if (Animation is not null)
{
if (TargetObject is not null)
{
Animation.Start(TargetObject);
}
else
{
Animation.Start(sender as UIElement);
}
}
return default!;
}
}

View File

@@ -1,22 +0,0 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style
x:Key="WebViewerFlyoutPresenterStyle"
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="0"/>
<Setter Property="CornerRadius" Value="0"/>
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}"/>
</Style>
<Style
x:Key="FlyoutPresenterPadding0And2Style"
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="0,2"/>
</Style>
<Style
x:Key="FlyoutPresenterPadding6Style"
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="6"/>
</Style>
</ResourceDictionary>

View File

@@ -11,28 +11,13 @@
<ItemsPanelTemplate x:Key="WrapPanelSpacing4Template">
<cwcont:WrapPanel HorizontalSpacing="4" VerticalSpacing="4"/>
</ItemsPanelTemplate>
<ItemsPanelTemplate x:Key="HorizontalStackPanelSpacing0Template">
<ItemsPanelTemplate x:Key="HorizontalStackPanelTemplate">
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
<ItemsPanelTemplate x:Key="HorizontalStackPanelSpacing2Template">
<StackPanel Orientation="Horizontal" Spacing="2"/>
</ItemsPanelTemplate>
<ItemsPanelTemplate x:Key="UniformGridColumns2Spacing2Template">
<cwcont:UniformGrid
ColumnSpacing="2"
Columns="2"
RowSpacing="2"/>
</ItemsPanelTemplate>
<ItemsPanelTemplate x:Key="UniformGridColumns5Spacing4Template">
<cwcont:UniformGrid
ColumnSpacing="4"
Columns="5"
RowSpacing="4"/>
</ItemsPanelTemplate>
<ItemsPanelTemplate x:Key="UniformGridColumns5Spacing8Template">
<cwcont:UniformGrid
ColumnSpacing="8"
Columns="5"
RowSpacing="8"/>
</ItemsPanelTemplate>
</ResourceDictionary>

View File

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

View File

@@ -14,10 +14,4 @@
<TransitionCollection x:Key="ReorderThemeTransitions">
<ReorderThemeTransition/>
</TransitionCollection>
<TransitionCollection x:Key="RepositionThemeTransitions">
<RepositionThemeTransition/>
</TransitionCollection>
<TransitionCollection x:Key="NavigationThemeTransitions">
<NavigationThemeTransition/>
</TransitionCollection>
</ResourceDictionary>

View File

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

View File

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

View File

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

View File

@@ -8,4 +8,4 @@ namespace Snap.Hutao.Core.LifeCycle;
internal interface ICurrentWindowReference
{
public Window Window { get; set; }
}
}

View File

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

View File

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

View File

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

View File

@@ -48,11 +48,6 @@ internal sealed partial class SettingEntry
/// </summary>
public const string DailyNoteSilentWhenPlayingGame = "DailyNote.SilentWhenPlayingGame";
/// <summary>
/// 实时便笺 WebhookUrl
/// </summary>
public const string DailyNoteWebhookUrl = "DailyNote.WebhookUrl";
/// <summary>
/// 启动游戏 独占全屏
/// </summary>
@@ -73,15 +68,11 @@ internal sealed partial class SettingEntry
/// </summary>
public const string LaunchScreenWidth = "Launch.ScreenWidth";
public const string LaunchIsScreenWidthEnabled = "Launch.IsScreenWidthEnabled";
/// <summary>
/// 启动游戏 高度
/// </summary>
public const string LaunchScreenHeight = "Launch.ScreenHeight";
public const string LaunchIsScreenHeightEnabled = "Launch.IsScreenHeightEnabled";
/// <summary>
/// 启动游戏 解锁帧率
/// </summary>
@@ -97,8 +88,6 @@ internal sealed partial class SettingEntry
/// </summary>
public const string LaunchMonitor = "Launch.Monitor";
public const string LaunchIsMonitorEnabled = "Launch.IsMonitorEnabled";
/// <summary>
/// 启动游戏 多倍启动
/// </summary>

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 913 B

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@@ -506,84 +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="ServerPassportVerifyRequestNotCurrentUser" xml:space="preserve">
<value>验证请求失败,不是当前登录的账号</value>
</data>
<data name="ServerPassportVerifyRequestSuccess" xml:space="preserve">
<value>验证码已发送至邮箱</value>
</data>
<data name="ServerPassportVerifyRequestUserAlreadyExisted" 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>
@@ -1121,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>
@@ -1172,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>
@@ -1367,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>
@@ -1694,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>
@@ -1802,9 +1691,6 @@
<data name="ViewPageGachaLogInputAction" xml:space="preserve">
<value>输入</value>
</data>
<data name="ViewPageGachaLogRecoverFromHutaoCloudDescription" xml:space="preserve">
<value>从胡桃云恢复祈愿记录</value>
</data>
<data name="ViewPageGachaLogRefresh" xml:space="preserve">
<value>刷新</value>
</data>
@@ -1949,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>
@@ -2000,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>
@@ -2030,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>
@@ -2234,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>
@@ -2495,9 +2321,6 @@
<data name="ViewSpiralAbyssUploadRecord" xml:space="preserve">
<value>上传数据</value>
</data>
<data name="ViewTitleAutoClicking" xml:space="preserve">
<value>自动连点</value>
</data>
<data name="ViewToolHeader" xml:space="preserve">
<value>工具</value>
</data>
@@ -2597,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>

View File

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

View File

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

View File

@@ -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.DailyNoteWebhookUrl);
set => SetOption(ref webhookUrl, SettingEntry.DailyNoteWebhookUrl, value);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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>
/// 异步获取祈愿记录

View File

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

View File

@@ -1,52 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
namespace Snap.Hutao.Service.Game;
internal static class KnownLaunchSchemes
{
private static readonly LaunchScheme ServerChineseChannelDefaultSubChannelDefaultCompat = new LaunchSchemeChinese(ChannelType.Default, SubChannelType.Default, false);
private static readonly LaunchScheme ServerChineseChannelOfficialSubChannelDefault = new LaunchSchemeChinese(ChannelType.Official, SubChannelType.Default);
private static readonly LaunchScheme ServerChineseChannelOfficialSubChannelOfficial = new LaunchSchemeChinese(ChannelType.Official, SubChannelType.Official);
private static readonly LaunchScheme ServerChineseChannelOfficialSubChannelNoTapTap = new LaunchSchemeChinese(ChannelType.Official, SubChannelType.NoTapTap);
private static readonly LaunchScheme ServerChineseChannelOfficialSubChannelEpicCompat = new LaunchSchemeChinese(ChannelType.Official, SubChannelType.Epic, false);
private static readonly LaunchScheme ServerChineseChannelBilibiliSubChannelDefault = new LaunchSchemeBilibili(SubChannelType.Default);
private static readonly LaunchScheme ServerChineseChannelBilibiliSubChannelOfficialCompat = new LaunchSchemeBilibili(SubChannelType.Official, false);
private static readonly LaunchScheme ServerGlobalChannelDefaultSubChannelDefaultCompat = new LaunchSchemeOversea(ChannelType.Default, SubChannelType.Default, false);
private static readonly LaunchScheme ServerGlobalChannelOfficialSubChannelDefault = new LaunchSchemeOversea(ChannelType.Official, SubChannelType.Default);
private static readonly LaunchScheme ServerGlobalChannelOfficialSubChannelOfficial = new LaunchSchemeOversea(ChannelType.Official, SubChannelType.Official);
private static readonly LaunchScheme ServerGlobalChannelOfficialSubChannelEpic = new LaunchSchemeOversea(ChannelType.Official, SubChannelType.Epic);
private static readonly LaunchScheme ServerGlobalChannelOfficialSubChannelGoogle = new LaunchSchemeOversea(ChannelType.Official, SubChannelType.Google);
/// <summary>
/// 获取已知的启动方案
/// </summary>
/// <returns>已知的启动方案</returns>
public static List<LaunchScheme> Get()
{
return new List<LaunchScheme>()
{
// 官服
ServerChineseChannelDefaultSubChannelDefaultCompat,
ServerChineseChannelOfficialSubChannelDefault,
ServerChineseChannelOfficialSubChannelOfficial,
ServerChineseChannelOfficialSubChannelNoTapTap,
ServerChineseChannelOfficialSubChannelEpicCompat,
// 渠道服
ServerChineseChannelBilibiliSubChannelDefault,
ServerChineseChannelBilibiliSubChannelOfficialCompat,
// 国际服
ServerGlobalChannelDefaultSubChannelDefaultCompat,
ServerGlobalChannelOfficialSubChannelDefault,
ServerGlobalChannelOfficialSubChannelOfficial,
ServerGlobalChannelOfficialSubChannelEpic,
ServerGlobalChannelOfficialSubChannelGoogle,
};
}
}

View File

@@ -27,13 +27,10 @@ internal sealed class LaunchOptions : DbStoreOptions
private bool? isBorderless;
private bool? isExclusive;
private int? screenWidth;
private bool? isScreenWidthEnabled;
private int? screenHeight;
private bool? isScreenHeightEnabled;
private bool? unlockFps;
private int? targetFps;
private NameValue<int>? monitor;
private bool? isMonitorEnabled;
/// <summary>
/// 构造一个新的启动游戏选项
@@ -56,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>
@@ -65,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>
@@ -74,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>
@@ -86,12 +102,6 @@ internal sealed class LaunchOptions : DbStoreOptions
set => SetOption(ref screenWidth, SettingEntry.LaunchScreenWidth, value);
}
public bool IsScreenWidthEnabled
{
get => GetOption(ref isScreenWidthEnabled, SettingEntry.LaunchIsScreenWidthEnabled, true);
set => SetOption(ref isScreenWidthEnabled, SettingEntry.LaunchIsScreenWidthEnabled, value);
}
/// <summary>
/// 屏幕高度
/// </summary>
@@ -101,12 +111,6 @@ internal sealed class LaunchOptions : DbStoreOptions
set => SetOption(ref screenHeight, SettingEntry.LaunchScreenHeight, value);
}
public bool IsScreenHeightEnabled
{
get => GetOption(ref isScreenHeightEnabled, SettingEntry.LaunchIsScreenHeightEnabled, true);
set => SetOption(ref isScreenHeightEnabled, SettingEntry.LaunchIsScreenHeightEnabled, value);
}
/// <summary>
/// 是否全屏
/// </summary>
@@ -146,16 +150,10 @@ internal sealed class LaunchOptions : DbStoreOptions
}
}
public bool IsMonitorEnabled
{
get => GetOption(ref isMonitorEnabled, SettingEntry.LaunchIsMonitorEnabled, true);
set => SetOption(ref isMonitorEnabled, SettingEntry.LaunchIsMonitorEnabled, value);
}
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++)
{
@@ -167,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();
}
}
}

View File

@@ -0,0 +1,150 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
namespace Snap.Hutao.Service.Game;
/// <summary>
/// 方案列表部分
/// </summary>
internal sealed partial class LaunchScheme
{
private const int SdkStaticLauncherChineseId = 18;
private const int SdkStaticLauncherBilibiliId = 17;
private const int SdkStaticLauncherGlobalId = 10;
private const string SdkStaticLauncherChineseKey = "eYd89JmJ";
private const string SdkStaticLauncherBilibiliKey = "KAtdSsoQ";
private const string SdkStaticLauncherGlobalKey = "gcStgarh";
private static readonly LaunchScheme ServerChineseChannelDefaultSubChannelDefaultCompatOnly = new()
{
LauncherId = SdkStaticLauncherChineseId,
Key = SdkStaticLauncherChineseKey,
Channel = ChannelType.Default,
SubChannel = SubChannelType.Default,
IsOversea = false,
IsNotCompatOnly = false,
};
private static readonly LaunchScheme ServerChineseChannelOfficialSubChannelDefault = new()
{
LauncherId = SdkStaticLauncherChineseId,
Key = SdkStaticLauncherChineseKey,
Channel = ChannelType.Official,
SubChannel = SubChannelType.Default,
IsOversea = false,
};
private static readonly LaunchScheme ServerChineseChannelOfficialSubChannelOfficial = new()
{
LauncherId = SdkStaticLauncherChineseId,
Key = SdkStaticLauncherChineseKey,
Channel = ChannelType.Official,
SubChannel = SubChannelType.Official,
IsOversea = false,
};
private static readonly LaunchScheme ServerChineseChannelOfficialSubChannelNoTapTap = new()
{
LauncherId = SdkStaticLauncherChineseId,
Key = SdkStaticLauncherChineseKey,
Channel = ChannelType.Official,
SubChannel = SubChannelType.NoTapTap,
IsOversea = false,
};
private static readonly LaunchScheme ServerChineseChannelOfficialSubChannelEpicCompatOnly = new()
{
LauncherId = SdkStaticLauncherChineseId,
Key = SdkStaticLauncherChineseKey,
Channel = ChannelType.Official,
SubChannel = SubChannelType.Epic,
IsOversea = false,
IsNotCompatOnly = false,
};
private static readonly LaunchScheme ServerChineseChannelBilibiliSubChannelDefault = new()
{
LauncherId = SdkStaticLauncherBilibiliId,
Key = SdkStaticLauncherBilibiliKey,
Channel = ChannelType.Bili,
SubChannel = SubChannelType.Default,
IsOversea = false,
};
private static readonly LaunchScheme ServerChineseChannelBilibiliSubChannelOfficialCompatOnly = new()
{
LauncherId = SdkStaticLauncherBilibiliId,
Key = SdkStaticLauncherBilibiliKey,
Channel = ChannelType.Bili,
SubChannel = SubChannelType.Official,
IsOversea = false,
IsNotCompatOnly = false,
};
private static readonly LaunchScheme ServerGlobalChannelDefaultSubChannelDefaultCompatOnly = new()
{
LauncherId = SdkStaticLauncherGlobalId,
Key = SdkStaticLauncherGlobalKey,
Channel = ChannelType.Default,
SubChannel = SubChannelType.Default,
IsOversea = true,
IsNotCompatOnly = false,
};
private static readonly LaunchScheme ServerGlobalChannelOfficialSubChannelDefault = new()
{
LauncherId = SdkStaticLauncherGlobalId,
Key = SdkStaticLauncherGlobalKey,
Channel = ChannelType.Official,
SubChannel = SubChannelType.Default,
IsOversea = true,
};
private static readonly LaunchScheme ServerGlobalChannelOfficialSubChannelEpic = new()
{
LauncherId = SdkStaticLauncherGlobalId,
Key = SdkStaticLauncherGlobalKey,
Channel = ChannelType.Official,
SubChannel = SubChannelType.Epic,
IsOversea = true,
};
private static readonly LaunchScheme ServerGlobalChannelOfficialSubChannelGoogle = new()
{
LauncherId = SdkStaticLauncherGlobalId,
Key = SdkStaticLauncherGlobalKey,
Channel = ChannelType.Official,
SubChannel = SubChannelType.Google,
IsOversea = true,
};
/// <summary>
/// 获取已知的启动方案
/// </summary>
/// <returns>已知的启动方案</returns>
public static List<LaunchScheme> GetKnownSchemes()
{
return new List<LaunchScheme>()
{
// 官服
ServerChineseChannelDefaultSubChannelDefaultCompatOnly,
ServerChineseChannelOfficialSubChannelDefault,
ServerChineseChannelOfficialSubChannelOfficial,
ServerChineseChannelOfficialSubChannelNoTapTap,
ServerChineseChannelOfficialSubChannelEpicCompatOnly,
// 渠道服
ServerChineseChannelBilibiliSubChannelDefault,
ServerChineseChannelBilibiliSubChannelOfficialCompatOnly,
// 国际服
ServerGlobalChannelDefaultSubChannelDefaultCompatOnly,
ServerGlobalChannelOfficialSubChannelDefault,
ServerGlobalChannelOfficialSubChannelEpic,
ServerGlobalChannelOfficialSubChannelGoogle,
};
}
}

View File

@@ -9,7 +9,7 @@ namespace Snap.Hutao.Service.Game;
/// 启动方案
/// </summary>
[HighQuality]
internal partial class LaunchScheme
internal sealed partial class LaunchScheme
{
/// <summary>
/// 显示名称
@@ -32,29 +32,29 @@ internal partial class LaunchScheme
/// <summary>
/// 通道
/// </summary>
public ChannelType Channel { get; private protected set; }
public ChannelType Channel { get; private set; }
/// <summary>
/// 子通道
/// </summary>
public SubChannelType SubChannel { get; private protected set; }
public SubChannelType SubChannel { get; private set; }
/// <summary>
/// 启动器 Id
/// </summary>
public int LauncherId { get; private protected set; }
public int LauncherId { get; private set; }
/// <summary>
/// API Key
/// </summary>
public string Key { get; private protected set; } = default!;
public string Key { get; private set; } = default!;
/// <summary>
/// 是否为海外
/// </summary>
public bool IsOversea { get; private protected set; }
public bool IsOversea { get; private set; }
public bool IsNotCompatOnly { get; private protected set; } = true;
public bool IsNotCompatOnly { get; private set; } = true;
/// <summary>
/// 多通道相等

View File

@@ -1,22 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
namespace Snap.Hutao.Service.Game;
internal sealed class LaunchSchemeBilibili : LaunchScheme
{
private const int SdkStaticLauncherBilibiliId = 17;
private const string SdkStaticLauncherBilibiliKey = "KAtdSsoQ";
public LaunchSchemeBilibili(SubChannelType subChannel, bool isNotCompatOnly = true)
{
LauncherId = SdkStaticLauncherBilibiliId;
Key = SdkStaticLauncherBilibiliKey;
Channel = ChannelType.Bili;
SubChannel = subChannel;
IsOversea = false;
IsNotCompatOnly = isNotCompatOnly;
}
}

View File

@@ -1,22 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
namespace Snap.Hutao.Service.Game;
internal sealed class LaunchSchemeChinese : LaunchScheme
{
private const int SdkStaticLauncherChineseId = 18;
private const string SdkStaticLauncherChineseKey = "eYd89JmJ";
public LaunchSchemeChinese(ChannelType channel, SubChannelType subChannel, bool isNotCompatOnly = true)
{
LauncherId = SdkStaticLauncherChineseId;
Key = SdkStaticLauncherChineseKey;
Channel = channel;
SubChannel = subChannel;
IsOversea = false;
IsNotCompatOnly = isNotCompatOnly;
}
}

View File

@@ -1,22 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
namespace Snap.Hutao.Service.Game;
internal sealed class LaunchSchemeOversea : LaunchScheme
{
private const int SdkStaticLauncherOverseaId = 10;
private const string SdkStaticLauncherOverseaKey = "gcStgarh";
public LaunchSchemeOversea(ChannelType channel, SubChannelType subChannel, bool isNotCompatOnly = true)
{
LauncherId = SdkStaticLauncherOverseaId;
Key = SdkStaticLauncherOverseaKey;
Channel = channel;
SubChannel = subChannel;
IsOversea = true;
IsNotCompatOnly = isNotCompatOnly;
}
}

View File

@@ -34,9 +34,9 @@ internal static class ProcessInterop
.AppendIf("-popupwindow", options.IsBorderless)
.AppendIf("-window-mode", options.IsExclusive, "exclusive")
.Append("-screen-fullscreen", options.IsFullScreen ? 1 : 0)
.AppendIf("-screen-width", options.IsScreenWidthEnabled, options.ScreenWidth)
.AppendIf("-screen-height", options.IsScreenHeightEnabled, options.ScreenHeight)
.AppendIf("-monitor", options.IsMonitorEnabled, options.Monitor.Value)
.Append("-screen-width", options.ScreenWidth)
.Append("-screen-height", options.ScreenHeight)
.Append("-monitor", options.Monitor.Value)
.ToString();
return new()

View File

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

View File

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

View File

@@ -2,9 +2,7 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.Options;
using Snap.Hutao.Core.Setting;
using Snap.Hutao.Web.Hutao;
using System.Text.RegularExpressions;
@@ -23,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>
@@ -58,43 +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 password, string? token)
/// <summary>
/// 登录
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="token">令牌</param>
public void LoginSucceed(string userName, string? token)
{
LocalSetting.Set(SettingKeys.PassportUserName, username);
LocalSetting.Set(SettingKeys.PassportPassword, password);
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()
{
LocalSetting.Set(SettingKeys.PassportUserName, string.Empty);
LocalSetting.Set(SettingKeys.PassportPassword, string.Empty);
UserName = null;
token = null;
IsLoggedIn = false;
ClearUserInfo();
}
/// <summary>
@@ -120,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;
}
@@ -129,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;
}
}

View File

@@ -32,20 +32,27 @@ internal sealed partial class HutaoUserService : IHutaoUserService, IHutaoUserSe
public async ValueTask InitializeInternalAsync(CancellationToken token = default)
{
string userName = LocalSetting.Get(SettingKeys.PassportUserName, string.Empty);
string password = LocalSetting.Get(SettingKeys.PassportPassword, string.Empty);
string passport = LocalSetting.Get(SettingKeys.PassportPassword, string.Empty);
if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(passport))
{
options.SkipLogin();
}
else
{
Web.Response.Response<string> response = await passportClient.LoginAsync(userName, password, token).ConfigureAwait(false);
Web.Response.Response<string> response = await passportClient.LoginAsync(userName, passport, token).ConfigureAwait(false);
if (response.IsOk())
{
if (await options.PostLoginSucceedAsync(passportClient, taskContext, userName, password, 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;
}
}

View File

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

View File

@@ -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>
@@ -79,7 +79,6 @@
<None Remove="Control\Theme\Color.xaml" />
<None Remove="Control\Theme\Converter.xaml" />
<None Remove="Control\Theme\CornerRadius.xaml" />
<None Remove="Control\Theme\FlyoutStyle.xaml" />
<None Remove="Control\Theme\FontStyle.xaml" />
<None Remove="Control\Theme\Glyph.xaml" />
<None Remove="Control\Theme\InfoBarOverride.xaml" />
@@ -101,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" />
@@ -146,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" />
@@ -168,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" />
@@ -232,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" />
@@ -260,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" />
@@ -269,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>
@@ -303,45 +296,20 @@
<ItemGroup>
<None Include="..\.editorconfig" Link=".editorconfig" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="Resource\Localization\SH.resx" />
</ItemGroup>
<ItemGroup>
<Page Update="Control\Theme\FlyoutStyle.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</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>
@@ -523,6 +491,12 @@
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="View\Page\HutaoPassportPage.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<!-- Pages -->
<ItemGroup>

View File

@@ -51,7 +51,6 @@ internal sealed partial class AnnouncementContentViewer : UserControl
/// </summary>
public AnnouncementContentViewer()
{
Environment.SetEnvironmentVariable("WEBVIEW2_DEFAULT_BACKGROUND_COLOR", "00000000");
InitializeComponent();
loadEventHandler = OnLoaded;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -21,6 +21,7 @@ internal sealed partial class GachaLogRefreshProgressDialog : ContentDialog
public GachaLogRefreshProgressDialog(IServiceProvider serviceProvider)
{
InitializeComponent();
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
}
/// <summary>

View File

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

View File

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

View File

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

View File

@@ -1,26 +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
InputScope="EmailSmtpAddress"
IsSpellCheckEnabled="False"
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>

View File

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

View File

@@ -1,44 +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
InputScope="EmailSmtpAddress"
IsSpellCheckEnabled="False"
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}, Mode=OneWay}"
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>

View File

@@ -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.RequestVerifyAsync(UserName, VerifyCodeRequestType.Registration).ConfigureAwait(false);
infoBarService.Information(response.GetLocalizationMessage());
}
}

View File

@@ -1,44 +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
InputScope="EmailSmtpAddress"
IsSpellCheckEnabled="False"
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}, Mode=OneWay}"
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>

View File

@@ -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.RequestVerifyAsync(UserName, VerifyCodeRequestType.ResetPassword).ConfigureAwait(false);
infoBarService.Information(response.GetLocalizationMessage());
}
}

View File

@@ -1,45 +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"
InputScope="EmailSmtpAddress"
IsSpellCheckEnabled="False"
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}, Mode=OneWay}"
Password="{x:Bind Password, Mode=TwoWay}"
PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordHint}"/>
</StackPanel>
</ContentDialog>

View File

@@ -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 HutaoPassportUnregisterDialog : ContentDialog
{
private readonly HomaPassportClient homaPassportClient;
private readonly IInfoBarService infoBarService;
private readonly ITaskContext taskContext;
public HutaoPassportUnregisterDialog(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.RequestVerifyAsync(UserName, VerifyCodeRequestType.CancelRegistration).ConfigureAwait(false);
infoBarService.Information(response.GetLocalizationMessage());
}
}

View File

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

View File

@@ -21,6 +21,7 @@ internal sealed partial class LaunchGamePackageConvertDialog : ContentDialog
public LaunchGamePackageConvertDialog(IServiceProvider serviceProvider)
{
InitializeComponent();
XamlRoot = serviceProvider.GetRequiredService<MainWindow>().Content.XamlRoot;
DataContext = this;
}

View File

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

View File

@@ -12,9 +12,11 @@
MaxWidth="640"
Margin="32,48,32,32"
VerticalAlignment="Bottom"
ItemContainerTransitions="{StaticResource RepositionThemeTransitions}"
ItemsSource="{x:Bind InfoBars}"
Visibility="{x:Bind VisibilityButton.IsChecked, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
Visibility="{Binding ElementName=VisibilityButton, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}">
<ItemsControl.Transitions>
<RepositionThemeTransition/>
</ItemsControl.Transitions>
<ItemsControl.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>

View File

@@ -17,7 +17,7 @@
<NavigationView
x:Name="NavView"
CompactPaneLength="48"
IsBackEnabled="{x:Bind ContentFrame.CanGoBack, Mode=OneWay}"
IsBackEnabled="{Binding ElementName=ContentFrame, Path=CanGoBack}"
IsPaneOpen="True"
OpenPaneLength="188"
PaneDisplayMode="Left"
@@ -86,10 +86,13 @@
<shv:UserView/>
</NavigationView.PaneFooter>
<Frame
x:Name="ContentFrame"
ContentTransitions="{StaticResource NavigationThemeTransitions}"
UseLayoutRounding="True"/>
<Frame x:Name="ContentFrame" UseLayoutRounding="True">
<Frame.ContentTransitions>
<TransitionCollection>
<NavigationThemeTransition/>
</TransitionCollection>
</Frame.ContentTransitions>
</Frame>
</NavigationView>
<shv:InfoBarView/>

View File

@@ -164,21 +164,6 @@
</Grid>
</Border>
</DataTemplate>
<Style
x:Key="AchievementGoalListViewItemStyle"
BasedOn="{StaticResource DefaultListViewItemStyle}"
TargetType="ListViewItem">
<Setter Property="Margin" Value="0,0,6,0"/>
</Style>
<Style
x:Key="AchievementListViewItemStyle"
BasedOn="{StaticResource DefaultListViewItemStyle}"
TargetType="ListViewItem">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0,4,8,0"/>
</Style>
</Page.Resources>
<mxi:Interaction.Behaviors>
@@ -297,7 +282,6 @@
PaneBackground="{x:Null}">
<SplitView.Pane>
<ListView
ItemContainerStyle="{StaticResource AchievementGoalListViewItemStyle}"
ItemTemplate="{StaticResource AchievementGoalListTemplate}"
ItemsSource="{Binding AchievementGoals}"
SelectedItem="{Binding SelectedAchievementGoal, Mode=TwoWay}"
@@ -305,6 +289,11 @@
<mxi:Interaction.Behaviors>
<shcb:SelectedItemInViewBehavior/>
</mxi:Interaction.Behaviors>
<ListView.ItemContainerStyle>
<Style BasedOn="{StaticResource DefaultListViewItemStyle}" TargetType="ListViewItem">
<Setter Property="Margin" Value="0,0,6,0"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</SplitView.Pane>
@@ -312,10 +301,16 @@
<ListView
Margin="8,0,0,0"
Padding="0,0,0,8"
ItemContainerStyle="{StaticResource AchievementListViewItemStyle}"
ItemTemplate="{StaticResource AchievementTemplate}"
ItemsSource="{Binding Achievements}"
SelectionMode="None"/>
SelectionMode="None">
<ListView.ItemContainerStyle>
<Style BasedOn="{StaticResource DefaultListViewItemStyle}" TargetType="ListViewItem">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0,4,8,0"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</SplitView.Content>
</SplitView>
</cwc:Case>

View File

@@ -29,126 +29,9 @@
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
<DataTemplate x:Key="AnnouncementTemplate">
<ItemContainer cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<Border Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<!-- Image Layer -->
<Border cw:UIElementExtensions.ClipToBounds="True" CornerRadius="{ThemeResource ControlCornerRadiusTop}">
<Border
x:Name="ImageZoomBorder"
VerticalAlignment="Top"
cw:VisualExtensions.NormalizedCenterPoint="0.5">
<cww:ConstrainedBox AspectRatio="1080:390" CornerRadius="{ThemeResource ControlCornerRadiusTop}">
<shci:CachedImage Source="{Binding Banner}" Stretch="UniformToFill"/>
</cww:ConstrainedBox>
<cwa:Explicit.Animations>
<cwa:AnimationSet x:Name="ImageZoomInAnimation">
<shca:ImageZoomInAnimation/>
</cwa:AnimationSet>
<cwa:AnimationSet x:Name="ImageZoomOutAnimation">
<shca:ImageZoomOutAnimation/>
</cwa:AnimationSet>
</cwa:Explicit.Animations>
</Border>
</Border>
<!-- Time Description -->
<Grid Grid.Row="0">
<Border
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Visibility="{Binding ShouldShowTimeDescription, Converter={StaticResource BoolToVisibilityConverter}}">
<ProgressBar
MinHeight="2"
VerticalAlignment="Bottom"
Background="Transparent"
CornerRadius="0"
Maximum="1"
Value="{Binding TimePercent, Mode=OneWay}"/>
</Border>
</Grid>
<!-- General Description -->
<Border Grid.Row="1">
<StackPanel Margin="4" VerticalAlignment="Bottom">
<TextBlock
Margin="4,6,0,0"
HorizontalAlignment="Stretch"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding Subtitle}"
TextTrimming="WordEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Margin="4,6,0,0"
Opacity="0.6"
Style="{StaticResource BodyTextBlockStyle}"
Text="{Binding Title}"
TextTrimming="WordEllipsis"
TextWrapping="NoWrap"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Margin="4,4,0,4"
FontSize="10"
Opacity="0.4"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding TimeFormatted}"
TextWrapping="NoWrap"/>
<TextBlock
Grid.Column="1"
Margin="4,4,4,4"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
FontSize="10"
Opacity="0.8"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding TimeDescription}"
Visibility="{Binding ShouldShowTimeDescription, Converter={StaticResource BoolToVisibilityConverter}}"/>
</Grid>
</StackPanel>
</Border>
</Grid>
<!-- 公告详情网页视图 -->
<FlyoutBase.AttachedFlyout>
<Flyout LightDismissOverlayMode="On" Placement="Full">
<Flyout.FlyoutPresenterStyle>
<Style BasedOn="{StaticResource DefaultFlyoutPresenterStyle}" TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="0"/>
<Setter Property="CornerRadius" Value="0"/>
<Setter Property="MaxWidth" Value="640"/>
</Style>
</Flyout.FlyoutPresenterStyle>
<shvco:AnnouncementContentViewer Announcement="{Binding}"/>
</Flyout>
</FlyoutBase.AttachedFlyout>
<mxi:Interaction.Behaviors>
<mxic:EventTriggerBehavior EventName="Tapped">
<shcb:OpenAttachedFlyoutAction/>
</mxic:EventTriggerBehavior>
<mxic:EventTriggerBehavior EventName="PointerEntered">
<shcb:StartAnimationActionNoThrow Animation="{Binding ElementName=ImageZoomInAnimation}" TargetObject="{Binding ElementName=ImageZoomBorder}"/>
</mxic:EventTriggerBehavior>
<mxic:EventTriggerBehavior EventName="PointerExited">
<shcb:StartAnimationActionNoThrow Animation="{Binding ElementName=ImageZoomOutAnimation}" TargetObject="{Binding ElementName=ImageZoomBorder}"/>
</mxic:EventTriggerBehavior>
</mxi:Interaction.Behaviors>
</Border>
</ItemContainer>
</DataTemplate>
<DataTemplate x:Key="AnnouncementPivotItemContentTemplate">
<ItemsRepeater
Margin="16,16,16,16"
HorizontalAlignment="Stretch"
ItemTemplate="{StaticResource AnnouncementTemplate}"
ItemsSource="{Binding List}">
<ItemsRepeater.Layout>
<UniformGridLayout
@@ -158,6 +41,118 @@
MinItemWidth="300"
MinRowSpacing="12"/>
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<ItemContainer cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<Border Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<!-- Image Layer -->
<Border cw:UIElementExtensions.ClipToBounds="True" CornerRadius="{ThemeResource ControlCornerRadius}">
<Border VerticalAlignment="Top" cw:VisualExtensions.NormalizedCenterPoint="0.5">
<cww:ConstrainedBox AspectRatio="1080:390" CornerRadius="{ThemeResource ControlCornerRadius}">
<shci:CachedImage Source="{Binding Banner}" Stretch="UniformToFill"/>
</cww:ConstrainedBox>
<cwa:Explicit.Animations>
<cwa:AnimationSet x:Name="ImageZoomInAnimation">
<shca:ImageZoomInAnimation/>
</cwa:AnimationSet>
<cwa:AnimationSet x:Name="ImageZoomOutAnimation">
<shca:ImageZoomOutAnimation/>
</cwa:AnimationSet>
</cwa:Explicit.Animations>
</Border>
</Border>
<!-- Time Description -->
<Grid Grid.Row="0">
<Border
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Visibility="{Binding ShouldShowTimeDescription, Converter={StaticResource BoolToVisibilityConverter}}">
<ProgressBar
MinHeight="2"
VerticalAlignment="Bottom"
Background="Transparent"
CornerRadius="0"
Maximum="1"
Value="{Binding TimePercent, Mode=OneWay}"/>
</Border>
</Grid>
<!-- General Description -->
<Border Grid.Row="1">
<StackPanel Margin="4" VerticalAlignment="Bottom">
<TextBlock
Margin="4,6,0,0"
HorizontalAlignment="Stretch"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding Subtitle}"
TextTrimming="WordEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Margin="4,6,0,0"
Opacity="0.6"
Style="{StaticResource BodyTextBlockStyle}"
Text="{Binding Title}"
TextTrimming="WordEllipsis"
TextWrapping="NoWrap"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Margin="4,4,0,4"
FontSize="10"
Opacity="0.4"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding TimeFormatted}"
TextWrapping="NoWrap"/>
<TextBlock
Grid.Column="1"
Margin="4,4,4,4"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
FontSize="10"
Opacity="0.8"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding TimeDescription}"
Visibility="{Binding ShouldShowTimeDescription, Converter={StaticResource BoolToVisibilityConverter}}"/>
</Grid>
</StackPanel>
</Border>
</Grid>
<FlyoutBase.AttachedFlyout>
<Flyout LightDismissOverlayMode="On" Placement="Full">
<Flyout.FlyoutPresenterStyle>
<Style BasedOn="{StaticResource DefaultFlyoutPresenterStyle}" TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="0"/>
<Setter Property="CornerRadius" Value="0"/>
<Setter Property="MaxWidth" Value="640"/>
</Style>
</Flyout.FlyoutPresenterStyle>
<shvco:AnnouncementContentViewer Announcement="{Binding}"/>
</Flyout>
</FlyoutBase.AttachedFlyout>
<mxi:Interaction.Behaviors>
<mxic:EventTriggerBehavior EventName="Tapped">
<shcb:OpenAttachedFlyoutAction/>
</mxic:EventTriggerBehavior>
<mxic:EventTriggerBehavior EventName="PointerEntered">
<cwb:StartAnimationAction Animation="{Binding ElementName=ImageZoomInAnimation}"/>
</mxic:EventTriggerBehavior>
<mxic:EventTriggerBehavior EventName="PointerExited">
<cwb:StartAnimationAction Animation="{Binding ElementName=ImageZoomOutAnimation}"/>
</mxic:EventTriggerBehavior>
</mxi:Interaction.Behaviors>
</Border>
</ItemContainer>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</DataTemplate>
@@ -189,6 +184,7 @@
</ItemContainer.Resources>
</ItemContainer>
</DataTemplate>
</shc:ScopedPage.Resources>
<Grid>
@@ -227,11 +223,11 @@
<Pivot Style="{StaticResource DefaultPivotStyle}">
<PivotItem
Content="{Binding Announcement.List[0]}"
ContentTemplate="{StaticResource AnnouncementPivotItemContentTemplate}"
ContentTemplate="{StaticResource AnnouncementTemplate}"
Header="{shcm:ResourceString Name=ViewPageAnnouncementActivity}"/>
<PivotItem
Content="{Binding Announcement.List[1]}"
ContentTemplate="{StaticResource AnnouncementPivotItemContentTemplate}"
ContentTemplate="{StaticResource AnnouncementTemplate}"
Header="{shcm:ResourceString Name=ViewPageAnnouncementGame}"/>
</Pivot>
</StackPanel>

View File

@@ -58,382 +58,6 @@
GridValue="{x:Bind GridImageExportPanel}"
ListValue="{x:Bind ListImageExportPanel}"/>
<DataTemplate x:Key="AvatarGridViewSkillTemplate">
<Border
Width="40"
Margin="0,0,6,0"
Style="{StaticResource BorderCardStyle}">
<StackPanel>
<shci:MonoChrome
Width="32"
Height="32"
Margin="4,4,4,0"
HorizontalAlignment="Center"
EnableLazyLoading="False"
Source="{Binding Icon}"/>
<TextBlock
Margin="0,0,0,4"
HorizontalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding Level}"/>
</StackPanel>
</Border>
</DataTemplate>
<DataTemplate x:Key="AvatarGridViewTemplate">
<Grid ColumnSpacing="6" Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border
Grid.RowSpan="2"
Grid.ColumnSpan="2"
CornerRadius="{ThemeResource ControlCornerRadius}">
<shci:CachedImage
MaxWidth="145"
HorizontalAlignment="Right"
Opacity="0.5"
Source="{Binding NameCard}"
Stretch="UniformToFill"/>
</Border>
<shvcont:BottomTextControl
Grid.Row="0"
Grid.Column="0"
Margin="6,6,0,6"
Text="{Binding Level}">
<Grid>
<shvcont:ItemIcon
Width="61.5"
Height="61.5"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding ActivatedConstellationCount}"/>
</Border>
</Grid>
</shvcont:BottomTextControl>
<shvcont:BottomTextControl
Grid.Row="0"
Grid.Column="1"
Margin="0,6,6,6"
Text="{Binding Weapon.Level}">
<Grid>
<shvcont:ItemIcon
Width="61.5"
Height="61.5"
Icon="{Binding Weapon.Icon}"
Quality="{Binding Weapon.Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding Weapon.AffixLevelNumber}"/>
</Border>
</Grid>
</shvcont:BottomTextControl>
<ItemsControl
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="6,0,0,6"
VerticalAlignment="Bottom"
ItemTemplate="{StaticResource AvatarGridViewSkillTemplate}"
ItemsPanel="{StaticResource HorizontalStackPanelSpacing0Template}"
ItemsSource="{Binding Skills}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="AvatarListViewTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<shci:CachedImage
Grid.Column="0"
Width="48"
Height="48"
Margin="0,0,12,12"
Source="{Binding SideIcon, Mode=OneWay}"/>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock
Margin="12,0,0,0"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Margin="12,0,0,0"
Opacity="0.7"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding Level}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
<StackPanel
Grid.Column="2"
VerticalAlignment="Center"
Opacity="0.7"
Visibility="{Binding ElementName=RefreshTimeToggle, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<TextBlock
HorizontalAlignment="Right"
FontSize="11"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding ShowcaseRefreshTimeFormat}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
HorizontalAlignment="Right"
FontSize="11"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding GameRecordRefreshTimeFormat}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
HorizontalAlignment="Right"
FontSize="11"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding CalculatorRefreshTimeFormat}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate x:Key="AvatarConstellationTemplate">
<Button
Margin="0,0,2,0"
Padding="2"
Background="Transparent"
BorderBrush="{x:Null}">
<Button.Content>
<Grid>
<shci:CachedImage
Width="36"
Height="36"
Opacity="{Binding IsActivated, Converter={StaticResource BoolToOpacityConverter}}"
Source="{Binding Icon}"/>
<Image
Width="16"
Height="16"
Source="ms-appx:///Resource/Icon/UI_Icon_Locked.png"
Visibility="{Binding IsActivated, Converter={StaticResource BoolToVisibilityRevertConverter}}"/>
</Grid>
</Button.Content>
<Button.Flyout>
<Flyout Placement="Bottom">
<shct:DescriptionTextBlock MaxWidth="320" Description="{Binding Description}">
<shct:DescriptionTextBlock.Resources>
<Style BasedOn="{StaticResource BodyTextBlockStyle}" TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</shct:DescriptionTextBlock.Resources>
</shct:DescriptionTextBlock>
</Flyout>
</Button.Flyout>
</Button>
</DataTemplate>
<DataTemplate x:Key="AvatarPropertyTemplate">
<Grid Padding="16,8" Background="{Binding Background, Mode=OneWay}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="108"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<shci:MonoChrome
Width="16"
Height="16"
Source="{Binding Icon}"/>
<TextBlock
Grid.Row="0"
Grid.Column="1"
Margin="16,0,0,0"
HorizontalAlignment="Left"
Text="{Binding Name}"/>
<TextBlock
Grid.Row="0"
Grid.Column="2"
HorizontalAlignment="Right"
Text="{Binding Value}"/>
<TextBlock
Grid.Row="0"
Grid.Column="3"
Margin="8,0,0,0"
HorizontalAlignment="Left"
Foreground="{StaticResource AvatarPropertyAddValueColorBrush}"
Text="{Binding AddValue}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="AvatarReliquarySubPropertyTemplate">
<Grid ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock Grid.Column="1" Text="{Binding Value}"/>
<Grid Grid.Column="2" Opacity="1">
<Ellipse
Width="16"
Height="16"
Margin="0,0,0,0"
Opacity="0.8"
StrokeThickness="1">
<Ellipse.Stroke>
<SolidColorBrush Color="{Binding EnhancedCount, Converter={ThemeResource CountToGradientColorConverter}}"/>
</Ellipse.Stroke>
</Ellipse>
<TextBlock
Grid.Column="2"
Margin="0,0,0,1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="{ThemeResource InfoBadgeValueFontSize}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding EnhancedCount}">
<TextBlock.Foreground>
<SolidColorBrush Color="{Binding EnhancedCount, Converter={ThemeResource CountToGradientColorConverter}}"/>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</Grid>
</DataTemplate>
<DataTemplate x:Key="AvatarReliquarySparseSubPropertyTemplate">
<Grid Opacity="{Binding Opacity}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock Grid.Column="1" Text="{Binding Value}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="AvatarReliquaryTemplate">
<Expander
Margin="0,0,0,16"
Padding="16"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch">
<Expander.Header>
<Grid Margin="0,8,8,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<shvcont:ItemIcon
Grid.Column="0"
Width="32"
Height="32"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Grid
Grid.Column="1"
Margin="16,0,0,0"
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<!-- 主属性 -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding MainProperty.Name}"
TextTrimming="CharacterEllipsis"/>
<TextBlock Grid.Column="1" Text="{Binding MainProperty.Value}"/>
</Grid>
<!-- 评分 -->
<Grid Margin="0,8,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageAvatarPropertyScore}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock Grid.Column="1" Text="{Binding ScoreFormatted}"/>
</Grid>
</StackPanel>
<AppBarSeparator Grid.Column="1"/>
<ItemsControl
Grid.Column="2"
ItemTemplate="{StaticResource AvatarReliquarySubPropertyTemplate}"
ItemsSource="{Binding ComposedSubProperties}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<cwcont:UniformGrid
ColumnSpacing="16"
Columns="2"
RowSpacing="8"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</Grid>
</Expander.Header>
<StackPanel>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageAvatarPropertyPrimaryProperties}"/>
<ItemsControl
ItemTemplate="{StaticResource AvatarReliquarySparseSubPropertyTemplate}"
ItemsPanel="{StaticResource UniformGridColumns5Spacing8Template}"
ItemsSource="{Binding PrimarySubProperties}"/>
<TextBlock
Margin="0,16,0,0"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageAvatarPropertySecondaryProperties}"/>
<ItemsControl
ItemTemplate="{StaticResource AvatarReliquarySparseSubPropertyTemplate}"
ItemsPanel="{StaticResource UniformGridColumns5Spacing8Template}"
ItemsSource="{Binding SecondarySubProperties}"/>
</StackPanel>
</Expander>
</DataTemplate>
</ResourceDictionary>
</Page.Resources>
@@ -486,10 +110,12 @@
</AppBarButton>
</CommandBar>
<cwcont:SwitchPresenter
Grid.Row="1"
ContentTransitions="{ThemeResource ContentThemeTransitions}"
Value="{Binding ElementName=ItemsPanelSelector, Path=Current, Mode=OneWay}">
<cwcont:SwitchPresenter Grid.Row="1" Value="{Binding ElementName=ItemsPanelSelector, Path=Current, Mode=OneWay}">
<cwcont:SwitchPresenter.ContentTransitions>
<TransitionCollection>
<ContentThemeTransition/>
</TransitionCollection>
</cwcont:SwitchPresenter.ContentTransitions>
<cwcont:Case Value="Grid">
<ScrollViewer>
<StackPanel x:Name="GridImageExportPanel" Background="Transparent">
@@ -497,9 +123,117 @@
Margin="16,16,4,-8"
cwa:ItemsReorderAnimation.Duration="0:0:0.1"
ItemContainerStyle="{StaticResource LargeGridViewItemStyle}"
ItemTemplate="{StaticResource AvatarGridViewTemplate}"
ItemsSource="{Binding Summary.Avatars}"
SelectedItem="{Binding SelectedAvatar, Mode=TwoWay}"/>
SelectedItem="{Binding SelectedAvatar, Mode=TwoWay}">
<GridView.ItemTemplate>
<DataTemplate>
<Border Style="{StaticResource BorderCardStyle}">
<Grid ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border
Grid.RowSpan="2"
Grid.ColumnSpan="2"
CornerRadius="{ThemeResource ControlCornerRadius}">
<shci:CachedImage
MaxWidth="145"
HorizontalAlignment="Right"
Opacity="0.5"
Source="{Binding NameCard}"
Stretch="UniformToFill"/>
</Border>
<shvcont:BottomTextControl
Grid.Row="0"
Grid.Column="0"
Margin="6,6,0,6"
Text="{Binding Level}">
<Grid>
<shvcont:ItemIcon
Width="61.5"
Height="61.5"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding ActivatedConstellationCount}"/>
</Border>
</Grid>
</shvcont:BottomTextControl>
<shvcont:BottomTextControl
Grid.Row="0"
Grid.Column="1"
Margin="0,6,6,6"
Text="{Binding Weapon.Level}">
<Grid>
<shvcont:ItemIcon
Width="61.5"
Height="61.5"
Icon="{Binding Weapon.Icon}"
Quality="{Binding Weapon.Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding Weapon.AffixLevelNumber}"/>
</Border>
</Grid>
</shvcont:BottomTextControl>
<ItemsControl
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="6,0,0,6"
VerticalAlignment="Bottom"
ItemsPanel="{StaticResource HorizontalStackPanelTemplate}"
ItemsSource="{Binding Skills}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border
Width="40"
Margin="0,0,6,0"
Style="{StaticResource BorderCardStyle}">
<StackPanel>
<shci:MonoChrome
Width="32"
Height="32"
Margin="4,4,4,0"
HorizontalAlignment="Center"
EnableLazyLoading="False"
Source="{Binding Icon}"/>
<TextBlock
Margin="0,0,0,4"
HorizontalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding Level}"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</StackPanel>
</ScrollViewer>
</cwcont:Case>
@@ -511,10 +245,66 @@
OpenPaneLength="{StaticResource CompatSplitViewOpenPaneLength2}"
PaneBackground="Transparent">
<SplitView.Pane>
<ListView
ItemTemplate="{StaticResource AvatarListViewTemplate}"
ItemsSource="{Binding Summary.Avatars}"
SelectedItem="{Binding SelectedAvatar, Mode=TwoWay}"/>
<ListView ItemsSource="{Binding Summary.Avatars}" SelectedItem="{Binding SelectedAvatar, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<shci:CachedImage
Grid.Column="0"
Width="48"
Height="48"
Margin="0,0,12,12"
Source="{Binding SideIcon, Mode=OneWay}"/>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock
Margin="12,0,0,0"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Margin="12,0,0,0"
Opacity="0.7"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding Level}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
<StackPanel
Grid.Column="2"
VerticalAlignment="Center"
Opacity="0.7"
Visibility="{Binding ElementName=RefreshTimeToggle, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<TextBlock
HorizontalAlignment="Right"
FontSize="11"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding ShowcaseRefreshTimeFormat}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
HorizontalAlignment="Right"
FontSize="11"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding GameRecordRefreshTimeFormat}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
HorizontalAlignment="Right"
FontSize="11"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding CalculatorRefreshTimeFormat}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</SplitView.Pane>
<SplitView.Content>
<ScrollViewer>
@@ -659,8 +449,12 @@
Grid.Row="1"
Grid.Column="0"
Margin="16"
ItemsPanel="{StaticResource HorizontalStackPanelSpacing0Template}"
ItemsSource="{Binding SelectedAvatar.Constellations}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
@@ -729,8 +523,70 @@
Grid.Column="1"
Margin="16"
VerticalAlignment="Bottom"
ItemTemplate="{StaticResource AvatarConstellationTemplate}"
ItemsSource="{Binding SelectedAvatar.Skills}"/>
ItemsSource="{Binding SelectedAvatar.Skills}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Margin="0,2,0,0"
Padding="4"
Background="Transparent"
BorderBrush="{x:Null}">
<Button.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="48"/>
</Grid.ColumnDefinitions>
<shci:CachedImage
Grid.Column="0"
Width="36"
Height="36"
Source="{Binding Icon}"/>
<TextBlock
Grid.Column="1"
Margin="6,0,0,2"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="#FFFFFFFF"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Info.Level}"/>
</Grid>
</Button.Content>
<Button.Flyout>
<Flyout Placement="Left">
<StackPanel MaxWidth="320">
<StackPanel.Resources>
<Thickness x:Key="SettingsCardPadding">16</Thickness>
<x:Double x:Key="SettingsCardWrapThreshold">0</x:Double>
<x:Double x:Key="SettingsCardWrapNoIconThreshold">0</x:Double>
<x:Double x:Key="SettingsCardMinHeight">0</x:Double>
</StackPanel.Resources>
<shct:DescriptionTextBlock Description="{Binding Description}">
<shct:DescriptionTextBlock.Resources>
<Style BasedOn="{StaticResource BodyTextBlockStyle}" TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</shct:DescriptionTextBlock.Resources>
</shct:DescriptionTextBlock>
<ItemsControl Margin="0,12,0,0" ItemsSource="{Binding Info.Parameters}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<cwcont:SettingsCard
Margin="0,2,0,0"
Padding="12,0"
Header="{Binding Description}">
<TextBlock Margin="0,8" Text="{Binding Parameter}"/>
</cwcont:SettingsCard>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Border>
@@ -742,19 +598,221 @@
HorizontalContentAlignment="Stretch"
Background="{x:Null}"
Header="{shcm:ResourceString Name=ViewPageAvatarPropertyHeader}">
<Border Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}" CornerRadius="{ThemeResource ControlCornerRadiusBottom}">
<Border Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}" CornerRadius="0,0,4,4">
<shcca:AlternatingItemsControl
Margin="0,0,0,-2"
ItemAlternateBackground="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
ItemTemplate="{StaticResource AvatarPropertyTemplate}"
ItemsSource="{Binding SelectedAvatar.Properties}"/>
ItemsSource="{Binding SelectedAvatar.Properties}">
<shcca:AlternatingItemsControl.ItemTemplate>
<DataTemplate>
<Grid Padding="16,8" Background="{Binding Background, Mode=OneWay}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="108"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<shci:MonoChrome
Width="16"
Height="16"
Source="{Binding Icon}"/>
<TextBlock
Grid.Row="0"
Grid.Column="1"
Margin="16,0,0,0"
HorizontalAlignment="Left"
Text="{Binding Name}"/>
<TextBlock
Grid.Row="0"
Grid.Column="2"
HorizontalAlignment="Right"
Text="{Binding Value}"/>
<TextBlock
Grid.Row="0"
Grid.Column="3"
Margin="8,0,0,0"
HorizontalAlignment="Left"
Foreground="{StaticResource AvatarPropertyAddValueColorBrush}"
Text="{Binding AddValue}"/>
</Grid>
</DataTemplate>
</shcca:AlternatingItemsControl.ItemTemplate>
</shcca:AlternatingItemsControl>
</Border>
</Expander>
<!-- 圣遗物 -->
<ItemsControl
Margin="16,16,16,0"
ItemTemplate="{StaticResource AvatarReliquaryTemplate}"
ItemsSource="{Binding SelectedAvatar.Reliquaries}"/>
<ItemsControl Margin="16,16,16,0" ItemsSource="{Binding SelectedAvatar.Reliquaries}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander
Margin="0,0,0,16"
Padding="16"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch">
<Expander.Header>
<Grid Margin="0,8,8,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<shvcont:ItemIcon
Grid.Column="0"
Width="32"
Height="32"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Grid
Grid.Column="1"
Margin="16,0,0,0"
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<!-- 主属性 -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding MainProperty.Name}"
TextTrimming="CharacterEllipsis"/>
<TextBlock Grid.Column="1" Text="{Binding MainProperty.Value}"/>
</Grid>
<!-- 评分 -->
<Grid Margin="0,8,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageAvatarPropertyScore}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock Grid.Column="1" Text="{Binding ScoreFormatted}"/>
</Grid>
</StackPanel>
<AppBarSeparator Grid.Column="1"/>
<ItemsControl Grid.Column="2" ItemsSource="{Binding ComposedSubProperties}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<cwcont:UniformGrid
ColumnSpacing="16"
Columns="2"
RowSpacing="8"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock Grid.Column="1" Text="{Binding Value}"/>
<Grid Grid.Column="2" Opacity="1">
<Ellipse
Width="16"
Height="16"
Margin="0,0,0,0"
Opacity="0.8"
StrokeThickness="1">
<Ellipse.Stroke>
<SolidColorBrush Color="{Binding EnhancedCount, Converter={ThemeResource CountToGradientColorConverter}}"/>
</Ellipse.Stroke>
</Ellipse>
<TextBlock
Grid.Column="2"
Margin="0,0,0,1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="{ThemeResource InfoBadgeValueFontSize}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding EnhancedCount}">
<TextBlock.Foreground>
<SolidColorBrush Color="{Binding EnhancedCount, Converter={ThemeResource CountToGradientColorConverter}}"/>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Grid>
</Expander.Header>
<StackPanel>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageAvatarPropertyPrimaryProperties}"/>
<ItemsControl ItemsSource="{Binding PrimarySubProperties}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<cwcont:UniformGrid ColumnSpacing="8" Columns="5"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Opacity="{Binding Opacity}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock Grid.Column="1" Text="{Binding Value}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock
Margin="0,16,0,0"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageAvatarPropertySecondaryProperties}"/>
<ItemsControl ItemsSource="{Binding SecondarySubProperties}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<cwcont:UniformGrid ColumnSpacing="8" Columns="5"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Opacity="{Binding Opacity}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock Grid.Column="1" Text="{Binding Value}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</SplitView.Content>

View File

@@ -20,219 +20,27 @@
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<cwconv:BoolToObjectConverter x:Key="BoolToBrushSelector" FalseValue="{StaticResource ControlFillColorTransparentBrush}">
<cwconv:BoolToObjectConverter.TrueValue>
<SolidColorBrush Color="#206A890A"/>
</cwconv:BoolToObjectConverter.TrueValue>
</cwconv:BoolToObjectConverter>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<cwconv:BoolToObjectConverter x:Key="BoolToBrushSelector" FalseValue="{StaticResource ControlFillColorTransparentBrush}">
<cwconv:BoolToObjectConverter.TrueValue>
<SolidColorBrush Color="#20A5D610"/>
</cwconv:BoolToObjectConverter.TrueValue>
</cwconv:BoolToObjectConverter>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
<cwconv:BoolToObjectConverter x:Key="BoolToOpacityConverter">
<cwconv:BoolToObjectConverter.TrueValue>
<x:Double>0.4</x:Double>
</cwconv:BoolToObjectConverter.TrueValue>
<cwconv:BoolToObjectConverter.FalseValue>
<x:Double>1</x:Double>
</cwconv:BoolToObjectConverter.FalseValue>
</cwconv:BoolToObjectConverter>
<cwconv:BoolToObjectConverter x:Key="BoolToOpacityConverter">
<cwconv:BoolToObjectConverter.TrueValue>
<x:Double>0.4</x:Double>
</cwconv:BoolToObjectConverter.TrueValue>
<cwconv:BoolToObjectConverter.FalseValue>
<x:Double>1</x:Double>
</cwconv:BoolToObjectConverter.FalseValue>
</cwconv:BoolToObjectConverter>
<cwconv:BoolToObjectConverter
x:Key="BoolToStyleSelector"
FalseValue="{StaticResource BodyTextBlockStyle}"
TrueValue="{StaticResource BaseTextBlockStyle}"/>
<cwconv:BoolToObjectConverter
x:Key="BoolToStyleSelector"
FalseValue="{StaticResource BodyTextBlockStyle}"
TrueValue="{StaticResource BaseTextBlockStyle}"/>
<DataTemplate x:Key="CultivateEntryItemTemplate">
<Grid Margin="0,4,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid>
<shvco:ItemIcon
Width="32"
Height="32"
Icon="{Binding Inner.Icon, Converter={StaticResource ItemIconConverter}}"
Opacity="{Binding IsFinished, Converter={StaticResource BoolToOpacityConverter}}"
Quality="{Binding Inner.RankLevel}"/>
<FontIcon
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="24"
Glyph="&#xE73E;"
Visibility="{Binding IsFinished, Converter={StaticResource BoolToVisibilityConverter}}"/>
</Grid>
<Button
Grid.Column="1"
Height="32"
Margin="6,0,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Background="{Binding IsToday, Converter={ThemeResource BoolToBrushSelector}}"
Command="{Binding Path=DataContext.FinishStateCommand, Source={StaticResource BindingProxy}}"
CommandParameter="{Binding}"
Style="{StaticResource ButtonRevealStyle}">
<Grid Opacity="{Binding IsFinished, Converter={StaticResource BoolToOpacityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Margin="0,0,0,0"
VerticalAlignment="Center"
Style="{Binding IsToday, Converter={StaticResource BoolToStyleSelector}}"
Text="{Binding Inner.Name}"
TextTrimming="CharacterEllipsis"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Style="{Binding IsToday, Converter={StaticResource BoolToStyleSelector}}"
Text="{Binding Entity.Count}"/>
</Grid>
</Button>
</Grid>
</DataTemplate>
<DataTemplate x:Key="CultivateEntryTemplate">
<ItemContainer Margin="0,0,0,16">
<ItemContainer.Resources>
<SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ItemContainerPressedBackground" Color="Transparent"/>
</ItemContainer.Resources>
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<shvco:ItemIcon
Width="48"
Height="48"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<TextBlock
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center"
Text="{Binding Name}"/>
<StackPanel Grid.Column="2" Orientation="Horizontal">
<Button
Width="48"
Height="48"
Margin="8,0,0,0"
Background="Transparent"
Command="{Binding Path=DataContext.RemoveEntryCommand, Source={StaticResource BindingProxy}}"
CommandParameter="{Binding}"
Content="&#xE74D;"
FontFamily="{StaticResource SymbolThemeFontFamily}"
Style="{StaticResource ButtonRevealStyle}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageCultivationRemoveEntry}"/>
</StackPanel>
</Grid>
<MenuFlyoutSeparator Grid.Row="1"/>
<ScrollViewer
Grid.Row="2"
Height="296"
Margin="0,2,0,0">
<ItemsControl
Margin="8,0,8,8"
ItemTemplate="{StaticResource CultivateEntryItemTemplate}"
ItemsSource="{Binding Items}"/>
</ScrollViewer>
</Grid>
</ItemContainer>
</DataTemplate>
<DataTemplate x:Key="StatisticsItemTemplate">
<ItemContainer Margin="0,0,0,16">
<ItemContainer.Resources>
<SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ItemContainerPressedBackground" Color="Transparent"/>
</ItemContainer.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<shvco:ItemIcon
Grid.Column="0"
Width="32"
Height="32"
Icon="{Binding Inner.Icon, Converter={StaticResource ItemIconConverter}}"
Quality="{Binding Inner.RankLevel}"/>
<TextBlock
Grid.Column="1"
Margin="16,0,0,0"
VerticalAlignment="Center"
Text="{Binding Inner.Name}"
TextTrimming="CharacterEllipsis"/>
<TextBlock
Grid.Column="2"
Margin="16,0,4,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Text="{Binding CountFormatted}"/>
</Grid>
</ItemContainer>
</DataTemplate>
<DataTemplate x:Key="InventoryItemTemplate">
<ItemContainer>
<ItemContainer.Resources>
<SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ItemContainerPressedBackground" Color="Transparent"/>
</ItemContainer.Resources>
<Button
Padding="0"
Background="Transparent"
BorderBrush="{x:Null}"
BorderThickness="0">
<shvco:BottomTextControl Text="{Binding Count, Mode=OneWay}">
<shvco:ItemIcon Icon="{Binding Inner.Icon, Converter={StaticResource ItemIconConverter}}" Quality="{Binding Inner.RankLevel}"/>
</shvco:BottomTextControl>
<Button.Flyout>
<Flyout>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Style="{StaticResource BaseTextBlockStyle}" Text="{Binding Inner.Name}"/>
<NumberBox
Grid.Row="1"
MinWidth="160"
Margin="0,16,0,0"
Maximum="4294967295"
Minimum="0"
Value="{Binding Count, Mode=TwoWay}"/>
</Grid>
</Flyout>
</Button.Flyout>
</Button>
</ItemContainer>
</DataTemplate>
</ResourceDictionary>
<cwconv:BoolToObjectConverter x:Key="BoolToBrushSelector" FalseValue="{StaticResource ControlFillColorTransparentBrush}">
<cwconv:BoolToObjectConverter.TrueValue>
<SolidColorBrush Color="#20A5D610"/>
</cwconv:BoolToObjectConverter.TrueValue>
</cwconv:BoolToObjectConverter>
</Page.Resources>
<mxi:Interaction.Behaviors>
@@ -277,7 +85,6 @@
<ItemsView
Padding="16,0"
IsItemInvokedEnabled="False"
ItemTemplate="{StaticResource CultivateEntryTemplate}"
ItemsSource="{Binding CultivateEntries}"
SelectionMode="None">
<ItemsView.Layout>
@@ -288,13 +95,158 @@
MinItemWidth="300"
MinRowSpacing="-4"/>
</ItemsView.Layout>
<ItemsView.ItemTemplate>
<DataTemplate>
<ItemContainer Margin="0,0,0,16">
<ItemContainer.Resources>
<SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ItemContainerPressedBackground" Color="Transparent"/>
</ItemContainer.Resources>
<Border Style="{StaticResource BorderCardStyle}">
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<shvco:ItemIcon
Width="48"
Height="48"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<TextBlock
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center"
Text="{Binding Name}"/>
<StackPanel
x:Name="ButtonPanel"
Grid.Column="2"
Orientation="Horizontal"
Visibility="Collapsed">
<Button
Width="48"
Height="48"
Margin="8,0,0,0"
Background="Transparent"
Command="{Binding Path=DataContext.RemoveEntryCommand, Source={StaticResource BindingProxy}}"
CommandParameter="{Binding}"
Content="&#xE74D;"
FontFamily="{StaticResource SymbolThemeFontFamily}"
Style="{StaticResource ButtonRevealStyle}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageCultivationRemoveEntry}"/>
</StackPanel>
</Grid>
<MenuFlyoutSeparator Grid.Row="1"/>
<ScrollViewer
Grid.Row="2"
Height="296"
Margin="0,2,0,0">
<ItemsControl Margin="8,0,8,8" ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,4,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid>
<shvco:ItemIcon
Width="32"
Height="32"
Icon="{Binding Inner.Icon, Converter={StaticResource ItemIconConverter}}"
Opacity="{Binding IsFinished, Converter={StaticResource BoolToOpacityConverter}}"
Quality="{Binding Inner.RankLevel}"/>
<FontIcon
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="24"
Glyph="&#xE73E;"
Visibility="{Binding IsFinished, Converter={StaticResource BoolToVisibilityConverter}}"/>
</Grid>
<Button
Grid.Column="1"
Height="32"
Margin="6,0,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Background="{Binding IsToday, Converter={StaticResource BoolToBrushSelector}}"
Command="{Binding Path=DataContext.FinishStateCommand, Source={StaticResource BindingProxy}}"
CommandParameter="{Binding}"
Style="{StaticResource ButtonRevealStyle}">
<Grid Opacity="{Binding IsFinished, Converter={StaticResource BoolToOpacityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Margin="0,0,0,0"
VerticalAlignment="Center"
Style="{Binding IsToday, Converter={StaticResource BoolToStyleSelector}}"
Text="{Binding Inner.Name}"
TextTrimming="CharacterEllipsis"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Style="{Binding IsToday, Converter={StaticResource BoolToStyleSelector}}"
Text="{Binding Entity.Count}"/>
</Grid>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<Grid.Resources>
<Storyboard x:Name="ButtonPanelVisibleStoryboard">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="ButtonPanelCollapsedStoryboard">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<mxi:Interaction.Behaviors>
<mxic:EventTriggerBehavior EventName="PointerEntered">
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelVisibleStoryboard}"/>
</mxic:EventTriggerBehavior>
<mxic:EventTriggerBehavior EventName="PointerExited">
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelCollapsedStoryboard}"/>
</mxic:EventTriggerBehavior>
</mxi:Interaction.Behaviors>
</Grid>
</Border>
</ItemContainer>
</DataTemplate>
</ItemsView.ItemTemplate>
</ItemsView>
</PivotItem>
<PivotItem Header="{shcm:ResourceString Name=ViewPageCultivationMaterialStatistics}">
<ItemsView
Padding="16,0"
IsItemInvokedEnabled="False"
ItemTemplate="{StaticResource StatisticsItemTemplate}"
ItemsSource="{Binding StatisticsItems}"
SelectionMode="None">
<ItemsView.Layout>
@@ -305,6 +257,42 @@
MinItemWidth="300"
MinRowSpacing="-4"/>
</ItemsView.Layout>
<ItemsView.ItemTemplate>
<DataTemplate>
<ItemContainer Margin="0,0,0,16">
<ItemContainer.Resources>
<SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ItemContainerPressedBackground" Color="Transparent"/>
</ItemContainer.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<shvco:ItemIcon
Grid.Column="0"
Width="32"
Height="32"
Icon="{Binding Inner.Icon, Converter={StaticResource ItemIconConverter}}"
Quality="{Binding Inner.RankLevel}"/>
<TextBlock
Grid.Column="1"
Margin="16,0,0,0"
VerticalAlignment="Center"
Text="{Binding Inner.Name}"
TextTrimming="CharacterEllipsis"/>
<TextBlock
Grid.Column="2"
Margin="16,0,4,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Text="{Binding CountFormatted}"/>
</Grid>
</ItemContainer>
</DataTemplate>
</ItemsView.ItemTemplate>
</ItemsView>
</PivotItem>
</Pivot>
@@ -348,15 +336,51 @@
</PivotItem>
<PivotItem Header="{shcm:ResourceString Name=ViewPageCultivationInventoryItem}">
<ScrollView HorizontalScrollBarVisibility="Hidden">
<ItemsRepeater
Margin="16"
ItemTemplate="{StaticResource InventoryItemTemplate}"
ItemsSource="{Binding InventoryItems}">
<ItemsRepeater Margin="16" ItemsSource="{Binding InventoryItems}">
<ItemsRepeater.Layout>
<cwcont:WrapLayout HorizontalSpacing="12" VerticalSpacing="12"/>
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<ItemContainer>
<ItemContainer.Resources>
<SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ItemContainerPressedBackground" Color="Transparent"/>
</ItemContainer.Resources>
<Button
Padding="0"
Background="Transparent"
BorderBrush="{x:Null}"
BorderThickness="0">
<shvco:BottomTextControl Text="{Binding Count, Mode=OneWay}">
<shvco:ItemIcon Icon="{Binding Inner.Icon, Converter={StaticResource ItemIconConverter}}" Quality="{Binding Inner.RankLevel}"/>
</shvco:BottomTextControl>
<Button.Flyout>
<Flyout>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Style="{StaticResource BaseTextBlockStyle}" Text="{Binding Inner.Name}"/>
<NumberBox
Grid.Row="1"
MinWidth="160"
Margin="0,16,0,0"
Maximum="4294967295"
Minimum="0"
Value="{Binding Count, Mode=TwoWay}"/>
</Grid>
</Flyout>
</Button.Flyout>
</Button>
</ItemContainer>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</ScrollView>
</PivotItem>
</Pivot>
</Grid>

View File

@@ -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}"
@@ -27,361 +26,6 @@
<Page.Resources>
<shc:BindingProxy x:Key="ViewModelBindingProxy" DataContext="{Binding}"/>
<DataTemplate x:Key="UserAndUidTemplate">
<Grid Padding="0,0,0,16">
<TextBlock VerticalAlignment="Center" Text="{Binding Uid}"/>
<Button
Margin="16,0,0,0"
Padding="6"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Command="{Binding DataContext.TrackRoleCommand, Source={StaticResource ViewModelBindingProxy}}"
CommandParameter="{Binding}"
Content="&#xE710;"
FontFamily="{StaticResource SymbolThemeFontFamily}"
Style="{StaticResource ButtonRevealStyle}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageDailyNoteAddEntryToolTip}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DailyNoteEntryTemplate">
<ItemContainer cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<ItemContainer.Resources>
<SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ItemContainerPressedBackground" Color="Transparent"/>
</ItemContainer.Resources>
<Grid Padding="8" Style="{ThemeResource GridCardStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid MinHeight="40" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Margin="4,2,0,4"
VerticalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding UserGameRole}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<StackPanel
x:Name="ButtonPanel"
Grid.Column="1"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button
Margin="8,0,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
shch:FrameworkElementHelper.SquareLength="40"
Background="Transparent"
BorderBrush="{x:Null}"
BorderThickness="0"
Command="{Binding DataContext.RemoveDailyNoteCommand, Source={StaticResource ViewModelBindingProxy}}"
CommandParameter="{Binding}"
Content="{StaticResource FontIconContentDelete}"
FontFamily="{StaticResource SymbolThemeFontFamily}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageDailyNoteRemoveToolTip}"/>
<Button
Margin="8,0,0,0"
VerticalAlignment="Stretch"
shch:FrameworkElementHelper.SquareLength="40"
Background="Transparent"
BorderBrush="{x:Null}"
BorderThickness="0"
Command="{Binding DataContext.ModifyNotificationCommand, Source={StaticResource ViewModelBindingProxy}}"
CommandParameter="{Binding}"
Content="{StaticResource FontIconContentSetting}"
FontFamily="{StaticResource SymbolThemeFontFamily}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageDailyNoteNotificationSetting}"/>
</StackPanel>
</Grid>
<StackPanel
Grid.Row="1"
Margin="0,8,0,0"
Spacing="6">
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="2"
Height="40"
MinHeight="48"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="{Binding DailyNote.MaxResin, Mode=OneWay}"
Opacity="{StaticResource LargeBackgroundProgressBarOpacity}"
Value="{Binding DailyNote.CurrentResin, Mode=OneWay}"/>
<shci:CachedImage
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_ItemIcon_210}"/>
<StackPanel
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center">
<TextBlock
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding DailyNote.ResinFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Opacity="0.6"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding DailyNote.ResinRecoveryTargetTime, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="2"
Height="40"
MinHeight="48"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="{Binding DailyNote.MaxHomeCoin, Mode=OneWay}"
Opacity="{StaticResource LargeBackgroundProgressBarOpacity}"
Value="{Binding DailyNote.CurrentHomeCoin, Mode=OneWay}"/>
<shci:CachedImage
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_ItemIcon_204}"/>
<StackPanel
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center">
<TextBlock
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding DailyNote.HomeCoinFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Opacity="0.6"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding DailyNote.HomeCoinRecoveryTargetTimeFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="3"
Height="40"
MinHeight="48"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="{Binding DailyNote.TotalTaskNum, Mode=OneWay}"
Opacity="{StaticResource LargeBackgroundProgressBarOpacity}"
Value="{Binding DailyNote.FinishedTaskNum, Mode=OneWay}"/>
<shci:CachedImage
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_MarkQuest_Events_Proce}"/>
<StackPanel
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center">
<TextBlock
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding DailyNote.TaskFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Opacity="0.6"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding DailyNote.ExtraTaskRewardDescription, Mode=OneWay}"
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 FlyoutPresenterStyle="{StaticResource FlyoutPresenterPadding6Style}" Placement="BottomEdgeAlignedRight">
<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>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="2"
Height="40"
MinHeight="48"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="{Binding DailyNote.ResinDiscountNumLimit, Mode=OneWay}"
Opacity="{ThemeResource LargeBackgroundProgressBarOpacity}"
Value="{Binding DailyNote.ResinDiscountUsedNum, Mode=OneWay}"/>
<shci:CachedImage
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_MarkTower}"/>
<StackPanel
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center">
<TextBlock
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding DailyNote.ResinDiscountFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Opacity="0.6"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageDailyNoteResinDiscountUsed}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="2"
Height="40"
MinHeight="48"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="604800"
Opacity="{StaticResource LargeBackgroundProgressBarOpacity}"
Value="{Binding DailyNote.Transformer.RecoveryTime.TotalSeconds, Mode=OneWay}"/>
<shci:CachedImage
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_ItemIcon_220021}"/>
<StackPanel
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center">
<TextBlock
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding DailyNote.Transformer.ObtainedAndReachedFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Opacity="0.6"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding DailyNote.Transformer.ObtainedAndTimeFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
</StackPanel>
<MenuFlyoutSeparator Grid.Row="2" Margin="6,6,6,0"/>
<ItemsControl
Grid.Row="3"
Margin="0,6,0,0"
ItemsSource="{Binding DailyNote.Expeditions, Mode=OneWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<cwc:UniformGrid
ColumnSpacing="8"
Columns="2"
RowSpacing="8"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="2"
MinHeight="40"
HorizontalAlignment="Stretch"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="{Binding TotalTime, Mode=OneWay}"
Opacity="{StaticResource LargeBackgroundProgressBarOpacity}"
Value="{Binding PassedTime, Mode=OneWay}"/>
<shci:CachedImage
Margin="0,0,0,8"
shch:FrameworkElementHelper.SquareLength="32"
Source="{Binding AvatarSideIcon, Mode=OneWay}"/>
<TextBlock
Grid.Column="1"
Margin="16,0,0,0"
VerticalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding RemainedTimeFormatted, Mode=OneWay}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock
Grid.Row="4"
Margin="0,6,0,0"
Opacity="0.7"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding RefreshTimeFormatted}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</Grid>
</ItemContainer>
</DataTemplate>
</Page.Resources>
<Grid>
@@ -401,27 +45,54 @@
Label="{shcm:ResourceString Name=ViewPageDailyNoteVerify}">
<AppBarButton.Flyout>
<Flyout
FlyoutPresenterStyle="{ThemeResource WebViewerFlyoutPresenterStyle}"
LightDismissOverlayMode="On"
Placement="Full"
ShowMode="Standard">
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}"/>
</Style>
</Flyout.FlyoutPresenterStyle>
<shvc:WebViewer SourceProvider="{Binding VerifyUrlSource, Mode=OneWay}"/>
</Flyout>
</AppBarButton.Flyout>
</AppBarButton>
<AppBarButton Icon="{shcm:FontIcon Glyph={StaticResource FontIconContentAdd}}" Label="{shcm:ResourceString Name=ViewPageDailyNoteAddEntry}">
<AppBarButton.Flyout>
<Flyout
FlyoutPresenterStyle="{StaticResource FlyoutPresenterPadding0And2Style}"
LightDismissOverlayMode="On"
Placement="Bottom">
<Flyout LightDismissOverlayMode="On" Placement="Bottom">
<Flyout.FlyoutPresenterStyle>
<Style BasedOn="{StaticResource DefaultFlyoutPresenterStyle}" TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="0,2,0,2"/>
<Setter Property="Background" Value="{ThemeResource FlyoutPresenterBackground}"/>
</Style>
</Flyout.FlyoutPresenterStyle>
<StackPanel>
<TextBlock
Margin="16,12,16,16"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageDailyNoteAddEntryHint}"/>
<ScrollViewer MaxHeight="320" Padding="16,0">
<ItemsControl ItemTemplate="{StaticResource UserAndUidTemplate}" ItemsSource="{Binding UserAndUids}"/>
<ItemsControl ItemsSource="{Binding UserAndUids}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Padding="0,0,0,16">
<TextBlock VerticalAlignment="Center" Text="{Binding Uid}"/>
<Button
Margin="16,0,0,0"
Padding="6"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Command="{Binding DataContext.TrackRoleCommand, Source={StaticResource ViewModelBindingProxy}}"
CommandParameter="{Binding}"
Content="&#xE710;"
FontFamily="{StaticResource SymbolThemeFontFamily}"
Style="{StaticResource ButtonRevealStyle}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageDailyNoteAddEntryToolTip}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
</Flyout>
@@ -488,6 +159,7 @@
</StackPanel>
</cwc:HeaderedContentControl>
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageDailyNoteNotificationHeader}"/>
<cwc:SettingsCard
Description="{shcm:ResourceString Name=ViewPageDailyNoteSlientModeDescription}"
@@ -501,22 +173,11 @@
HeaderIcon="{shcm:FontIcon Glyph=&#xEA8F;}">
<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=&#xEE94;}"
IsClickEnabled="True"/>
</StackPanel>
</ScrollViewer>
</SplitView.Pane>
<ScrollView>
<ItemsRepeater
Margin="16"
ItemTemplate="{StaticResource DailyNoteEntryTemplate}"
ItemsSource="{Binding DailyNoteEntries}">
<ItemsRepeater Margin="16" ItemsSource="{Binding DailyNoteEntries}">
<ItemsRepeater.Layout>
<UniformGridLayout
ItemsJustification="Start"
@@ -525,6 +186,347 @@
MinItemWidth="300"
MinRowSpacing="12"/>
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<ItemContainer cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<ItemContainer.Resources>
<SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ItemContainerPressedBackground" Color="Transparent"/>
</ItemContainer.Resources>
<Grid Padding="8" Style="{ThemeResource GridCardStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.Resources>
<Storyboard x:Name="ButtonPanelVisibleStoryboard">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="ButtonPanelCollapsedStoryboard">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<mxi:Interaction.Behaviors>
<mxic:EventTriggerBehavior EventName="PointerEntered">
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelVisibleStoryboard}"/>
</mxic:EventTriggerBehavior>
<mxic:EventTriggerBehavior EventName="PointerExited">
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelCollapsedStoryboard}"/>
</mxic:EventTriggerBehavior>
</mxi:Interaction.Behaviors>
<Grid MinHeight="40" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Margin="4,2,0,4"
VerticalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding UserGameRole}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<StackPanel
x:Name="ButtonPanel"
Grid.Column="1"
HorizontalAlignment="Right"
Orientation="Horizontal"
Visibility="Collapsed">
<Button
Margin="8,0,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
shch:FrameworkElementHelper.SquareLength="40"
Background="Transparent"
BorderBrush="{x:Null}"
BorderThickness="0"
Command="{Binding DataContext.RemoveDailyNoteCommand, Source={StaticResource ViewModelBindingProxy}}"
CommandParameter="{Binding}"
Content="{StaticResource FontIconContentDelete}"
FontFamily="{StaticResource SymbolThemeFontFamily}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageDailyNoteRemoveToolTip}"/>
<Button
Margin="8,0,0,0"
VerticalAlignment="Stretch"
shch:FrameworkElementHelper.SquareLength="40"
Background="Transparent"
BorderBrush="{x:Null}"
BorderThickness="0"
Command="{Binding DataContext.ModifyNotificationCommand, Source={StaticResource ViewModelBindingProxy}}"
CommandParameter="{Binding}"
Content="{StaticResource FontIconContentSetting}"
FontFamily="{StaticResource SymbolThemeFontFamily}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageDailyNoteNotificationSetting}"/>
</StackPanel>
</Grid>
<StackPanel
Grid.Row="1"
Margin="0,8,0,0"
Spacing="6">
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="2"
Height="40"
MinHeight="48"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="{Binding DailyNote.MaxResin, Mode=OneWay}"
Opacity="{StaticResource LargeBackgroundProgressBarOpacity}"
Value="{Binding DailyNote.CurrentResin, Mode=OneWay}"/>
<shci:CachedImage
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_ItemIcon_210}"/>
<StackPanel
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center">
<TextBlock
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding DailyNote.ResinFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Opacity="0.6"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding DailyNote.ResinRecoveryTargetTime, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="2"
Height="40"
MinHeight="48"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="{Binding DailyNote.MaxHomeCoin, Mode=OneWay}"
Opacity="{StaticResource LargeBackgroundProgressBarOpacity}"
Value="{Binding DailyNote.CurrentHomeCoin, Mode=OneWay}"/>
<shci:CachedImage
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_ItemIcon_204}"/>
<StackPanel
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center">
<TextBlock
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding DailyNote.HomeCoinFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Opacity="0.6"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding DailyNote.HomeCoinRecoveryTargetTimeFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="2"
Height="40"
MinHeight="48"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="{Binding DailyNote.TotalTaskNum, Mode=OneWay}"
Opacity="{StaticResource LargeBackgroundProgressBarOpacity}"
Value="{Binding DailyNote.FinishedTaskNum, Mode=OneWay}"/>
<shci:CachedImage
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_MarkQuest_Events_Proce}"/>
<StackPanel
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center">
<TextBlock
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding DailyNote.TaskFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Opacity="0.6"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding DailyNote.ExtraTaskRewardDescription, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="2"
Height="40"
MinHeight="48"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="{Binding DailyNote.ResinDiscountNumLimit, Mode=OneWay}"
Opacity="{StaticResource LargeBackgroundProgressBarOpacity}"
Value="{Binding DailyNote.ResinDiscountUsedNum, Mode=OneWay}"/>
<shci:CachedImage
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_MarkTower}"/>
<StackPanel
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center">
<TextBlock
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding DailyNote.ResinDiscountFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Opacity="0.6"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageDailyNoteResinDiscountUsed}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="2"
Height="40"
MinHeight="48"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="604800"
Opacity="{StaticResource LargeBackgroundProgressBarOpacity}"
Value="{Binding DailyNote.Transformer.RecoveryTime.TotalSeconds, Mode=OneWay}"/>
<shci:CachedImage
Grid.Column="0"
Margin="4"
VerticalAlignment="Center"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_ItemIcon_220021}"/>
<StackPanel
Grid.Column="1"
Margin="8,0,0,0"
VerticalAlignment="Center">
<TextBlock
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding DailyNote.Transformer.ObtainedAndReachedFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Opacity="0.6"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding DailyNote.Transformer.ObtainedAndTimeFormatted, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
</StackPanel>
<MenuFlyoutSeparator Grid.Row="2" Margin="6,6,6,0"/>
<ItemsControl
Grid.Row="3"
Margin="0,6,0,0"
ItemsSource="{Binding DailyNote.Expeditions, Mode=OneWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<cwc:UniformGrid
ColumnSpacing="8"
Columns="2"
RowSpacing="8"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Style="{ThemeResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressBar
Grid.ColumnSpan="2"
MinHeight="40"
HorizontalAlignment="Stretch"
Background="{x:Null}"
CornerRadius="{ThemeResource ControlCornerRadius}"
Maximum="{Binding TotalTime, Mode=OneWay}"
Opacity="{StaticResource LargeBackgroundProgressBarOpacity}"
Value="{Binding PassedTime, Mode=OneWay}"/>
<shci:CachedImage
Margin="0,0,0,8"
shch:FrameworkElementHelper.SquareLength="32"
Source="{Binding AvatarSideIcon, Mode=OneWay}"/>
<TextBlock
Grid.Column="1"
Margin="16,0,0,0"
VerticalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding RemainedTimeFormatted, Mode=OneWay}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock
Grid.Row="4"
Margin="0,6,0,0"
Opacity="0.7"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding RefreshTimeFormatted}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
</Grid>
</ItemContainer>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</ScrollView>
</SplitView>

View File

@@ -7,7 +7,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
xmlns:shc="using:Snap.Hutao.Control"
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
xmlns:shci="using:Snap.Hutao.Control.Image"
@@ -22,206 +21,6 @@
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
</mxi:Interaction.Behaviors>
<Page.Resources>
<Flyout x:Key="HutaoCloudFlyout">
<Grid>
<mxi:Interaction.Behaviors>
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding HutaoCloudViewModel.OpenUICommand}"/>
</mxi:Interaction.Behaviors>
<Grid Visibility="{Binding HutaoCloudViewModel.IsInitialized, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid Visibility="{Binding HutaoCloudViewModel.Options.IsCloudServiceAllowed, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<StackPanel Margin="0,0,0,12">
<TextBlock
HorizontalTextAlignment="Center"
Text="{Binding HutaoCloudViewModel.Options.GachaLogExpireAt}"
TextAlignment="Center"/>
<TextBlock
Margin="0,6,0,0"
HorizontalTextAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudDeveloperHint}"
Visibility="{Binding HutaoCloudViewModel.Options.IsLicensedDeveloper, Converter={StaticResource BoolToVisibilityConverter}}"/>
</StackPanel>
</Grid>
<ScrollViewer Grid.Row="1" Margin="0,0,0,8">
<ScrollViewer.Resources>
<shc:BindingProxy x:Key="ViewModelBindingProxy" DataContext="{Binding}"/>
<shc:BindingProxy x:Key="HutaoCloudViewModelBindingProxy" DataContext="{Binding HutaoCloudViewModel}"/>
<DataTemplate x:Key="UidOperationTemplate">
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock Style="{StaticResource BaseTextBlockStyle}" Text="{Binding Uid}"/>
<TextBlock
Opacity="0.7"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding ItemCount}"/>
</StackPanel>
<StackPanel
Grid.Column="1"
Margin="6,0,0,0"
Orientation="Horizontal">
<Button
Margin="6,0,0,0"
VerticalAlignment="Stretch"
Background="Transparent"
Command="{Binding RetrieveCommand}"
CommandParameter="{Binding Uid}"
Content="&#xE896;"
FontFamily="{StaticResource SymbolThemeFontFamily}"
Style="{StaticResource ButtonRevealStyle}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudRetrieve}"/>
<Button
Margin="6,0,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Background="Transparent"
Command="{Binding DeleteCommand}"
CommandParameter="{Binding Uid}"
Content="&#xE74D;"
FontFamily="{StaticResource SymbolThemeFontFamily}"
Style="{StaticResource ButtonRevealStyle}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudDelete}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ScrollViewer.Resources>
<ItemsControl ItemTemplate="{StaticResource UidOperationTemplate}" ItemsSource="{Binding HutaoCloudViewModel.UidOperations}"/>
</ScrollViewer>
<Button
Grid.Row="2"
HorizontalAlignment="Stretch"
Command="{Binding HutaoCloudViewModel.UploadCommand}"
CommandParameter="{Binding SelectedArchive}"
Content="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudUpload}"/>
</Grid>
<StackPanel Spacing="{StaticResource SettingsCardSpacing}" Visibility="{Binding HutaoCloudViewModel.Options.IsCloudServiceAllowed, Converter={StaticResource BoolToVisibilityRevertConverter}}">
<StackPanel.Resources>
<Thickness x:Key="SettingsCardPadding">16</Thickness>
<x:Double x:Key="SettingsCardWrapThreshold">0</x:Double>
<x:Double x:Key="SettingsCardWrapNoIconThreshold">0</x:Double>
<x:Double x:Key="SettingsCardMinHeight">0</x:Double>
</StackPanel.Resources>
<TextBlock
Margin="0,0,0,8"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudNotAllowed}"
TextAlignment="Center"/>
<cwc:SettingsCard
Command="{Binding HutaoCloudViewModel.NavigateToSpiralAbyssRecordCommand}"
Description="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudSpiralAbyssActivityDescription}"
Header="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudSpiralAbyssActivityHeader}"
IsClickEnabled="True"/>
<cwc:SettingsCard
Command="{Binding HutaoCloudViewModel.NavigateToAfdianSkuCommand}"
Description="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudAfdianPurchaseDescription}"
Header="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudAfdianPurchaseHeader}"
IsClickEnabled="True"/>
</StackPanel>
</Grid>
<shvc:LoadingViewSlim
MinWidth="240"
Margin="-16"
IsLoading="{Binding HutaoCloudViewModel.IsInitialized, Converter={StaticResource BoolNegationConverter}}"/>
</Grid>
</Flyout>
<DataTemplate x:Key="HistoryWishItemTemplate">
<Border Width="40" Style="{StaticResource BorderCardStyle}">
<StackPanel>
<shvc:ItemIcon
Width="40"
Height="40"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<TextBlock
HorizontalTextAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding Count}"
TextTrimming="None"
TextWrapping="NoWrap"/>
</StackPanel>
</Border>
</DataTemplate>
<DataTemplate x:Key="HistoryWishListTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Margin="0,8,0,0" Orientation="Horizontal">
<TextBlock
Width="32"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Version}"/>
<TextBlock
Margin="0,0,0,0"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Name}"/>
</StackPanel>
<TextBlock
Margin="0,8,0,0"
HorizontalAlignment="Right"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding TotalCountFormatted}"/>
<ItemsControl
Grid.Row="1"
Margin="0,6,0,0"
HorizontalAlignment="Left"
ItemTemplate="{StaticResource HistoryWishItemTemplate}"
ItemsPanel="{StaticResource HorizontalStackPanelSpacing2Template}"
ItemsSource="{Binding OrangeUpList}"/>
<ItemsControl
Grid.Row="1"
Margin="0,6,0,0"
HorizontalAlignment="Right"
ItemTemplate="{StaticResource HistoryWishItemTemplate}"
ItemsPanel="{StaticResource HorizontalStackPanelSpacing2Template}"
ItemsSource="{Binding PurpleUpList}"/>
<TextBlock
Grid.Row="2"
Margin="0,6,0,8"
Opacity="0.6"
Text="{Binding TimeSpanFormatted}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="HistoryWishGridTemplate">
<Grid>
<shvc:ItemIcon
Badge="{Binding Badge}"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding Count}"/>
</Border>
</Grid>
</DataTemplate>
</Page.Resources>
<Grid Visibility="{Binding IsInitialized, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid Visibility="{Binding Statistics, Converter={StaticResource EmptyObjectToVisibilityConverter}}">
<Rectangle
@@ -264,10 +63,126 @@
</AppBarButton.Flyout>
</AppBarButton>
<AppBarSeparator/>
<AppBarButton
Flyout="{StaticResource HutaoCloudFlyout}"
Icon="{shcm:FontIcon Glyph=&#xE753;}"
Label="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloud}"/>
<AppBarButton Icon="{shcm:FontIcon Glyph=&#xE753;}" Label="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloud}">
<AppBarButton.Flyout>
<Flyout Placement="Bottom">
<Grid>
<mxi:Interaction.Behaviors>
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding HutaoCloudViewModel.OpenUICommand}"/>
</mxi:Interaction.Behaviors>
<Grid Visibility="{Binding HutaoCloudViewModel.IsInitialized, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid Visibility="{Binding HutaoCloudViewModel.Options.IsCloudServiceAllowed, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<StackPanel Margin="0,0,0,12">
<TextBlock
HorizontalTextAlignment="Center"
Text="{Binding HutaoCloudViewModel.Options.GachaLogExpireAt}"
TextAlignment="Center"/>
<TextBlock
Margin="0,6,0,0"
HorizontalTextAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudDeveloperHint}"
Visibility="{Binding HutaoCloudViewModel.Options.IsLicensedDeveloper, Converter={StaticResource BoolToVisibilityConverter}}"/>
</StackPanel>
</Grid>
<ScrollViewer Grid.Row="1" Margin="0,0,0,8">
<ScrollViewer.Resources>
<shc:BindingProxy x:Key="ViewModelBindingProxy" DataContext="{Binding}"/>
<shc:BindingProxy x:Key="HutaoCloudViewModelBindingProxy" DataContext="{Binding HutaoCloudViewModel}"/>
</ScrollViewer.Resources>
<ItemsControl ItemsSource="{Binding HutaoCloudViewModel.UidOperations}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock Style="{StaticResource BaseTextBlockStyle}" Text="{Binding Uid}"/>
<TextBlock
Opacity="0.7"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding ItemCount}"/>
</StackPanel>
<StackPanel
Grid.Column="1"
Margin="6,0,0,0"
Orientation="Horizontal">
<Button
Margin="6,0,0,0"
VerticalAlignment="Stretch"
Background="Transparent"
Command="{Binding RetrieveCommand}"
CommandParameter="{Binding Uid}"
Content="&#xE896;"
FontFamily="{StaticResource SymbolThemeFontFamily}"
Style="{StaticResource ButtonRevealStyle}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudRetrieve}"/>
<Button
Margin="6,0,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Background="Transparent"
Command="{Binding DeleteCommand}"
CommandParameter="{Binding Uid}"
Content="&#xE74D;"
FontFamily="{StaticResource SymbolThemeFontFamily}"
Style="{StaticResource ButtonRevealStyle}"
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudDelete}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<Button
Grid.Row="2"
HorizontalAlignment="Stretch"
Command="{Binding HutaoCloudViewModel.UploadCommand}"
CommandParameter="{Binding SelectedArchive}"
Content="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudUpload}"/>
</Grid>
<StackPanel Spacing="{StaticResource SettingsCardSpacing}" Visibility="{Binding HutaoCloudViewModel.Options.IsCloudServiceAllowed, Converter={StaticResource BoolToVisibilityRevertConverter}}">
<StackPanel.Resources>
<Thickness x:Key="SettingsCardPadding">16</Thickness>
<x:Double x:Key="SettingsCardWrapThreshold">0</x:Double>
<x:Double x:Key="SettingsCardWrapNoIconThreshold">0</x:Double>
<x:Double x:Key="SettingsCardMinHeight">0</x:Double>
</StackPanel.Resources>
<TextBlock
Margin="0,0,0,8"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudNotAllowed}"
TextAlignment="Center"/>
<cwc:SettingsCard
Command="{Binding HutaoCloudViewModel.NavigateToSpiralAbyssRecordCommand}"
Description="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudSpiralAbyssActivityDescription}"
Header="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudSpiralAbyssActivityHeader}"
IsClickEnabled="True"/>
<cwc:SettingsCard
Command="{Binding HutaoCloudViewModel.NavigateToAfdianSkuCommand}"
Description="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudAfdianPurchaseDescription}"
Header="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudAfdianPurchaseHeader}"
IsClickEnabled="True"/>
</StackPanel>
</Grid>
<shvc:LoadingViewSlim
MinWidth="240"
Margin="-16"
IsLoading="{Binding HutaoCloudViewModel.IsInitialized, Converter={StaticResource BoolNegationConverter}}"/>
</Grid>
</Flyout>
</AppBarButton.Flyout>
</AppBarButton>
<AppBarSeparator/>
<AppBarButton
Command="{Binding ImportFromUIGFJsonCommand}"
@@ -315,10 +230,114 @@
OpenPaneLength="323"
PaneBackground="Transparent">
<SplitView.Pane>
<ListView
ItemTemplate="{StaticResource HistoryWishListTemplate}"
ItemsSource="{Binding Statistics.HistoryWishes}"
SelectedItem="{Binding SelectedHistoryWish, Mode=TwoWay}"/>
<ListView ItemsSource="{Binding Statistics.HistoryWishes}" SelectedItem="{Binding SelectedHistoryWish, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Margin="0,8,0,0" Orientation="Horizontal">
<TextBlock
Width="32"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Version}"/>
<TextBlock
Margin="0,0,0,0"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Name}"/>
</StackPanel>
<TextBlock
Margin="0,8,0,0"
HorizontalAlignment="Right"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding TotalCountFormatted}"/>
<ItemsControl
Grid.Row="1"
Margin="0,6,0,0"
HorizontalAlignment="Left"
ItemsSource="{Binding OrangeUpList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Spacing="2"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="40" Style="{StaticResource BorderCardStyle}">
<StackPanel>
<shvc:ItemIcon
Width="40"
Height="40"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<TextBlock
HorizontalTextAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding Count}"
TextTrimming="None"
TextWrapping="NoWrap"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl
Grid.Row="1"
Margin="0,6,0,0"
HorizontalAlignment="Right"
ItemsSource="{Binding PurpleUpList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Spacing="2"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="40" Style="{StaticResource BorderCardStyle}">
<StackPanel>
<shvc:ItemIcon
Width="40"
Height="40"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<TextBlock
HorizontalTextAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding Count}"
TextTrimming="None"
TextWrapping="NoWrap"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel
Grid.Row="2"
Margin="0,6,0,8"
Opacity="0.6"
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>
</ListView>
</SplitView.Pane>
<SplitView.Content>
<ScrollViewer>
@@ -340,35 +359,91 @@
</Border>
</Border>
<TextBlock
Margin="0,16,0,8"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeText}"
Visibility="{Binding SelectedHistoryWish.OrangeList.Count, Converter={StaticResource Int32ToVisibilityConverter}}"/>
<GridView
ItemTemplate="{StaticResource HistoryWishGridTemplate}"
ItemsSource="{Binding SelectedHistoryWish.OrangeList}"
SelectionMode="None"/>
<GridView ItemsSource="{Binding SelectedHistoryWish.OrangeList}" SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<shvc:ItemIcon
Badge="{Binding Badge}"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding Count}"/>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<TextBlock
Margin="0,0,0,8"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardPurpleText}"
Visibility="{Binding SelectedHistoryWish.PurpleList.Count, Converter={StaticResource Int32ToVisibilityConverter}}"/>
<GridView
ItemTemplate="{StaticResource HistoryWishGridTemplate}"
ItemsSource="{Binding SelectedHistoryWish.PurpleList}"
SelectionMode="None"/>
<GridView ItemsSource="{Binding SelectedHistoryWish.PurpleList}" SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<shvc:ItemIcon
Badge="{Binding Badge}"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding Count}"/>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<TextBlock
Margin="0,0,0,8"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardBlueText}"
Visibility="{Binding SelectedHistoryWish.BlueList.Count, Converter={StaticResource Int32ToVisibilityConverter}}"/>
<GridView
ItemTemplate="{StaticResource HistoryWishGridTemplate}"
ItemsSource="{Binding SelectedHistoryWish.BlueList}"
SelectionMode="None"/>
<GridView ItemsSource="{Binding SelectedHistoryWish.BlueList}" SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<shvc:ItemIcon
Badge="{Binding Badge}"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding Count}"/>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</StackPanel>
</ScrollViewer>
</SplitView.Content>
@@ -381,19 +456,55 @@
Margin="0,16,0,8"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeText}"/>
<GridView
ItemTemplate="{StaticResource HistoryWishItemTemplate}"
ItemsSource="{Binding Statistics.OrangeAvatars}"
SelectionMode="None"/>
<GridView ItemsSource="{Binding Statistics.OrangeAvatars}" SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<shvc:ItemIcon
Badge="{Binding Badge}"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding Count}"/>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<TextBlock
Margin="0,0,0,8"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardPurpleText}"/>
<GridView
ItemTemplate="{StaticResource HistoryWishItemTemplate}"
ItemsSource="{Binding Statistics.PurpleAvatars}"
SelectionMode="None"/>
<GridView ItemsSource="{Binding Statistics.PurpleAvatars}" SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<shvc:ItemIcon
Badge="{Binding Badge}"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding Count}"/>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</StackPanel>
</ScrollViewer>
</PivotItem>
@@ -404,28 +515,82 @@
Margin="0,16,0,8"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeText}"/>
<GridView
ItemTemplate="{StaticResource HistoryWishItemTemplate}"
ItemsSource="{Binding Statistics.OrangeWeapons}"
SelectionMode="None"/>
<GridView ItemsSource="{Binding Statistics.OrangeWeapons}" SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<shvc:ItemIcon
Badge="{Binding Badge}"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding Count}"/>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<TextBlock
Margin="0,0,0,8"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardPurpleText}"/>
<GridView
ItemTemplate="{StaticResource HistoryWishItemTemplate}"
ItemsSource="{Binding Statistics.PurpleWeapons}"
SelectionMode="None"/>
<GridView ItemsSource="{Binding Statistics.PurpleWeapons}" SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<shvc:ItemIcon
Badge="{Binding Badge}"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding Count}"/>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<TextBlock
Margin="0,0,0,8"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardBlueText}"/>
<GridView
ItemTemplate="{StaticResource HistoryWishItemTemplate}"
ItemsSource="{Binding Statistics.BlueWeapons}"
SelectionMode="None"/>
<GridView ItemsSource="{Binding Statistics.BlueWeapons}" SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<shvc:ItemIcon
Badge="{Binding Badge}"
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<Border
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#80000000"
CornerRadius="0,6,0,6">
<TextBlock
Margin="6,0,6,2"
Foreground="#FFFFFFFF"
Text="{Binding Count}"/>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</StackPanel>
</ScrollViewer>
</PivotItem>
@@ -496,18 +661,6 @@
Header="{shcm:ResourceString Name=ViewPageGachaLogImportHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE8B5;}"
IsClickEnabled="True"/>
<cwc:SettingsCard
Description="{shcm:ResourceString Name=ViewPageGachaLogRecoverFromHutaoCloudDescription}"
FlyoutBase.AttachedFlyout="{StaticResource HutaoCloudFlyout}"
Header="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloud}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE8B5;}"
IsClickEnabled="True">
<mxi:Interaction.Behaviors>
<mxic:EventTriggerBehavior EventName="Click">
<shcb:OpenAttachedFlyoutAction/>
</mxic:EventTriggerBehavior>
</mxi:Interaction.Behaviors>
</cwc:SettingsCard>
</StackPanel>
</StackPanel>
</Grid>

Some files were not shown because too many files have changed in this diff Show More