mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26e6d2008e | ||
|
|
fb77bd2f6b | ||
|
|
50459923f9 | ||
|
|
a97bab8a1c | ||
|
|
bbc8324f5d | ||
|
|
2c0b32ab8b | ||
|
|
0073636676 | ||
|
|
7457d72e1b | ||
|
|
eed89b2ce1 | ||
|
|
958fecdb77 | ||
|
|
bcf38fbefc | ||
|
|
ff146b4a2f | ||
|
|
419f8b8882 | ||
|
|
7a5f1ded35 | ||
|
|
844c8b7810 | ||
|
|
267b34f571 | ||
|
|
0f27ebc12c | ||
|
|
e051787584 | ||
|
|
8f273e69b5 | ||
|
|
88037049f3 | ||
|
|
8357d3b971 | ||
|
|
d41acc0a77 | ||
|
|
0dd79d4206 | ||
|
|
86061e404f |
@@ -1,5 +1,5 @@
|
||||
name: Artifact Rating Rules
|
||||
description: 圣遗物评分细则建议
|
||||
name: 圣遗物评分细则建议
|
||||
description: 为圣遗物评分规则提供你的想法
|
||||
title: "[Artifact Rating] 请在这里填写角色名称"
|
||||
labels: area-AvatarInfo
|
||||
assignees: Lightczx
|
||||
|
||||
108
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
108
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
name: 问题反馈
|
||||
description: 告诉我们你的问题
|
||||
title: "[Bug]: 在这里填写一个合适的标题"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
> **请在上方设置一个合适的工单标题**
|
||||
> 请按下方的要求填写完整的问题表单,以便我们更快的定位问题。
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: 检查清单
|
||||
description: |-
|
||||
请确保你已完整执行检查清单,否则你的 Issue 可能会被忽略
|
||||
options:
|
||||
- label: 我已完整阅读[胡桃工具箱文档](https://hut.ao/FAQ/most-frequent-questions.html),并认为我的问题没有在文档中得到解答
|
||||
required: true
|
||||
|
||||
- label: 我使用的操作系统是[受支持的版本](https://hut.ao/quick-start.html#%E6%9C%80%E4%BD%8E%E7%B3%BB%E7%BB%9F%E8%A6%81%E6%B1%82)
|
||||
required: true
|
||||
|
||||
- label: 我确认没有其他人已经提出了相同或类似的问题
|
||||
required: true
|
||||
|
||||
- label: 我会在下方的表单中附上充足的信息以帮助开发人员确定问题
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: winver
|
||||
attributes:
|
||||
label: Windows 版本
|
||||
description: |
|
||||
`Win+R` 输入 `winver` 回车后在打开的窗口第二行可以找到
|
||||
placeholder: 例:22000.556
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: shver
|
||||
attributes:
|
||||
label: Snap Hutao 版本
|
||||
description: 在应用标题,应用程序的设置界面中靠下的位置可以找到
|
||||
placeholder: 例:1.1.0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: deviceid
|
||||
attributes:
|
||||
label: 设备 ID
|
||||
description: |
|
||||
在胡桃工具箱的设置界面,你可以找到并复制你的设备 ID
|
||||
如果你的问题涉及程序崩溃,请填写该项,这将有助于我们定位问题
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: dropdown
|
||||
id: user-set-category
|
||||
attributes:
|
||||
label: 问题分类
|
||||
description: 请设置一个你认为合适的分类,这将帮助我们快速定位问题
|
||||
options:
|
||||
- 安装和环境
|
||||
- 成就管理
|
||||
- 角色信息面板
|
||||
- 游戏启动器
|
||||
- 实时便笺
|
||||
- 养成计算器
|
||||
- 文件缓存
|
||||
- 祈愿记录
|
||||
- 玩家查询
|
||||
- 胡桃数据库
|
||||
- 用户界面
|
||||
- 签到
|
||||
- Wiki
|
||||
- 公告
|
||||
- 其它
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: 发生了什么?
|
||||
description: 详细的描述问题发生前后的行为,以便我们解决问题
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: what-expected
|
||||
attributes:
|
||||
label: 你期望发生的行为?
|
||||
description: 详细的描述你期望发生的行为,突出与目前(可能不正确的)行为的不同
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: 相关的崩溃日志
|
||||
description: |
|
||||
在资源管理器中直接输入`%userprofile%/Documents/Hutao`即可进入文件夹
|
||||
如果应用程序崩溃了,请将`log.db` 文件上传,文件包含了敏感信息,谨慎上传
|
||||
如果这个表单是关于导入祈愿记录的问题,请包含你导入的`Json`文件
|
||||
> **务必不要上传`user.db`文件,该文件包含你的帐号敏感信息**
|
||||
|
||||
91
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
91
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,91 +0,0 @@
|
||||
name: 问题反馈
|
||||
description: 告诉我们你的问题
|
||||
title: "[Bug]: 在这里填写一个合适的标题"
|
||||
labels: ["BUG"]
|
||||
assignees:
|
||||
- Lightczx
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
请按下方的要求填写完整的问题表单,以便我们更快的定位问题。
|
||||
|
||||
- type: input
|
||||
id: winver
|
||||
attributes:
|
||||
label: Windows 版本
|
||||
description: |
|
||||
`Win+R` 输入 `winver` 回车后在打开的窗口第二行可以找到
|
||||
placeholder: 例:22000.556
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: shver
|
||||
attributes:
|
||||
label: Snap Hutao 版本
|
||||
description: 在应用标题,应用程序的设置界面中靠下的位置可以找到
|
||||
placeholder: 例:1.1.0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: 发生了什么?
|
||||
description: 详细的描述问题发生前后的行为,以便我们解决问题
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: what-expected
|
||||
attributes:
|
||||
label: 你期望发生的行为?
|
||||
description: 详细的描述你期望发生的行为,突出与目前(可能不正确的)行为的不同
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: 相关的崩溃日志
|
||||
description: |
|
||||
在资源管理器中直接输入`%userprofile%/Documents/Hutao`即可进入文件夹
|
||||
如果应用程序崩溃了,请将`log.db` 文件上传,文件包含了敏感信息,谨慎上传
|
||||
如果这个表单是关于导入祈愿记录的问题,请包含你导入的`Json`文件
|
||||
**务必不要上传`user.db`文件,该文件包含你的帐号敏感信息**
|
||||
|
||||
- type: dropdown
|
||||
id: confirm-issue
|
||||
attributes:
|
||||
label: 我确认已在表单中附上了充足的补充说明以帮助开发人员确定问题
|
||||
description: 补充说明包括但不限于:日志文件、抛出的错误信息、截图和录屏
|
||||
options:
|
||||
- 是
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: confirm-no-duplicated-issue
|
||||
attributes:
|
||||
label: 我确认没有他人提出相同或类似的问题
|
||||
description: |
|
||||
请先通过 Issue 搜索功能确认这不是相同的问题;
|
||||
[BUG Issues](https://github.com/DGP-Studio/Snap.Hutao/issues?q=is%3Aissue+is%3Aopen+label%3ABUG)
|
||||
你应该在原始 Issue 中通过回复添加有助于解决问题的信息,而不是创建重复的问题;
|
||||
**没有帮助的重复问题可能会被直接关闭**
|
||||
options:
|
||||
- 是
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: confirm-docs
|
||||
attributes:
|
||||
label: 我确认该问题没有在文档中解释
|
||||
description: Snap Hutao 官方文档:[https://hut.ao](https://hut.ao)
|
||||
options:
|
||||
- 是
|
||||
validations:
|
||||
required: true
|
||||
|
||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
8
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,7 +1,5 @@
|
||||
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 问题与操作指南文档
|
||||
url: https://www.snapgenshin.com/documents/
|
||||
about: |
|
||||
[暂不可用]在发起 Issue 前 请查阅此文档确认文档中尚未包含你的问题的解决方案
|
||||
- name: 胡桃工具箱 - 官方文档
|
||||
url: https://hut.ao
|
||||
about: 请在提出问题前阅读文档
|
||||
27
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
27
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: 功能请求
|
||||
description: 告诉我们你的想法
|
||||
title: "[Feat]: 在这里填写一个合适的标题"
|
||||
labels: ["功能"]
|
||||
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
|
||||
19
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
19
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -1,19 +0,0 @@
|
||||
name: 功能请求
|
||||
description: 告诉我们你的想法
|
||||
title: "[Feat]: 在这里填写一个合适的标题"
|
||||
labels: ["功能"]
|
||||
assignees:
|
||||
- Lightczx
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
请按下方的要求填写完整的问题表单,以便我们更快的定位问题。
|
||||
|
||||
- type: textarea
|
||||
id: req
|
||||
attributes:
|
||||
label: 你想要实现或优化的功能?
|
||||
description: 详细的描述一下你想要的功能
|
||||
validations:
|
||||
required: true
|
||||
76
.github/ISSUE_TEMPLATE/network-issue.yml
vendored
Normal file
76
.github/ISSUE_TEMPLATE/network-issue.yml
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
name: 网络问题
|
||||
description: 当网络问题影响到你的程序使用时
|
||||
title: "[Network]: 在这里填写一个合适的标题"
|
||||
labels: ["area-Network"]
|
||||
assignees:
|
||||
- Lightczx
|
||||
- Masterain98
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**请先在上方为工单设置一个合适的标题**
|
||||
**请按下方的要求填写完整的问题表单,以便我们更快的定位问题。**
|
||||
|
||||
- type: textarea
|
||||
id: network-diagnosis-report
|
||||
attributes:
|
||||
label: 提交你的网络诊断报告
|
||||
description: |
|
||||
停下!
|
||||
**在填写下面的问题之前请先使用我们的网络诊断工具**
|
||||
**这个工具将会生成一份报告,请将这份报告拖入下面的框中,让其与你的工单一起被上传提交**
|
||||
- 你可以点击下面的链接以下载网络诊断工具:
|
||||
- [胡桃资源站](https://d.hut.ao/d/tools/network-diagnosis-tool.exe)
|
||||
- [GitHub](https://github.com/DGP-Studio/Snap.Hutao/files/10081999/network-diagnosis-hutao.zip)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: user-geo-location
|
||||
attributes:
|
||||
label: 你的地理位置
|
||||
description: |
|
||||
中国用户请精确到省级行政区
|
||||
海外用户请精确到国家
|
||||
placeholder: 北京
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: user-isp
|
||||
attributes:
|
||||
label: 你的运营商
|
||||
description: 中国用户请精确到省级行政区,海外地区请精确到国家
|
||||
options:
|
||||
- 中国电信
|
||||
- 中国联通
|
||||
- 中国移动
|
||||
- 中国广电
|
||||
- 其它
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: user-issue-category
|
||||
attributes:
|
||||
label: 你的问题
|
||||
description: 选择一个问题类别
|
||||
options:
|
||||
- 完全无法连接服务器
|
||||
- 连接速度慢
|
||||
- 获取到了不正确的页面或数据
|
||||
- 图片下载错误(429 Error)
|
||||
- 其它
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: 你的问题(补充)
|
||||
description: 如果你在上一项中选择了`其它`或者你有更多信息需要提供,请在这里写下来
|
||||
validations:
|
||||
required: false
|
||||
|
||||
|
||||
2
.github/workflows/PublishDistribution.yml
vendored
2
.github/workflows/PublishDistribution.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
|
||||
# Upload to Drive
|
||||
- name: Upload Drive
|
||||
timeout-minutes: 5
|
||||
timeout-minutes: 15
|
||||
env:
|
||||
RCCONF: ${{ secrets.RCCONF }}
|
||||
run: |
|
||||
|
||||
24
README.md
24
README.md
@@ -1,34 +1,26 @@
|
||||
# Snap.Hutao
|
||||
# [Snap.Hutao](https://hut.ao)
|
||||
> 唷,找本堂主有何贵干呀?
|
||||
|
||||

|
||||
|
||||
## 项目首页(文档)
|
||||
# 特别感谢
|
||||
|
||||
[](https://github.com/DGP-Studio/Snap.Hutao.Docs/actions/workflows/deploy-docs.yml)
|
||||
### 原神组织与个人
|
||||
|
||||
[HUT.AO](https://hut.ao)
|
||||
* [HolographicHat](https://github.com/HolographicHat)
|
||||
* [UIGF organization](https://uigf.org)
|
||||
|
||||
## 安装
|
||||
|
||||
* 前往 [下载页面](https://go.hut.ao/down) 下载最新版本的 `胡桃` 安装包
|
||||
* (曾启用的可以跳过此步骤)在系统设置中打开 **开发者选项** 界面,勾选 `开发人员模式` 和 `允许 PowerShell 脚本`
|
||||
* 完全解压后,右键使用 powershell 运行 `install.ps1` 文件
|
||||
* 安装完成后可以关闭 `允许 PowerShell 脚本`
|
||||
|
||||
## 特别感谢
|
||||
|
||||
### 原神项目
|
||||
### 特定的原神项目
|
||||
|
||||
* [biuuu/genshin-wish-export](https://github.com/biuuu/genshin-wish-export)
|
||||
* [HolographicHat/YaeAchievement](https://github.com/HolographicHat/YaeAchievement)
|
||||
* [xunkong/xunkong](https://github.com/xunkong/xunkong)
|
||||
* [YuehaiTeam/cocogoat](https://github.com/YuehaiTeam/cocogoat)
|
||||
|
||||
### 技术栈
|
||||
### 使用的技术栈
|
||||
|
||||
* [CommunityToolkit/dotnet](https://github.com/CommunityToolkit/dotnet)
|
||||
* [CommunityToolkit/WindowsCommunityToolkit](https://github.com/CommunityToolkit/WindowsCommunityToolkit)
|
||||
* [dahall/taskscheduler](https://github.com/dahall/taskscheduler)
|
||||
* [dotnet/efcore](https://github.com/dotnet/efcore)
|
||||
* [dotnet/runtime](https://github.com/dotnet/runtime)
|
||||
* [DotNetAnalyzers/StyleCopAnalyzers](https://github.com/DotNetAnalyzers/StyleCopAnalyzers)
|
||||
|
||||
147
azure-pipelines.yml
Normal file
147
azure-pipelines.yml
Normal file
@@ -0,0 +1,147 @@
|
||||
# CI process script for Snap.Hutao
|
||||
# Usage:
|
||||
# 1. Append the script in Pipelines
|
||||
# 2. Upload the pfx and cer certificates to Pipelines Library secrets
|
||||
# 3. Permit the pfx usage
|
||||
# 4. Add a `pw` variable in the script variables, which is pfx password
|
||||
# 5. Connect the GitHub in project settings
|
||||
# 6. Run
|
||||
|
||||
trigger:
|
||||
- main
|
||||
|
||||
pool:
|
||||
vmImage: 'windows-2022'
|
||||
|
||||
variables:
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
solution: '$(Build.SourcesDirectory)/src/Snap.Hutao/Snap.Hutao.sln'
|
||||
project: $(Build.SourcesDirectory)/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj'
|
||||
buildPlatform: 'x64'
|
||||
buildConfiguration: 'Release'
|
||||
build_date: $[ format('{0:yyyy}.{0:MM}.{0:dd}', pipeline.startTime) ]
|
||||
|
||||
|
||||
steps:
|
||||
- task: GetRevision@1
|
||||
displayName: get Pipelines revision number
|
||||
inputs:
|
||||
VariableName: 'rev_number'
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: Install dotNet
|
||||
inputs:
|
||||
packageType: 'sdk'
|
||||
version: '7.x'
|
||||
includePreviewVersions: true
|
||||
|
||||
- task: NuGetToolInstaller@1
|
||||
name: 'NuGetToolInstaller'
|
||||
displayName: 'NuGet Installer'
|
||||
|
||||
- task: NuGetCommand@2
|
||||
displayName: NuGet restore
|
||||
inputs:
|
||||
command: 'restore'
|
||||
restoreSolution: '$(solution)'
|
||||
feedsToUse: 'select'
|
||||
|
||||
- task: MsixPackaging@1
|
||||
displayName: Build binary package
|
||||
inputs:
|
||||
outputPath: '$(Build.ArtifactStagingDirectory)/'
|
||||
solution: '$(solution)'
|
||||
clean: false
|
||||
generateBundle: false
|
||||
buildConfiguration: 'Release'
|
||||
buildPlatform: 'x64'
|
||||
updateAppVersion: false
|
||||
appPackageDistributionMode: 'SideloadOnly'
|
||||
msbuildLocationMethod: 'location'
|
||||
msbuildLocation: 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Msbuild\Current\Bin\MSBuild.exe'
|
||||
|
||||
- task: MagicChunks@2
|
||||
inputs:
|
||||
sourcePath: '$(Build.SourcesDirectory)\src\Snap.Hutao\Snap.Hutao\bin\x64\Release\net7.0-windows10.0.18362.0\win10-x64\AppxManifest.xml'
|
||||
fileType: 'Xml'
|
||||
targetPathType: 'source'
|
||||
transformationType: 'json'
|
||||
transformations: |
|
||||
{
|
||||
"Package/Identity/@Name": "7f0db578-026f-4e0b-a75b-d5d06bb0a74c",
|
||||
"Package/Identity/@Publisher": "CN=DGP Studio CI",
|
||||
"Package/Identity/@Version": "$(build_date).$(rev_number)",
|
||||
"Package/Properties/DisplayName": "胡桃 Alpha",
|
||||
"Package/Properties/PublisherDisplayName":"DGP Studio CI"
|
||||
}
|
||||
|
||||
- task: CmdLine@2
|
||||
displayName: Create resources folder
|
||||
inputs:
|
||||
script: |
|
||||
mkdir Assets
|
||||
|
||||
mkdir Resource
|
||||
workingDirectory: '$(Build.SourcesDirectory)\src\Snap.Hutao\Snap.Hutao\bin\x64\Release\net7.0-windows10.0.18362.0\win10-x64'
|
||||
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy Assets Folder
|
||||
inputs:
|
||||
SourceFolder: '$(Build.SourcesDirectory)\src\Snap.Hutao\Snap.Hutao\Assets'
|
||||
Contents: '**'
|
||||
TargetFolder: '$(Build.SourcesDirectory)\src\Snap.Hutao\Snap.Hutao\bin\x64\Release\net7.0-windows10.0.18362.0\win10-x64\Assets'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy Resource Folder
|
||||
inputs:
|
||||
SourceFolder: '$(Build.SourcesDirectory)\src\Snap.Hutao\Snap.Hutao\Resource'
|
||||
Contents: '**'
|
||||
TargetFolder: '$(Build.SourcesDirectory)\src\Snap.Hutao\Snap.Hutao\bin\x64\Release\net7.0-windows10.0.18362.0\win10-x64\Resource'
|
||||
|
||||
- task: CmdLine@2
|
||||
displayName: Build MSIX
|
||||
inputs:
|
||||
script: '"C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64\makeappx.exe" pack /d $(Build.SourcesDirectory)\src\Snap.Hutao\Snap.Hutao\bin\x64\Release\net7.0-windows10.0.18362.0\win10-x64 /p $(Build.ArtifactStagingDirectory)/Snap.Hutao.Alpha-$(build_date).$(rev_number).msix'
|
||||
|
||||
- task: MsixSigning@1
|
||||
displayName: Sign MSIX package
|
||||
inputs:
|
||||
package: '$(Build.ArtifactStagingDirectory)/Snap.Hutao.Alpha-$(build_date).$(rev_number).msix'
|
||||
certificate: 'DGP_Studio_CI.pfx'
|
||||
passwordVariable: 'pw'
|
||||
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Upload Output'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)/'
|
||||
artifact: 'Output'
|
||||
publishLocation: 'pipeline'
|
||||
|
||||
- task: DownloadSecureFile@1
|
||||
name: cerFile
|
||||
displayName: Download Root CA
|
||||
inputs:
|
||||
secureFile: 'Snap.Hutao.CI.cer'
|
||||
|
||||
- task: GitHubRelease@1
|
||||
inputs:
|
||||
gitHubConnection: 'github.com_Masterain'
|
||||
repositoryName: 'DGP-Studio/Snap.Hutao'
|
||||
action: 'create'
|
||||
target: '$(Build.SourceVersion)'
|
||||
tagSource: 'userSpecifiedTag'
|
||||
tag: '$(build_date).$(rev_number)'
|
||||
title: '$(build_date).$(rev_number)'
|
||||
releaseNotesSource: 'inline'
|
||||
releaseNotesInline: |
|
||||
## 提示 (Hint)
|
||||
该发布版本由 CI 程序自动打包生成,属于 `Alpha` 测试版,仅用于开发调试和内部测试用途。使用该版本可能存在意料之外的风险,请仅在有明确用途的情况下使用该版本。
|
||||
|
||||
This release is a Alpha Testing version generated by CI program automatically in a purpose of debugging and interal testing. Using this release may have unexpected risk, please only use it when you know what you are doing.
|
||||
assets: |
|
||||
$(Build.ArtifactStagingDirectory)/*
|
||||
$(cerFile.secureFilePath)
|
||||
isPreRelease: true
|
||||
changeLogCompareToRelease: 'lastFullRelease'
|
||||
changeLogType: 'commitBased'
|
||||
@@ -1,4 +1,6 @@
|
||||
[*.cs]
|
||||
charset = utf-8-bom
|
||||
|
||||
[*.cs]
|
||||
|
||||
# SA1101: Prefix local calls with this
|
||||
dotnet_diagnostic.SA1101.severity = none
|
||||
@@ -76,31 +78,31 @@ dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
|
||||
|
||||
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
|
||||
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.types.required_modifiers =
|
||||
dotnet_naming_symbols.types.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||
|
||||
# 命名样式
|
||||
|
||||
dotnet_naming_style.begins_with_i.required_prefix = I
|
||||
dotnet_naming_style.begins_with_i.required_suffix =
|
||||
dotnet_naming_style.begins_with_i.word_separator =
|
||||
dotnet_naming_style.begins_with_i.required_suffix =
|
||||
dotnet_naming_style.begins_with_i.word_separator =
|
||||
dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
dotnet_diagnostic.SA1629.severity = none
|
||||
dotnet_diagnostic.SA1642.severity = none
|
||||
@@ -185,29 +187,29 @@ dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.style = 帕斯
|
||||
|
||||
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interface.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.类型.applicable_kinds = class, struct, interface, enum
|
||||
dotnet_naming_symbols.类型.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
|
||||
dotnet_naming_symbols.类型.required_modifiers =
|
||||
dotnet_naming_symbols.类型.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.非字段成员.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.非字段成员.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
|
||||
dotnet_naming_symbols.非字段成员.required_modifiers =
|
||||
dotnet_naming_symbols.非字段成员.required_modifiers =
|
||||
|
||||
# 命名样式
|
||||
|
||||
dotnet_naming_style.以_i_开始.required_prefix = I
|
||||
dotnet_naming_style.以_i_开始.required_suffix =
|
||||
dotnet_naming_style.以_i_开始.word_separator =
|
||||
dotnet_naming_style.以_i_开始.required_suffix =
|
||||
dotnet_naming_style.以_i_开始.word_separator =
|
||||
dotnet_naming_style.以_i_开始.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.帕斯卡拼写法.required_prefix =
|
||||
dotnet_naming_style.帕斯卡拼写法.required_suffix =
|
||||
dotnet_naming_style.帕斯卡拼写法.word_separator =
|
||||
dotnet_naming_style.帕斯卡拼写法.required_prefix =
|
||||
dotnet_naming_style.帕斯卡拼写法.required_suffix =
|
||||
dotnet_naming_style.帕斯卡拼写法.word_separator =
|
||||
dotnet_naming_style.帕斯卡拼写法.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.帕斯卡拼写法.required_prefix =
|
||||
dotnet_naming_style.帕斯卡拼写法.required_suffix =
|
||||
dotnet_naming_style.帕斯卡拼写法.word_separator =
|
||||
dotnet_naming_style.帕斯卡拼写法.required_prefix =
|
||||
dotnet_naming_style.帕斯卡拼写法.required_suffix =
|
||||
dotnet_naming_style.帕斯卡拼写法.word_separator =
|
||||
dotnet_naming_style.帕斯卡拼写法.capitalization = pascal_case
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -4,50 +4,57 @@
|
||||
xmlns:contract7NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,7)"
|
||||
xmlns:contract7Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,7)">
|
||||
|
||||
<Style x:Key="SettingButtonStyle" TargetType="Button" BasedOn="{StaticResource DefaultButtonStyle}" >
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardBorderBrush}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="Padding" Value="16,5,16,6" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Style
|
||||
x:Key="SettingButtonStyle"
|
||||
BasedOn="{StaticResource DefaultButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardBorderBrush}"/>
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}"/>
|
||||
<Setter Property="Padding" Value="16,5,16,6"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="HyperlinkButtonStyle" TargetType="HyperlinkButton" >
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Style x:Key="HyperlinkButtonStyle" TargetType="HyperlinkButton">
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="TextButtonStyle" TargetType="ButtonBase">
|
||||
<Setter Property="Background" Value="{ThemeResource HyperlinkButtonBackground}" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource HyperlinkButtonForeground}" />
|
||||
<Setter Property="MinWidth" Value="0" />
|
||||
<Setter Property="MinHeight" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
|
||||
<Setter Property="Background" Value="{ThemeResource HyperlinkButtonBackground}"/>
|
||||
<Setter Property="Foreground" Value="{ThemeResource HyperlinkButtonForeground}"/>
|
||||
<Setter Property="MinWidth" Value="0"/>
|
||||
<Setter Property="MinHeight" Value="0"/>
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ButtonBase">
|
||||
<Grid Margin="{TemplateBinding Padding}" CornerRadius="4" Background="{TemplateBinding Background}">
|
||||
<ContentPresenter x:Name="Text"
|
||||
Content="{TemplateBinding Content}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
FontWeight="SemiBold"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
|
||||
<Grid
|
||||
Margin="{TemplateBinding Padding}"
|
||||
Background="{TemplateBinding Background}"
|
||||
CornerRadius="4">
|
||||
<ContentPresenter
|
||||
x:Name="Text"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
FontWeight="SemiBold"/>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Normal"/>
|
||||
|
||||
<VisualState x:Name="PointerOver">
|
||||
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonForegroundPointerOver}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonForegroundPointerOver}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBackgroundPointerOver}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBackgroundPointerOver}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBorderBrushPointerOver}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBorderBrushPointerOver}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
@@ -56,13 +63,13 @@
|
||||
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonForegroundPressed}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonForegroundPressed}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBackgroundPressed}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBackgroundPressed}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBorderBrushPressed}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBorderBrushPressed}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
@@ -71,13 +78,13 @@
|
||||
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonForegroundDisabled}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonForegroundDisabled}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBackgroundDisabled}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBackgroundDisabled}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBorderBrushDisabled}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBorderBrushDisabled}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
@@ -85,7 +92,6 @@
|
||||
</VisualStateGroup>
|
||||
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
|
||||
</Grid>
|
||||
|
||||
</ControlTemplate>
|
||||
@@ -93,192 +99,434 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- This style overrides the default style so that all ToggleSwitches are right aligned, with the label on the left -->
|
||||
<!-- This style overrides the default style so that all ToggleSwitches are right aligned, with the label on the left -->
|
||||
<Style x:Key="ToggleSwitchSettingStyle" TargetType="ToggleSwitch">
|
||||
<Setter Property="Foreground" Value="{ThemeResource ToggleSwitchContentForeground}" />
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right" />
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
|
||||
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
|
||||
<Setter Property="ManipulationMode" Value="System,TranslateX" />
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource ToggleSwitchContentForeground}"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Right"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
|
||||
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
|
||||
<Setter Property="ManipulationMode" Value="System,TranslateX"/>
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
|
||||
|
||||
<Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3" />
|
||||
<Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3"/>
|
||||
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleSwitch">
|
||||
<Grid
|
||||
contract7Present:CornerRadius="{TemplateBinding CornerRadius}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
contract7Present:CornerRadius="{TemplateBinding CornerRadius}">
|
||||
BorderThickness="{TemplateBinding BorderThickness}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ContentPresenter
|
||||
x:Name="HeaderContentPresenter"
|
||||
Grid.Row="0"
|
||||
Margin="{ThemeResource ToggleSwitchTopHeaderMargin}"
|
||||
VerticalAlignment="Top"
|
||||
x:DeferLoadStrategy="Lazy"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Content="{TemplateBinding Header}"
|
||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||
Foreground="{ThemeResource ToggleSwitchHeaderForeground}"
|
||||
IsHitTestVisible="False"
|
||||
TextWrapping="Wrap"
|
||||
Visibility="Collapsed"/>
|
||||
<Grid
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="{ThemeResource ToggleSwitchPreContentMargin}"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="{ThemeResource ToggleSwitchPostContentMargin}"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="12" MaxWidth="12"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid
|
||||
x:Name="SwitchAreaGrid"
|
||||
Grid.RowSpan="3"
|
||||
Grid.ColumnSpan="3"
|
||||
Margin="0,5"
|
||||
contract7NotPresent:CornerRadius="{StaticResource ControlCornerRadius}"
|
||||
contract7Present:CornerRadius="{TemplateBinding CornerRadius}"
|
||||
Background="{ThemeResource ToggleSwitchContainerBackground}"
|
||||
Control.IsTemplateFocusTarget="True"/>
|
||||
<ContentPresenter
|
||||
x:Name="OffContentPresenter"
|
||||
Grid.RowSpan="3"
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Content="{TemplateBinding OffContent}"
|
||||
ContentTemplate="{TemplateBinding OffContentTemplate}"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
IsHitTestVisible="False"
|
||||
Opacity="0"/>
|
||||
<ContentPresenter
|
||||
x:Name="OnContentPresenter"
|
||||
Grid.RowSpan="3"
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Content="{TemplateBinding OnContent}"
|
||||
ContentTemplate="{TemplateBinding OnContentTemplate}"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
IsHitTestVisible="False"
|
||||
Opacity="0"/>
|
||||
<Rectangle
|
||||
x:Name="OuterBorder"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Width="40"
|
||||
Height="20"
|
||||
Fill="{ThemeResource ToggleSwitchFillOff}"
|
||||
RadiusX="10"
|
||||
RadiusY="10"
|
||||
Stroke="{ThemeResource ToggleSwitchStrokeOff}"
|
||||
StrokeThickness="{ThemeResource ToggleSwitchOuterBorderStrokeThickness}"/>
|
||||
<Rectangle
|
||||
x:Name="SwitchKnobBounds"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Width="40"
|
||||
Height="20"
|
||||
Fill="{ThemeResource ToggleSwitchFillOn}"
|
||||
Opacity="0"
|
||||
RadiusX="10"
|
||||
RadiusY="10"
|
||||
Stroke="{ThemeResource ToggleSwitchStrokeOn}"
|
||||
StrokeThickness="{ThemeResource ToggleSwitchOnStrokeThickness}"/>
|
||||
<Grid
|
||||
x:Name="SwitchKnob"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Width="20"
|
||||
Height="20"
|
||||
HorizontalAlignment="Left">
|
||||
<Border
|
||||
x:Name="SwitchKnobOn"
|
||||
Grid.Column="2"
|
||||
Width="12"
|
||||
Height="12"
|
||||
Margin="0,0,1,0"
|
||||
HorizontalAlignment="Center"
|
||||
contract7Present:BackgroundSizing="OuterBorderEdge"
|
||||
Background="{ThemeResource ToggleSwitchKnobFillOn}"
|
||||
BorderBrush="{ThemeResource ToggleSwitchKnobStrokeOn}"
|
||||
CornerRadius="7"
|
||||
Opacity="0"
|
||||
RenderTransformOrigin="0.5, 0.5">
|
||||
<Border.RenderTransform>
|
||||
<CompositeTransform/>
|
||||
</Border.RenderTransform>
|
||||
</Border>
|
||||
<Rectangle
|
||||
x:Name="SwitchKnobOff"
|
||||
Grid.Column="2"
|
||||
Width="12"
|
||||
Height="12"
|
||||
Margin="-1,0,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Fill="{ThemeResource ToggleSwitchKnobFillOff}"
|
||||
RadiusX="7"
|
||||
RadiusY="7"
|
||||
RenderTransformOrigin="0.5, 0.5">
|
||||
<Rectangle.RenderTransform>
|
||||
<CompositeTransform/>
|
||||
</Rectangle.RenderTransform>
|
||||
</Rectangle>
|
||||
<Grid.RenderTransform>
|
||||
<TranslateTransform x:Name="KnobTranslateTransform"/>
|
||||
</Grid.RenderTransform>
|
||||
</Grid>
|
||||
<Thumb
|
||||
x:Name="SwitchThumb"
|
||||
Grid.RowSpan="3"
|
||||
Grid.ColumnSpan="3"
|
||||
AutomationProperties.AccessibilityView="Raw">
|
||||
<Thumb.Template>
|
||||
<ControlTemplate TargetType="Thumb">
|
||||
<Rectangle Fill="Transparent"/>
|
||||
</ControlTemplate>
|
||||
</Thumb.Template>
|
||||
</Thumb>
|
||||
|
||||
</Grid>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="Stroke">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOff}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOff}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="Fill">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOff}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOff}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Fill">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOff}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOff}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOn}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOn}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Fill">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOn}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOn}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Stroke">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOn}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOn}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchAreaGrid" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchContainerBackground}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchContainerBackground}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Width" EnableDependentAnimation="True" >
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOn"
|
||||
Storyboard.TargetProperty="Width">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="12"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOn"
|
||||
Storyboard.TargetProperty="Height">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="12"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Width" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOff"
|
||||
Storyboard.TargetProperty="Width">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="12"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOff"
|
||||
Storyboard.TargetProperty="Height">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="12"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)">
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchStrokeOffPointerOver}" />
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchStrokeOffPointerOver}"/>
|
||||
</ColorAnimationUsingKeyFrames>
|
||||
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchFillOffPointerOver}" />
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchFillOffPointerOver}"/>
|
||||
</ColorAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Fill">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOffPointerOver}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOffPointerOver}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOnPointerOver}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOnPointerOver}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Fill">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOnPointerOver}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOnPointerOver}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Stroke">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOnPointerOver}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOnPointerOver}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ColorAnimationUsingKeyFrames Storyboard.TargetName="SwitchAreaGrid" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchContainerBackgroundPointerOver}" />
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchContainerBackgroundPointerOver}"/>
|
||||
</ColorAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Width" EnableDependentAnimation="True" >
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOn"
|
||||
Storyboard.TargetProperty="Width">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="14"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOn"
|
||||
Storyboard.TargetProperty="Height">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="14"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Width" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOff"
|
||||
Storyboard.TargetProperty="Width">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="14"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOff"
|
||||
Storyboard.TargetProperty="Height">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="14"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed">
|
||||
|
||||
<VisualState.Setters>
|
||||
<Setter Target="SwitchKnobOn.HorizontalAlignment" Value="Right" />
|
||||
<Setter Target="SwitchKnobOn.Margin" Value="0,0,3,0" />
|
||||
<Setter Target="SwitchKnobOff.HorizontalAlignment" Value="Left" />
|
||||
<Setter Target="SwitchKnobOff.Margin" Value="3,0,0,0" />
|
||||
<Setter Target="SwitchKnobOn.HorizontalAlignment" Value="Right"/>
|
||||
<Setter Target="SwitchKnobOn.Margin" Value="0,0,3,0"/>
|
||||
<Setter Target="SwitchKnobOff.HorizontalAlignment" Value="Left"/>
|
||||
<Setter Target="SwitchKnobOff.Margin" Value="3,0,0,0"/>
|
||||
</VisualState.Setters>
|
||||
|
||||
<Storyboard>
|
||||
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)">
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchStrokeOffPressed}" />
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchStrokeOffPressed}"/>
|
||||
</ColorAnimationUsingKeyFrames>
|
||||
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchFillOffPressed}" />
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchFillOffPressed}"/>
|
||||
</ColorAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Fill">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOnPressed}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOnPressed}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Stroke">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOnPressed}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOnPressed}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Fill">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOffPressed}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOffPressed}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOnPressed}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOnPressed}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ColorAnimationUsingKeyFrames Storyboard.TargetName="SwitchAreaGrid" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchContainerBackgroundPressed}" />
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchContainerBackgroundPressed}"/>
|
||||
</ColorAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Width" EnableDependentAnimation="True" >
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="17" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOn"
|
||||
Storyboard.TargetProperty="Width">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="17"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOn"
|
||||
Storyboard.TargetProperty="Height">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="14"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Width" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="17" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOff"
|
||||
Storyboard.TargetProperty="Width">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="17"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOff"
|
||||
Storyboard.TargetProperty="Height">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlFasterAnimationDuration}"
|
||||
Value="14"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchHeaderForegroundDisabled}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchHeaderForegroundDisabled}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OffContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchContentForegroundDisabled}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchContentForegroundDisabled}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OnContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchContentForegroundDisabled}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchContentForegroundDisabled}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)">
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchStrokeOffDisabled}" />
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchStrokeOffDisabled}"/>
|
||||
</ColorAnimationUsingKeyFrames>
|
||||
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchFillOffDisabled}" />
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchFillOffDisabled}"/>
|
||||
</ColorAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Fill">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOnDisabled}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOnDisabled}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Stroke">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOnDisabled}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOnDisabled}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Fill">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOffDisabled}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOffDisabled}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOnDisabled}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOnDisabled}"/>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ColorAnimationUsingKeyFrames Storyboard.TargetName="SwitchAreaGrid" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchContainerBackgroundDisabled}" />
|
||||
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchContainerBackgroundDisabled}"/>
|
||||
</ColorAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Width" EnableDependentAnimation="True" >
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlNormalAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOn"
|
||||
Storyboard.TargetProperty="Width">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlNormalAnimationDuration}"
|
||||
Value="12"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlNormalAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOn"
|
||||
Storyboard.TargetProperty="Height">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlNormalAnimationDuration}"
|
||||
Value="12"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Width" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlNormalAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOff"
|
||||
Storyboard.TargetProperty="Width">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlNormalAnimationDuration}"
|
||||
Value="12"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlNormalAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
EnableDependentAnimation="True"
|
||||
Storyboard.TargetName="SwitchKnobOff"
|
||||
Storyboard.TargetProperty="Height">
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
|
||||
KeyTime="{StaticResource ControlNormalAnimationDuration}"
|
||||
Value="12"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
@@ -287,111 +535,117 @@
|
||||
<VisualStateGroup x:Name="ToggleStates">
|
||||
|
||||
<VisualStateGroup.Transitions>
|
||||
<VisualTransition x:Name="DraggingToOnTransition"
|
||||
<VisualTransition
|
||||
x:Name="DraggingToOnTransition"
|
||||
GeneratedDuration="0"
|
||||
From="Dragging"
|
||||
To="On"
|
||||
GeneratedDuration="0">
|
||||
To="On">
|
||||
|
||||
<Storyboard>
|
||||
<RepositionThemeAnimation TargetName="SwitchKnob" FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobCurrentToOnOffset}" />
|
||||
<RepositionThemeAnimation FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobCurrentToOnOffset}" TargetName="SwitchKnob"/>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualTransition>
|
||||
<VisualTransition x:Name="OnToDraggingTransition"
|
||||
<VisualTransition
|
||||
x:Name="OnToDraggingTransition"
|
||||
GeneratedDuration="0"
|
||||
From="On"
|
||||
To="Dragging"
|
||||
GeneratedDuration="0">
|
||||
To="Dragging">
|
||||
<Storyboard>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="0" Value="1" />
|
||||
<LinearDoubleKeyFrame KeyTime="0" Value="1"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="0" Value="1" />
|
||||
<LinearDoubleKeyFrame KeyTime="0" Value="1"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="0" Value="0" />
|
||||
<LinearDoubleKeyFrame KeyTime="0" Value="0"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualTransition>
|
||||
<VisualTransition x:Name="DraggingToOffTransition"
|
||||
<VisualTransition
|
||||
x:Name="DraggingToOffTransition"
|
||||
GeneratedDuration="0"
|
||||
From="Dragging"
|
||||
To="Off"
|
||||
GeneratedDuration="0">
|
||||
To="Off">
|
||||
|
||||
<Storyboard>
|
||||
<RepositionThemeAnimation TargetName="SwitchKnob" FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobCurrentToOffOffset}" />
|
||||
<RepositionThemeAnimation FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobCurrentToOffOffset}" TargetName="SwitchKnob"/>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualTransition>
|
||||
<VisualTransition x:Name="OnToOffTransition"
|
||||
<VisualTransition
|
||||
x:Name="OnToOffTransition"
|
||||
GeneratedDuration="0"
|
||||
From="On"
|
||||
To="Off"
|
||||
GeneratedDuration="0">
|
||||
To="Off">
|
||||
|
||||
<Storyboard>
|
||||
<RepositionThemeAnimation TargetName="SwitchKnob" FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobOnToOffOffset}" />
|
||||
<RepositionThemeAnimation FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobOnToOffOffset}" TargetName="SwitchKnob"/>
|
||||
</Storyboard>
|
||||
</VisualTransition>
|
||||
<VisualTransition x:Name="OffToOnTransition"
|
||||
<VisualTransition
|
||||
x:Name="OffToOnTransition"
|
||||
GeneratedDuration="0"
|
||||
From="Off"
|
||||
To="On"
|
||||
GeneratedDuration="0">
|
||||
To="On">
|
||||
|
||||
<Storyboard>
|
||||
<RepositionThemeAnimation TargetName="SwitchKnob" FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobOffToOnOffset}"/>
|
||||
<RepositionThemeAnimation FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobOffToOnOffset}" TargetName="SwitchKnob"/>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualTransition>
|
||||
</VisualStateGroup.Transitions>
|
||||
<VisualState x:Name="Dragging" />
|
||||
<VisualState x:Name="Off" />
|
||||
<VisualState x:Name="Dragging"/>
|
||||
<VisualState x:Name="Off"/>
|
||||
<VisualState x:Name="On">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="KnobTranslateTransform"
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="KnobTranslateTransform"
|
||||
Storyboard.TargetProperty="X"
|
||||
To="20"
|
||||
Duration="0" />
|
||||
Duration="0"/>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Opacity">
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
@@ -401,11 +655,12 @@
|
||||
<VisualState x:Name="OffContent">
|
||||
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="OffContentPresenter"
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="OffContentPresenter"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="1"
|
||||
Duration="0" />
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="OffContentPresenter">
|
||||
Duration="0"/>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OffContentPresenter" Storyboard.TargetProperty="IsHitTestVisible">
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<x:Boolean>True</x:Boolean>
|
||||
@@ -417,11 +672,12 @@
|
||||
<VisualState x:Name="OnContent">
|
||||
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="OnContentPresenter"
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="OnContentPresenter"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="1"
|
||||
Duration="0" />
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="OnContentPresenter">
|
||||
Duration="0"/>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OnContentPresenter" Storyboard.TargetProperty="IsHitTestVisible">
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<x:Boolean>True</x:Boolean>
|
||||
@@ -434,149 +690,11 @@
|
||||
</VisualStateGroup>
|
||||
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ContentPresenter x:Name="HeaderContentPresenter"
|
||||
x:DeferLoadStrategy="Lazy"
|
||||
Grid.Row="0"
|
||||
Content="{TemplateBinding Header}"
|
||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||
Foreground="{ThemeResource ToggleSwitchHeaderForeground}"
|
||||
IsHitTestVisible="False"
|
||||
Margin="{ThemeResource ToggleSwitchTopHeaderMargin}"
|
||||
TextWrapping="Wrap"
|
||||
VerticalAlignment="Top"
|
||||
Visibility="Collapsed"
|
||||
AutomationProperties.AccessibilityView="Raw" />
|
||||
<Grid
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="{ThemeResource ToggleSwitchPreContentMargin}" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="{ThemeResource ToggleSwitchPostContentMargin}" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="12" MaxWidth="12" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid x:Name="SwitchAreaGrid"
|
||||
Grid.RowSpan="3"
|
||||
Grid.ColumnSpan="3"
|
||||
Margin="0,5"
|
||||
contract7Present:CornerRadius="{TemplateBinding CornerRadius}"
|
||||
contract7NotPresent:CornerRadius="{StaticResource ControlCornerRadius}"
|
||||
Control.IsTemplateFocusTarget="True"
|
||||
Background="{ThemeResource ToggleSwitchContainerBackground}" />
|
||||
<ContentPresenter x:Name="OffContentPresenter"
|
||||
Grid.RowSpan="3"
|
||||
Grid.Column="0"
|
||||
Opacity="0"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
IsHitTestVisible="False"
|
||||
Content="{TemplateBinding OffContent}"
|
||||
ContentTemplate="{TemplateBinding OffContentTemplate}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
AutomationProperties.AccessibilityView="Raw" />
|
||||
<ContentPresenter x:Name="OnContentPresenter"
|
||||
Grid.RowSpan="3"
|
||||
Grid.Column="0"
|
||||
Opacity="0"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
IsHitTestVisible="False"
|
||||
Content="{TemplateBinding OnContent}"
|
||||
ContentTemplate="{TemplateBinding OnContentTemplate}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
AutomationProperties.AccessibilityView="Raw" />
|
||||
<Rectangle x:Name="OuterBorder"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Height="20"
|
||||
Width="40"
|
||||
RadiusX="10"
|
||||
RadiusY="10"
|
||||
Fill="{ThemeResource ToggleSwitchFillOff}"
|
||||
Stroke="{ThemeResource ToggleSwitchStrokeOff}"
|
||||
StrokeThickness="{ThemeResource ToggleSwitchOuterBorderStrokeThickness}" />
|
||||
<Rectangle x:Name="SwitchKnobBounds"
|
||||
Grid.Row="1"
|
||||
Height="20"
|
||||
Width="40"
|
||||
RadiusX="10"
|
||||
RadiusY="10"
|
||||
Grid.Column="2"
|
||||
Fill="{ThemeResource ToggleSwitchFillOn}"
|
||||
Stroke="{ThemeResource ToggleSwitchStrokeOn}"
|
||||
StrokeThickness="{ThemeResource ToggleSwitchOnStrokeThickness}"
|
||||
Opacity="0" />
|
||||
<Grid x:Name="SwitchKnob"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
HorizontalAlignment="Left"
|
||||
Width="20"
|
||||
Height="20">
|
||||
<Border x:Name="SwitchKnobOn"
|
||||
Background="{ThemeResource ToggleSwitchKnobFillOn}"
|
||||
BorderBrush="{ThemeResource ToggleSwitchKnobStrokeOn}"
|
||||
contract7Present:BackgroundSizing="OuterBorderEdge"
|
||||
Width="12"
|
||||
Height="12"
|
||||
CornerRadius="7"
|
||||
Grid.Column="2"
|
||||
Opacity="0"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,1,0"
|
||||
RenderTransformOrigin="0.5, 0.5">
|
||||
<Border.RenderTransform>
|
||||
<CompositeTransform/>
|
||||
</Border.RenderTransform>
|
||||
</Border>
|
||||
<Rectangle x:Name="SwitchKnobOff"
|
||||
Fill="{ThemeResource ToggleSwitchKnobFillOff}"
|
||||
Width="12"
|
||||
Height="12"
|
||||
RadiusX="7"
|
||||
Grid.Column="2"
|
||||
RadiusY="7"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="-1,0,0,0"
|
||||
RenderTransformOrigin="0.5, 0.5">
|
||||
<Rectangle.RenderTransform>
|
||||
<CompositeTransform/>
|
||||
</Rectangle.RenderTransform>
|
||||
</Rectangle>
|
||||
<Grid.RenderTransform>
|
||||
<TranslateTransform x:Name="KnobTranslateTransform" />
|
||||
</Grid.RenderTransform>
|
||||
</Grid>
|
||||
<Thumb x:Name="SwitchThumb"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Grid.RowSpan="3"
|
||||
Grid.ColumnSpan="3">
|
||||
<Thumb.Template>
|
||||
<ControlTemplate TargetType="Thumb">
|
||||
<Rectangle Fill="Transparent" />
|
||||
</ControlTemplate>
|
||||
</Thumb.Template>
|
||||
</Thumb>
|
||||
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:controls="using:SettingsUI.Controls"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:SettingsUI.Controls">
|
||||
<Style x:Key="ListViewItemSettingStyle" TargetType="ListViewItem">
|
||||
<Setter Property="Margin" Value="0,0,0,2" />
|
||||
<Setter Property="Padding" Value="0,0,0,0" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Margin" Value="0,0,0,2"/>
|
||||
<Setter Property="Padding" Value="0,0,0,0"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
TargetType="controls:CheckBoxWithDescriptionControl"
|
||||
BasedOn="{StaticResource DefaultCheckBoxStyle}" />
|
||||
|
||||
<Style BasedOn="{StaticResource DefaultCheckBoxStyle}" TargetType="controls:CheckBoxWithDescriptionControl"/>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Style x:Key="OobeSubtitleStyle" TargetType="TextBlock">
|
||||
<Setter Property="Margin" Value="0,16,0,0" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource DefaultTextForegroundThemeBrush}" />
|
||||
<Setter Property="AutomationProperties.HeadingLevel" Value="Level3" />
|
||||
<Setter Property="FontFamily" Value="XamlAutoFontFamily" />
|
||||
<Setter Property="FontSize" Value="{StaticResource BodyTextBlockFontSize}" />
|
||||
<Setter Property="FontWeight" Value="SemiBold" />
|
||||
<Setter Property="TextTrimming" Value="CharacterEllipsis" />
|
||||
<Setter Property="TextWrapping" Value="Wrap" />
|
||||
<Setter Property="LineStackingStrategy" Value="MaxHeight" />
|
||||
<Setter Property="TextLineBounds" Value="Full" />
|
||||
<Setter Property="Margin" Value="0,16,0,0"/>
|
||||
<Setter Property="Foreground" Value="{ThemeResource DefaultTextForegroundThemeBrush}"/>
|
||||
<Setter Property="AutomationProperties.HeadingLevel" Value="Level3"/>
|
||||
<Setter Property="FontFamily" Value="XamlAutoFontFamily"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource BodyTextBlockFontSize}"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
<Setter Property="LineStackingStrategy" Value="MaxHeight"/>
|
||||
<Setter Property="TextLineBounds" Value="Full"/>
|
||||
</Style>
|
||||
|
||||
<x:Double x:Key="SecondaryTextFontSize">12</x:Double>
|
||||
|
||||
@@ -1,29 +1,27 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<StaticResource x:Key="CardBackgroundBrush" ResourceKey="CardBackgroundFillColorDefaultBrush" />
|
||||
<StaticResource x:Key="CardBorderBrush" ResourceKey="CardStrokeColorDefaultBrush" />
|
||||
<StaticResource x:Key="CardPrimaryForegroundBrush" ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="CardBackgroundBrush" ResourceKey="CardBackgroundFillColorDefaultBrush"/>
|
||||
<StaticResource x:Key="CardBorderBrush" ResourceKey="CardStrokeColorDefaultBrush"/>
|
||||
<StaticResource x:Key="CardPrimaryForegroundBrush" ResourceKey="TextFillColorPrimaryBrush"/>
|
||||
<SolidColorBrush x:Key="InfoBarInformationalSeverityBackgroundBrush" Color="#FF34424d"/>
|
||||
<Color x:Key="InfoBarInformationalSeverityIconBackground">#FF5fb2f2</Color>
|
||||
<Thickness x:Key="CardBorderThickness">1</Thickness>
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<StaticResource x:Key="CardBackgroundBrush" ResourceKey="CardBackgroundFillColorDefaultBrush" />
|
||||
<StaticResource x:Key="CardBorderBrush" ResourceKey="CardStrokeColorDefaultBrush" />
|
||||
<StaticResource x:Key="CardPrimaryForegroundBrush" ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="CardBackgroundBrush" ResourceKey="CardBackgroundFillColorDefaultBrush"/>
|
||||
<StaticResource x:Key="CardBorderBrush" ResourceKey="CardStrokeColorDefaultBrush"/>
|
||||
<StaticResource x:Key="CardPrimaryForegroundBrush" ResourceKey="TextFillColorPrimaryBrush"/>
|
||||
<SolidColorBrush x:Key="InfoBarInformationalSeverityBackgroundBrush" Color="#FFd3e7f7"/>
|
||||
<Color x:Key="InfoBarInformationalSeverityIconBackground">#FF0063b1</Color>
|
||||
<Thickness x:Key="CardBorderThickness">1</Thickness>
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="CardBackgroundBrush" ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||
<StaticResource x:Key="CardBorderBrush" ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
<StaticResource x:Key="CardPrimaryForegroundBrush" ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
<StaticResource x:Key="CardBackgroundBrush" ResourceKey="SystemColorButtonFaceColorBrush"/>
|
||||
<StaticResource x:Key="CardBorderBrush" ResourceKey="SystemColorButtonTextColorBrush"/>
|
||||
<StaticResource x:Key="CardPrimaryForegroundBrush" ResourceKey="SystemColorButtonTextColorBrush"/>
|
||||
<SolidColorBrush x:Key="InfoBarInformationalSeverityBackgroundBrush" Color="#FF34424d"/>
|
||||
<Color x:Key="InfoBarInformationalSeverityIconBackground">#FF5fb2f2</Color>
|
||||
<Thickness x:Key="CardBorderThickness">2</Thickness>
|
||||
|
||||
@@ -11,42 +11,38 @@
|
||||
|
||||
<!-- Styles -->
|
||||
<!-- Setting used in a Expander header -->
|
||||
<Style x:Key="ExpanderHeaderSettingStyle"
|
||||
TargetType="controls:Setting">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
<Setter Property="Padding" Value="0,14,0,14" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Style x:Key="ExpanderHeaderSettingStyle" TargetType="controls:Setting">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||
<Setter Property="Padding" Value="0,14,0,14"/>
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
</Style>
|
||||
|
||||
<Thickness x:Key="ExpanderChevronMargin">0,0,8,0</Thickness>
|
||||
|
||||
<!-- Setting used in a Expander header -->
|
||||
<Style x:Key="ExpanderContentSettingStyle"
|
||||
TargetType="controls:Setting">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="0,1,0,0" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardBorderBrush}" />
|
||||
<Setter Property="CornerRadius" Value="0" />
|
||||
<Setter Property="Padding" Value="{StaticResource ExpanderSettingMargin}" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Style x:Key="ExpanderContentSettingStyle" TargetType="controls:Setting">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="BorderThickness" Value="0,1,0,0"/>
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardBorderBrush}"/>
|
||||
<Setter Property="CornerRadius" Value="0"/>
|
||||
<Setter Property="Padding" Value="{StaticResource ExpanderSettingMargin}"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
</Style>
|
||||
|
||||
<!-- Setting expander style -->
|
||||
<Style x:Key="SettingExpanderStyle"
|
||||
TargetType="Expander">
|
||||
<Setter Property="Background" Value="{ThemeResource CardBackgroundBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource CardBorderThickness}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardBorderBrush}" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Style x:Key="SettingExpanderStyle" TargetType="Expander">
|
||||
<Setter Property="Background" Value="{ThemeResource CardBackgroundBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource CardBorderThickness}"/>
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardBorderBrush}"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ExpanderSeparatorStyle"
|
||||
TargetType="Rectangle">
|
||||
<Setter Property="Height" Value="1" />
|
||||
<Setter Property="Stroke" Value="{ThemeResource CardBorderBrush}" />
|
||||
<Style x:Key="ExpanderSeparatorStyle" TargetType="Rectangle">
|
||||
<Setter Property="Height" Value="1"/>
|
||||
<Setter Property="Stroke" Value="{ThemeResource CardBorderBrush}"/>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="../Styles/Common.xaml"/>
|
||||
<ResourceDictionary Source="../Styles/TextBlock.xaml"/>
|
||||
@@ -9,6 +7,6 @@
|
||||
<ResourceDictionary Source="../Themes/Colors.xaml"/>
|
||||
<ResourceDictionary Source="../Themes/SettingsExpanderStyles.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
|
||||
<x:Double x:Key="SettingActionControlMinWidth">240</x:Double>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -26,7 +27,6 @@ public class HttpClientGenerator : ISourceGenerator
|
||||
|
||||
private const string PrimaryHttpMessageHandlerAttributeName = "Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient.PrimaryHttpMessageHandlerAttribute";
|
||||
private const string DynamicSecretAttributeName = "Snap.Hutao.Web.Hoyolab.DynamicSecret.UseDynamicSecretAttribute";
|
||||
private const string IgnoreSetCookieAttributeName = "Snap.Hutao.Web.Hoyolab.Annotation.IgnoreSetCookieAttribute";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Initialize(GeneratorInitializationContext context)
|
||||
@@ -54,7 +54,6 @@ public class HttpClientGenerator : ISourceGenerator
|
||||
// This class is generated by Snap.Hutao.SourceGeneration
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Snap.Hutao.Web.Hoyolab;
|
||||
using Snap.Hutao.Web.Hoyolab.DynamicSecret;
|
||||
using System.Net.Http;
|
||||
|
||||
@@ -83,10 +82,7 @@ internal static partial class IocHttpClientConfiguration
|
||||
|
||||
foreach (INamedTypeSymbol classSymbol in receiver.Classes)
|
||||
{
|
||||
lineBuilder
|
||||
.Clear()
|
||||
.Append("\r\n");
|
||||
|
||||
lineBuilder.Clear().Append("\r\n");
|
||||
lineBuilder.Append(@" services.AddHttpClient<");
|
||||
lineBuilder.Append($"{classSymbol.ToDisplayString()}>(");
|
||||
|
||||
@@ -139,11 +135,6 @@ internal static partial class IocHttpClientConfiguration
|
||||
lineBuilder.Append(".AddHttpMessageHandler<DynamicSecretHandler>()");
|
||||
}
|
||||
|
||||
if (classSymbol.GetAttributes().Any(attr => attr.AttributeClass!.ToDisplayString() == IgnoreSetCookieAttributeName))
|
||||
{
|
||||
lineBuilder.Append(".AddHttpMessageHandler<IgnoreSetCookieHandler>()");
|
||||
}
|
||||
|
||||
lineBuilder.Append(";");
|
||||
|
||||
lines.Add(lineBuilder.ToString());
|
||||
@@ -154,4 +145,34 @@ internal static partial class IocHttpClientConfiguration
|
||||
sourceCodeBuilder.Append(line);
|
||||
}
|
||||
}
|
||||
|
||||
private class HttpClientSyntaxContextReceiver : ISyntaxContextReceiver
|
||||
{
|
||||
/// <summary>
|
||||
/// 注入特性的名称
|
||||
/// </summary>
|
||||
public const string AttributeName = "Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient.HttpClientAttribute";
|
||||
|
||||
/// <summary>
|
||||
/// 所有需要注入的类型符号
|
||||
/// </summary>
|
||||
public List<INamedTypeSymbol> Classes { get; } = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
|
||||
{
|
||||
// any class with at least one attribute is a candidate for injection generation
|
||||
if (context.Node is ClassDeclarationSyntax classDeclarationSyntax && classDeclarationSyntax.AttributeLists.Count > 0)
|
||||
{
|
||||
// get as named type symbol
|
||||
if (context.SemanticModel.GetDeclaredSymbol(classDeclarationSyntax) is INamedTypeSymbol classSymbol)
|
||||
{
|
||||
if (classSymbol.GetAttributes().Any(ad => ad.AttributeClass!.ToDisplayString() == AttributeName))
|
||||
{
|
||||
Classes.Add(classSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Snap.Hutao.SourceGeneration.DedendencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// Created on demand before each generation pass
|
||||
/// </summary>
|
||||
public class HttpClientSyntaxContextReceiver : ISyntaxContextReceiver
|
||||
{
|
||||
/// <summary>
|
||||
/// 注入特性的名称
|
||||
/// </summary>
|
||||
public const string AttributeName = "Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient.HttpClientAttribute";
|
||||
|
||||
/// <summary>
|
||||
/// 所有需要注入的类型符号
|
||||
/// </summary>
|
||||
public List<INamedTypeSymbol> Classes { get; } = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
|
||||
{
|
||||
// any class with at least one attribute is a candidate for injection generation
|
||||
if (context.Node is ClassDeclarationSyntax classDeclarationSyntax && classDeclarationSyntax.AttributeLists.Count > 0)
|
||||
{
|
||||
// get as named type symbol
|
||||
if (context.SemanticModel.GetDeclaredSymbol(classDeclarationSyntax) is INamedTypeSymbol classSymbol)
|
||||
{
|
||||
if (classSymbol.GetAttributes().Any(ad => ad.AttributeClass!.ToDisplayString() == AttributeName))
|
||||
{
|
||||
Classes.Add(classSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -122,4 +123,34 @@ internal static partial class ServiceCollectionExtension
|
||||
sourceCodeBuilder.Append(line);
|
||||
}
|
||||
}
|
||||
|
||||
private class InjectionSyntaxContextReceiver : ISyntaxContextReceiver
|
||||
{
|
||||
/// <summary>
|
||||
/// 注入特性的名称
|
||||
/// </summary>
|
||||
public const string AttributeName = "Snap.Hutao.Core.DependencyInjection.Annotation.InjectionAttribute";
|
||||
|
||||
/// <summary>
|
||||
/// 所有需要注入的类型符号
|
||||
/// </summary>
|
||||
public List<INamedTypeSymbol> Classes { get; } = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
|
||||
{
|
||||
// any class with at least one attribute is a candidate for injection generation
|
||||
if (context.Node is ClassDeclarationSyntax classDeclarationSyntax && classDeclarationSyntax.AttributeLists.Count > 0)
|
||||
{
|
||||
// get as named type symbol
|
||||
if (context.SemanticModel.GetDeclaredSymbol(classDeclarationSyntax) is INamedTypeSymbol classSymbol)
|
||||
{
|
||||
if (classSymbol.GetAttributes().Any(ad => ad.AttributeClass!.ToDisplayString() == AttributeName))
|
||||
{
|
||||
Classes.Add(classSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Snap.Hutao.SourceGeneration.DedendencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// Created on demand before each generation pass
|
||||
/// </summary>
|
||||
public class InjectionSyntaxContextReceiver : ISyntaxContextReceiver
|
||||
{
|
||||
/// <summary>
|
||||
/// 注入特性的名称
|
||||
/// </summary>
|
||||
public const string AttributeName = "Snap.Hutao.Core.DependencyInjection.Annotation.InjectionAttribute";
|
||||
|
||||
/// <summary>
|
||||
/// 所有需要注入的类型符号
|
||||
/// </summary>
|
||||
public List<INamedTypeSymbol> Classes { get; } = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
|
||||
{
|
||||
// any class with at least one attribute is a candidate for injection generation
|
||||
if (context.Node is ClassDeclarationSyntax classDeclarationSyntax && classDeclarationSyntax.AttributeLists.Count > 0)
|
||||
{
|
||||
// get as named type symbol
|
||||
if (context.SemanticModel.GetDeclaredSymbol(classDeclarationSyntax) is INamedTypeSymbol classSymbol)
|
||||
{
|
||||
if (classSymbol.GetAttributes().Any(ad => ad.AttributeClass!.ToDisplayString() == AttributeName))
|
||||
{
|
||||
Classes.Add(classSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// This file is used by Code Analysis to maintain SuppressMessage
|
||||
// attributes that are applied to this project.
|
||||
// Project-level suppressions either have no target or are given
|
||||
// a specific target and scoped to a namespace, type, member, etc.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
[assembly: SuppressMessage("MicrosoftCodeAnalysisReleaseTracking", "RS2008:启用分析器发布跟踪", Justification = "<挂起>", Scope = "member", Target = "~F:Snap.Hutao.SourceGeneration.TodoAnalyzer.Descriptor")]
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
@@ -6,6 +6,7 @@
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -17,15 +18,11 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.1" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435">
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4-beta1.22518.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
52
src/Snap.Hutao/Snap.Hutao.SourceGeneration/TodoAnalyzer.cs
Normal file
52
src/Snap.Hutao/Snap.Hutao.SourceGeneration/TodoAnalyzer.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Snap.Hutao.SourceGeneration;
|
||||
|
||||
/// <summary>
|
||||
/// 高亮TODO
|
||||
/// </summary>
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
internal class TodoAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
private static readonly DiagnosticDescriptor Descriptor =
|
||||
new("SH0001", "TODO 项尚未实现", "此 TODO 项需要实现", "Standard", DiagnosticSeverity.Info, true);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get => ImmutableArray.Create(Descriptor); }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
|
||||
context.EnableConcurrentExecution();
|
||||
|
||||
context.RegisterSyntaxTreeAction(HandleSyntaxTree);
|
||||
}
|
||||
|
||||
private static void HandleSyntaxTree(SyntaxTreeAnalysisContext context)
|
||||
{
|
||||
SyntaxNode root = context.Tree.GetCompilationUnitRoot(context.CancellationToken);
|
||||
foreach (SyntaxTrivia node in root.DescendantTrivia(descendIntoTrivia: true))
|
||||
{
|
||||
switch (node.Kind())
|
||||
{
|
||||
case SyntaxKind.SingleLineCommentTrivia:
|
||||
case SyntaxKind.MultiLineCommentTrivia:
|
||||
string text = node.ToString().ToLowerInvariant();
|
||||
if (text.Contains("todo:"))
|
||||
{
|
||||
string hint = node.ToString().Substring(text.IndexOf("todo:") + 6);
|
||||
DiagnosticDescriptor descriptor = new("SH0001", "TODO 项尚未实现", hint, "Standard", DiagnosticSeverity.Info, true);
|
||||
context.ReportDiagnostic(Diagnostic.Create(descriptor, node.GetLocation()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,50 +13,71 @@
|
||||
<ResourceDictionary Source="ms-appx:///SettingsUI/Themes/SettingsUI.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!--Modify Window title bar color-->
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<Color x:Key="CompatBackgroundColor">#FFF4F4F4</Color>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<Color x:Key="CompatBackgroundColor">#FF242424</Color>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<!-- Modify Window title bar color -->
|
||||
<StaticResource x:Key="WindowCaptionBackground" ResourceKey="ControlFillColorTransparentBrush"/>
|
||||
<StaticResource x:Key="WindowCaptionBackgroundDisabled" ResourceKey="ControlFillColorTransparentBrush"/>
|
||||
<!--Page Transparent Background-->
|
||||
<!-- Page Transparent Background -->
|
||||
<StaticResource x:Key="ApplicationPageBackgroundThemeBrush" ResourceKey="ControlFillColorTransparentBrush"/>
|
||||
<!--IconFont-->
|
||||
<!-- IconFont -->
|
||||
<FontFamily x:Key="SymbolThemeFontFamily">ms-appx:///Resource/Font/Segoe Fluent Icons.ttf#Segoe Fluent Icons</FontFamily>
|
||||
<!--InfoBar Resource-->
|
||||
<!-- InfoBar Resource -->
|
||||
<Thickness x:Key="InfoBarIconMargin">6,16,16,16</Thickness>
|
||||
<Thickness x:Key="InfoBarContentRootPadding">16,0,0,0</Thickness>
|
||||
<!--Pivot Resource-->
|
||||
<!-- Pivot Resource -->
|
||||
<x:Double x:Key="PivotHeaderItemFontSize">16</x:Double>
|
||||
<Thickness x:Key="PivotHeaderItemMargin">16,0,0,0</Thickness>
|
||||
<Thickness x:Key="PivotItemMargin">0</Thickness>
|
||||
<!--CornerRadius-->
|
||||
<!-- CornerRadius -->
|
||||
<CornerRadius x:Key="CompatCornerRadius">6</CornerRadius>
|
||||
<CornerRadius x:Key="CompatCornerRadiusTop">6,6,0,0</CornerRadius>
|
||||
<CornerRadius x:Key="CompatCornerRadiusRight">0,6,6,0</CornerRadius>
|
||||
<CornerRadius x:Key="CompatCornerRadiusBottom">0,0,6,6</CornerRadius>
|
||||
<CornerRadius x:Key="CompatCornerRadiusSmall">2</CornerRadius>
|
||||
<!--Converters-->
|
||||
<!-- Converters -->
|
||||
<cwuc:BoolNegationConverter x:Key="BoolNegationConverter"/>
|
||||
<cwuc:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
||||
<shmmc:AchievementIconConverter x:Key="AchievementIconConverter"/>
|
||||
<shmmc:AvatarCardConverter x:Key="AvatarCardConverter"/>
|
||||
<shmmc:AvatarIconConverter x:Key="AvatarIconConverter"/>
|
||||
<shmmc:AvatarNameCardPicConverter x:Key="AvatarNameCardPicConverter"/>
|
||||
<shmmc:AvatarSideIconConverter x:Key="AvatarSideIconConverter"/>
|
||||
<shmmc:DescParamDescriptor x:Key="DescParamDescriptor"/>
|
||||
<shmmc:ElementNameIconConverter x:Key="ElementNameIconConverter"/>
|
||||
<shmmc:EquipIconConverter x:Key="EquipIconConverter"/>
|
||||
<shmmc:GachaAvatarImgConverter x:Key="GachaAvatarImgConverter"/>
|
||||
<shmmc:GachaAvatarIconConverter x:Key="GachaAvatarIconConverter"/>
|
||||
<shmmc:GachaEquipIconConverter x:Key="GachaEquipIconConverter"/>
|
||||
<shmmc:ItemIconConverter x:Key="ItemIconConverter"/>
|
||||
<shmmc:PropertyInfoDescriptor x:Key="PropertyDescriptor"/>
|
||||
<shmmc:QualityColorConverter x:Key="QualityColorConverter"/>
|
||||
<shmmc:WeaponTypeIconConverter x:Key="WeaponTypeIconConverter"/>
|
||||
<shvc:BoolToVisibilityRevertConverter x:Key="BoolToVisibilityRevertConverter"/>
|
||||
|
||||
<!--Styles-->
|
||||
<shvc:EmptyObjectToVisibilityConverter x:Key="EmptyObjectToVisibilityConverter"/>
|
||||
|
||||
<!-- Styles -->
|
||||
<Style
|
||||
x:Key="LargeGridViewItemStyle"
|
||||
TargetType="GridViewItem"
|
||||
BasedOn="{StaticResource DefaultGridViewItemStyle}">
|
||||
BasedOn="{StaticResource DefaultGridViewItemStyle}"
|
||||
TargetType="GridViewItem">
|
||||
<Setter Property="Margin" Value="0,0,12,12"/>
|
||||
</Style>
|
||||
<!--ItemsPanelTemplate-->
|
||||
|
||||
<Style x:Key="BorderCardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="{ThemeResource CardBackgroundFillColorDefaultBrush}"/>
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="CornerRadius" Value="{StaticResource CompatCornerRadius}"/>
|
||||
</Style>
|
||||
<!-- ItemsPanelTemplate -->
|
||||
<ItemsPanelTemplate x:Key="ItemsStackPanelTemplate">
|
||||
<ItemsStackPanel/>
|
||||
</ItemsPanelTemplate>
|
||||
|
||||
@@ -36,28 +36,35 @@ public partial class App : Application
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
[SuppressMessage("", "VSTHRD100")]
|
||||
protected override async void OnLaunched(LaunchActivatedEventArgs args)
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
||||
{
|
||||
AppActivationArguments activatedEventArgs = AppInstance.GetCurrent().GetActivatedEventArgs();
|
||||
AppInstance firstInstance = AppInstance.FindOrRegisterForKey("main");
|
||||
|
||||
if (firstInstance.IsCurrent)
|
||||
try
|
||||
{
|
||||
// manually invoke
|
||||
Activation.Activate(firstInstance, activatedEventArgs);
|
||||
firstInstance.Activated += Activation.Activate;
|
||||
ToastNotificationManagerCompat.OnActivated += Activation.NotificationActivate;
|
||||
AppActivationArguments activatedEventArgs = AppInstance.GetCurrent().GetActivatedEventArgs();
|
||||
AppInstance firstInstance = AppInstance.FindOrRegisterForKey("main");
|
||||
|
||||
logger.LogInformation(EventIds.CommonLog, "Snap Hutao | {name} : {version}", CoreEnvironment.FamilyName, CoreEnvironment.Version);
|
||||
logger.LogInformation(EventIds.CommonLog, "Cache folder : {folder}", ApplicationData.Current.TemporaryFolder.Path);
|
||||
if (firstInstance.IsCurrent)
|
||||
{
|
||||
// manually invoke
|
||||
Activation.NonRedirectToActivate(firstInstance, activatedEventArgs);
|
||||
firstInstance.Activated += Activation.Activate;
|
||||
ToastNotificationManagerCompat.OnActivated += Activation.NotificationActivate;
|
||||
|
||||
JumpListHelper.ConfigAsync().SafeForget(logger);
|
||||
logger.LogInformation(EventIds.CommonLog, "Snap Hutao | {name} : {version}", CoreEnvironment.FamilyName, CoreEnvironment.Version);
|
||||
logger.LogInformation(EventIds.CommonLog, "Cache folder : {folder}", ApplicationData.Current.TemporaryFolder.Path);
|
||||
|
||||
JumpListHelper.ConfigureAsync().SafeForget(logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Redirect the activation (and args) to the "main" instance, and exit.
|
||||
firstInstance.RedirectActivationTo(activatedEventArgs);
|
||||
Process.GetCurrentProcess().Kill();
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception)
|
||||
{
|
||||
// Redirect the activation (and args) to the "main" instance, and exit.
|
||||
await firstInstance.RedirectActivationToAsync(activatedEventArgs);
|
||||
// AppInstance.GetCurrent() calls failed
|
||||
Process.GetCurrentProcess().Kill();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,11 @@ namespace Snap.Hutao.Context.Database;
|
||||
/// <summary>
|
||||
/// 应用程序数据库上下文
|
||||
/// </summary>
|
||||
public class AppDbContext : DbContext
|
||||
public sealed class AppDbContext : DbContext
|
||||
{
|
||||
private readonly Guid contextId;
|
||||
private readonly ILogger<AppDbContext>? logger;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的应用程序数据库上下文
|
||||
/// </summary>
|
||||
@@ -21,6 +24,19 @@ public class AppDbContext : DbContext
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的应用程序数据库上下文
|
||||
/// </summary>
|
||||
/// <param name="options">选项</param>
|
||||
/// <param name="logger">日志器</param>
|
||||
public AppDbContext(DbContextOptions<AppDbContext> options, ILogger<AppDbContext> logger)
|
||||
: this(options)
|
||||
{
|
||||
contextId = Guid.NewGuid();
|
||||
this.logger = logger;
|
||||
logger.LogInformation("AppDbContext[{id}] created.", contextId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置
|
||||
/// </summary>
|
||||
@@ -66,6 +82,41 @@ public class AppDbContext : DbContext
|
||||
/// </summary>
|
||||
public DbSet<DailyNoteEntry> DailyNotes { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 对象缓存
|
||||
/// </summary>
|
||||
public DbSet<ObjectCacheEntry> ObjectCache { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 培养计划
|
||||
/// </summary>
|
||||
public DbSet<CultivateProject> CultivateProjects { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 培养入口点
|
||||
/// </summary>
|
||||
public DbSet<CultivateEntry> CultivateEntries { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 培养消耗物品
|
||||
/// </summary>
|
||||
public DbSet<CultivateItem> CultivateItems { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 背包内物品
|
||||
/// </summary>
|
||||
public DbSet<InventoryItem> InventoryItems { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 背包内武器
|
||||
/// </summary>
|
||||
public DbSet<InventoryWeapon> InventoryWeapons { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 背包内圣遗物
|
||||
/// </summary>
|
||||
public DbSet<InventoryReliquary> InventoryReliquaries { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个临时的应用程序数据库上下文
|
||||
/// </summary>
|
||||
@@ -76,12 +127,20 @@ public class AppDbContext : DbContext
|
||||
return new(new DbContextOptionsBuilder<AppDbContext>().UseSqlite(sqlConnectionString).Options);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
logger?.LogInformation("AppDbContext[{id}] disposed.", contextId);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.ApplyConfiguration(new AvatarInfoConfiguration())
|
||||
.ApplyConfiguration(new UserConfiguration())
|
||||
.ApplyConfiguration(new DailyNoteEntryConfiguration());
|
||||
.ApplyConfiguration(new DailyNoteEntryConfiguration())
|
||||
.ApplyConfiguration(new InventoryReliquaryConfiguration());
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.IO;
|
||||
using Windows.ApplicationModel;
|
||||
|
||||
namespace Snap.Hutao.Context.FileSystem.Location;
|
||||
|
||||
@@ -19,7 +20,10 @@ internal class HutaoLocation : IFileSystemLocation
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
string myDocument = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
|
||||
path = Path.GetFullPath(Path.Combine(myDocument, "Hutao"));
|
||||
|
||||
// 将测试版与正式版的文件目录分离
|
||||
string folderName = Package.Current.PublisherDisplayName == "DGP Studio CI" ? "HutaoAlpha" : "Hutao";
|
||||
path = Path.GetFullPath(Path.Combine(myDocument, folderName));
|
||||
}
|
||||
|
||||
return path;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.WinUI.UI.Behaviors;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Snap.Hutao.Control.Behavior;
|
||||
|
||||
/// <summary>
|
||||
/// AppTitleBar Workaround
|
||||
/// https://github.com/microsoft/microsoft-ui-xaml/issues/7756
|
||||
/// </summary>
|
||||
internal class ComboBoxExtendsContentIntoTitleBarWorkaroundBehavior : BehaviorBase<ComboBox>
|
||||
{
|
||||
private readonly IMessenger messenger;
|
||||
|
||||
/// <summary>
|
||||
/// AppTitleBar Workaround
|
||||
/// </summary>
|
||||
public ComboBoxExtendsContentIntoTitleBarWorkaroundBehavior()
|
||||
{
|
||||
messenger = Ioc.Default.GetRequiredService<IMessenger>();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnAssociatedObjectLoaded()
|
||||
{
|
||||
AssociatedObject.DropDownOpened += OnDropDownOpened;
|
||||
AssociatedObject.DropDownClosed += OnDropDownClosed;
|
||||
}
|
||||
|
||||
private void OnDropDownOpened(object? sender, object e)
|
||||
{
|
||||
messenger.Send(new Message.FlyoutOpenCloseMessage(true));
|
||||
}
|
||||
|
||||
private void OnDropDownClosed(object? sender, object e)
|
||||
{
|
||||
messenger.Send(new Message.FlyoutOpenCloseMessage(false));
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ internal class InvokeCommandOnUnloadedBehavior : BehaviorBase<UIElement>
|
||||
/// <inheritdoc/>
|
||||
protected override void OnDetaching()
|
||||
{
|
||||
// 由于卸载顺序问题,必须重写此方法才能正确触发命令
|
||||
if (Command != null && Command.CanExecute(null))
|
||||
{
|
||||
Command.Execute(null);
|
||||
|
||||
78
src/Snap.Hutao/Snap.Hutao/Control/Media/Bgra8.cs
Normal file
78
src/Snap.Hutao/Snap.Hutao/Control/Media/Bgra8.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using Windows.UI;
|
||||
|
||||
namespace Snap.Hutao.Control.Media;
|
||||
|
||||
/// <summary>
|
||||
/// BGRA8 结构
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct Bgra8
|
||||
{
|
||||
/// <summary>
|
||||
/// B
|
||||
/// </summary>
|
||||
[FieldOffset(0)]
|
||||
public byte B;
|
||||
|
||||
/// <summary>
|
||||
/// G
|
||||
/// </summary>
|
||||
[FieldOffset(1)]
|
||||
public byte G;
|
||||
|
||||
/// <summary>
|
||||
/// R
|
||||
/// </summary>
|
||||
[FieldOffset(2)]
|
||||
public byte R;
|
||||
|
||||
/// <summary>
|
||||
/// A
|
||||
/// </summary>
|
||||
[FieldOffset(3)]
|
||||
public byte A;
|
||||
|
||||
[FieldOffset(0)]
|
||||
private readonly uint data;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的 BGRA8 结构
|
||||
/// </summary>
|
||||
/// <param name="b">B</param>
|
||||
/// <param name="g">G</param>
|
||||
/// <param name="r">R</param>
|
||||
/// <param name="a">A</param>
|
||||
public Bgra8(byte b, byte g, byte r, byte a)
|
||||
{
|
||||
B = b;
|
||||
G = g;
|
||||
R = r;
|
||||
A = a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从Color值转换
|
||||
/// </summary>
|
||||
/// <param name="color">颜色</param>
|
||||
/// <returns>新的 BGRA8 结构</returns>
|
||||
public static Bgra8 FromColor(Color color)
|
||||
{
|
||||
return new(color.B, color.G, color.R, color.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从RGB值转换
|
||||
/// </summary>
|
||||
/// <param name="r">R</param>
|
||||
/// <param name="g">G</param>
|
||||
/// <param name="b">B</param>
|
||||
/// <returns>新的 BGRA8 结构</returns>
|
||||
public static Bgra8 FromRgb(byte r, byte g, byte b)
|
||||
{
|
||||
return new(b, g, r, 0xFF);
|
||||
}
|
||||
}
|
||||
175
src/Snap.Hutao/Snap.Hutao/Control/Media/Rgba8.cs
Normal file
175
src/Snap.Hutao/Snap.Hutao/Control/Media/Rgba8.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// Some part of this file came from:
|
||||
// https://github.com/xunkong/desktop/tree/main/src/Desktop/Desktop/Pages/CharacterInfoPage.xaml.cs
|
||||
|
||||
using CommunityToolkit.WinUI;
|
||||
using System.Runtime.InteropServices;
|
||||
using Windows.UI;
|
||||
|
||||
namespace Snap.Hutao.Control.Media;
|
||||
|
||||
/// <summary>
|
||||
/// RGBA 颜色
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct Rgba8
|
||||
{
|
||||
/// <summary>
|
||||
/// R
|
||||
/// </summary>
|
||||
[FieldOffset(3)]
|
||||
public byte R;
|
||||
|
||||
/// <summary>
|
||||
/// G
|
||||
/// </summary>
|
||||
[FieldOffset(2)]
|
||||
public byte G;
|
||||
|
||||
/// <summary>
|
||||
/// B
|
||||
/// </summary>
|
||||
[FieldOffset(1)]
|
||||
public byte B;
|
||||
|
||||
/// <summary>
|
||||
/// A
|
||||
/// </summary>
|
||||
[FieldOffset(0)]
|
||||
public byte A;
|
||||
|
||||
[FieldOffset(0)]
|
||||
private readonly uint data;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的 RGBA8 颜色
|
||||
/// </summary>
|
||||
/// <param name="hex">色值字符串</param>
|
||||
public Rgba8(ReadOnlySpan<char> hex)
|
||||
{
|
||||
Must.Argument(hex.Length == 8, "色值长度不为8");
|
||||
R = 0;
|
||||
G = 0;
|
||||
B = 0;
|
||||
A = 0;
|
||||
data = Convert.ToUInt32(hex.ToString(), 16);
|
||||
}
|
||||
|
||||
private Rgba8(byte r, byte g, byte b, byte a)
|
||||
{
|
||||
data = 0;
|
||||
R = r;
|
||||
G = g;
|
||||
B = b;
|
||||
A = a;
|
||||
}
|
||||
|
||||
public static implicit operator Color(Rgba8 hexColor)
|
||||
{
|
||||
return Color.FromArgb(hexColor.A, hexColor.R, hexColor.G, hexColor.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 HSL 颜色转换
|
||||
/// </summary>
|
||||
/// <param name="hsl">HSL 颜色</param>
|
||||
/// <returns>RGBA8颜色</returns>
|
||||
public static Rgba8 FromHsl(HslColor hsl)
|
||||
{
|
||||
double chroma = (1 - Math.Abs((2 * hsl.L) - 1)) * hsl.S;
|
||||
double h1 = hsl.H / 60;
|
||||
double x = chroma * (1 - Math.Abs((h1 % 2) - 1));
|
||||
double m = hsl.L - (0.5 * chroma);
|
||||
double r1, g1, b1;
|
||||
|
||||
if (h1 < 1)
|
||||
{
|
||||
r1 = chroma;
|
||||
g1 = x;
|
||||
b1 = 0;
|
||||
}
|
||||
else if (h1 < 2)
|
||||
{
|
||||
r1 = x;
|
||||
g1 = chroma;
|
||||
b1 = 0;
|
||||
}
|
||||
else if (h1 < 3)
|
||||
{
|
||||
r1 = 0;
|
||||
g1 = chroma;
|
||||
b1 = x;
|
||||
}
|
||||
else if (h1 < 4)
|
||||
{
|
||||
r1 = 0;
|
||||
g1 = x;
|
||||
b1 = chroma;
|
||||
}
|
||||
else if (h1 < 5)
|
||||
{
|
||||
r1 = x;
|
||||
g1 = 0;
|
||||
b1 = chroma;
|
||||
}
|
||||
else
|
||||
{
|
||||
r1 = chroma;
|
||||
g1 = 0;
|
||||
b1 = x;
|
||||
}
|
||||
|
||||
byte r = (byte)(255 * (r1 + m));
|
||||
byte g = (byte)(255 * (g1 + m));
|
||||
byte b = (byte)(255 * (b1 + m));
|
||||
byte a = (byte)(255 * hsl.A);
|
||||
|
||||
return new(r, g, b, a);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换到 HSL 颜色
|
||||
/// </summary>
|
||||
/// <returns>HSL 颜色</returns>
|
||||
public HslColor ToHsl()
|
||||
{
|
||||
const double toDouble = 1.0 / 255;
|
||||
double r = toDouble * R;
|
||||
double g = toDouble * G;
|
||||
double b = toDouble * B;
|
||||
double max = Math.Max(Math.Max(r, g), b);
|
||||
double min = Math.Min(Math.Min(r, g), b);
|
||||
double chroma = max - min;
|
||||
double h1;
|
||||
|
||||
if (chroma == 0)
|
||||
{
|
||||
h1 = 0;
|
||||
}
|
||||
else if (max == r)
|
||||
{
|
||||
// The % operator doesn't do proper modulo on negative
|
||||
// numbers, so we'll add 6 before using it
|
||||
h1 = (((g - b) / chroma) + 6) % 6;
|
||||
}
|
||||
else if (max == g)
|
||||
{
|
||||
h1 = 2 + ((b - r) / chroma);
|
||||
}
|
||||
else
|
||||
{
|
||||
h1 = 4 + ((r - g) / chroma);
|
||||
}
|
||||
|
||||
double lightness = 0.5 * (max + min);
|
||||
double saturation = chroma == 0 ? 0 : chroma / (1 - Math.Abs((2 * lightness) - 1));
|
||||
|
||||
HslColor ret;
|
||||
ret.H = 60 * h1;
|
||||
ret.S = saturation;
|
||||
ret.L = lightness;
|
||||
ret.A = toDouble * A;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Windows.Foundation;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.System.WinRT;
|
||||
using WinRT;
|
||||
|
||||
namespace Snap.Hutao.Control.Media;
|
||||
|
||||
/// <summary>
|
||||
/// 软件位图拓展
|
||||
/// </summary>
|
||||
public static class SoftwareBitmapExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 混合模式 正常
|
||||
/// </summary>
|
||||
/// <param name="softwareBitmap">软件位图</param>
|
||||
/// <param name="tint">底色</param>
|
||||
public static unsafe void NormalBlend(this SoftwareBitmap softwareBitmap, Bgra8 tint)
|
||||
{
|
||||
using (BitmapBuffer buffer = softwareBitmap.LockBuffer(BitmapBufferAccessMode.ReadWrite))
|
||||
{
|
||||
using (IMemoryBufferReference reference = buffer.CreateReference())
|
||||
{
|
||||
reference.As<IMemoryBufferByteAccess>().GetBuffer(out byte* data, out uint length);
|
||||
|
||||
for (int i = 0; i < length; i += 4)
|
||||
{
|
||||
Bgra8* pixel = (Bgra8*)(data + i);
|
||||
byte baseAlpha = pixel->A;
|
||||
pixel->B = (byte)(((pixel->B * baseAlpha) + (tint.B * (0xFF - baseAlpha))) / 0xFF);
|
||||
pixel->G = (byte)(((pixel->G * baseAlpha) + (tint.G * (0xFF - baseAlpha))) / 0xFF);
|
||||
pixel->R = (byte)(((pixel->R * baseAlpha) + (tint.R * (0xFF - baseAlpha))) / 0xFF);
|
||||
pixel->A = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,30 @@
|
||||
<UserControl
|
||||
x:Class="Snap.Hutao.Control.Panel.PanelSelector"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
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"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<SplitButton Padding="0,6" Click="SplitButtonClick" Loaded="SplitButtonLoaded">
|
||||
<SplitButton
|
||||
Padding="0,6"
|
||||
Click="SplitButtonClick"
|
||||
Loaded="SplitButtonLoaded">
|
||||
<SplitButton.Content>
|
||||
<FontIcon Name="IconPresenter" Glyph=""/>
|
||||
</SplitButton.Content>
|
||||
<SplitButton.Flyout>
|
||||
<MenuFlyout>
|
||||
<RadioMenuFlyoutItem
|
||||
Tag="List"
|
||||
Click="RadioMenuFlyoutItemClick"
|
||||
Icon="{shcm:FontIcon Glyph=}"
|
||||
Tag="List"
|
||||
Text="列表"/>
|
||||
<RadioMenuFlyoutItem
|
||||
Tag="Grid"
|
||||
Click="RadioMenuFlyoutItemClick"
|
||||
Icon="{shcm:FontIcon Glyph=}"
|
||||
Tag="Grid"
|
||||
Text="网格"/>
|
||||
</MenuFlyout>
|
||||
</SplitButton.Flyout>
|
||||
|
||||
@@ -8,8 +8,8 @@ using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Documents;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Snap.Hutao.Control.Media;
|
||||
using Snap.Hutao.Core;
|
||||
using System.Runtime.InteropServices;
|
||||
using Windows.UI;
|
||||
|
||||
namespace Snap.Hutao.Control.Text;
|
||||
@@ -19,8 +19,7 @@ namespace Snap.Hutao.Control.Text;
|
||||
/// </summary>
|
||||
public class DescriptionTextBlock : ContentControl
|
||||
{
|
||||
private static readonly DependencyProperty DescriptionProperty =
|
||||
Property<DescriptionTextBlock>.Depend(nameof(Description), string.Empty, OnDescriptionChanged);
|
||||
private static readonly DependencyProperty DescriptionProperty = Property<DescriptionTextBlock>.Depend(nameof(Description), string.Empty, OnDescriptionChanged);
|
||||
|
||||
private static readonly int ColorTagFullLength = "<color=#FFFFFFFF></color>".Length;
|
||||
private static readonly int ColorTagLeftLength = "<color=#FFFFFFFF>".Length;
|
||||
@@ -34,7 +33,10 @@ public class DescriptionTextBlock : ContentControl
|
||||
public DescriptionTextBlock()
|
||||
{
|
||||
IsTabStop = false;
|
||||
Content = new TextBlock();
|
||||
Content = new TextBlock()
|
||||
{
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
};
|
||||
|
||||
ActualThemeChanged += OnActualThemeChanged;
|
||||
}
|
||||
@@ -76,7 +78,7 @@ public class DescriptionTextBlock : ContentControl
|
||||
else if (description[i] == '<' && description[i + 1] == 'c')
|
||||
{
|
||||
AppendText(text, description[last..i]);
|
||||
HexColor color = new(description.Slice(i + 8, 8));
|
||||
Rgba8 color = new(description.Slice(i + 8, 8));
|
||||
int length = description[(i + ColorTagLeftLength)..].IndexOf('<');
|
||||
AppendColorText(text, description.Slice(i + ColorTagLeftLength, length), color);
|
||||
|
||||
@@ -112,7 +114,7 @@ public class DescriptionTextBlock : ContentControl
|
||||
text.Inlines.Add(new Run { Text = slice.ToString() });
|
||||
}
|
||||
|
||||
private static void AppendColorText(TextBlock text, ReadOnlySpan<char> slice, HexColor color)
|
||||
private static void AppendColorText(TextBlock text, ReadOnlySpan<char> slice, Rgba8 color)
|
||||
{
|
||||
Color targetColor;
|
||||
if (ThemeHelper.IsDarkMode(text.ActualTheme))
|
||||
@@ -123,7 +125,7 @@ public class DescriptionTextBlock : ContentControl
|
||||
{
|
||||
HslColor hsl = color.ToHsl();
|
||||
hsl.L *= 0.3;
|
||||
targetColor = HexColor.FromHsl(hsl);
|
||||
targetColor = Rgba8.FromHsl(hsl);
|
||||
}
|
||||
|
||||
text.Inlines.Add(new Run
|
||||
@@ -151,138 +153,4 @@ public class DescriptionTextBlock : ContentControl
|
||||
{
|
||||
ApplyDescription((TextBlock)Content, Description);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
private struct HexColor
|
||||
{
|
||||
[FieldOffset(3)]
|
||||
public byte R;
|
||||
[FieldOffset(2)]
|
||||
public byte G;
|
||||
[FieldOffset(1)]
|
||||
public byte B;
|
||||
[FieldOffset(0)]
|
||||
public byte A;
|
||||
|
||||
[FieldOffset(0)]
|
||||
private readonly uint data;
|
||||
|
||||
public HexColor(ReadOnlySpan<char> hex)
|
||||
{
|
||||
Must.Argument(hex.Length == 8, "色值长度不为8");
|
||||
R = 0;
|
||||
G = 0;
|
||||
B = 0;
|
||||
A = 0;
|
||||
data = Convert.ToUInt32(hex.ToString(), 16);
|
||||
}
|
||||
|
||||
private HexColor(byte r, byte g, byte b, byte a)
|
||||
{
|
||||
data = 0;
|
||||
R = r;
|
||||
G = g;
|
||||
B = b;
|
||||
A = a;
|
||||
}
|
||||
|
||||
public static implicit operator Color(HexColor hexColor)
|
||||
{
|
||||
return Color.FromArgb(hexColor.A, hexColor.R, hexColor.G, hexColor.B);
|
||||
}
|
||||
|
||||
public static HexColor FromHsl(HslColor hsl)
|
||||
{
|
||||
double chroma = (1 - Math.Abs((2 * hsl.L) - 1)) * hsl.S;
|
||||
double h1 = hsl.H / 60;
|
||||
double x = chroma * (1 - Math.Abs((h1 % 2) - 1));
|
||||
double m = hsl.L - (0.5 * chroma);
|
||||
double r1, g1, b1;
|
||||
|
||||
if (h1 < 1)
|
||||
{
|
||||
r1 = chroma;
|
||||
g1 = x;
|
||||
b1 = 0;
|
||||
}
|
||||
else if (h1 < 2)
|
||||
{
|
||||
r1 = x;
|
||||
g1 = chroma;
|
||||
b1 = 0;
|
||||
}
|
||||
else if (h1 < 3)
|
||||
{
|
||||
r1 = 0;
|
||||
g1 = chroma;
|
||||
b1 = x;
|
||||
}
|
||||
else if (h1 < 4)
|
||||
{
|
||||
r1 = 0;
|
||||
g1 = x;
|
||||
b1 = chroma;
|
||||
}
|
||||
else if (h1 < 5)
|
||||
{
|
||||
r1 = x;
|
||||
g1 = 0;
|
||||
b1 = chroma;
|
||||
}
|
||||
else
|
||||
{
|
||||
r1 = chroma;
|
||||
g1 = 0;
|
||||
b1 = x;
|
||||
}
|
||||
|
||||
byte r = (byte)(255 * (r1 + m));
|
||||
byte g = (byte)(255 * (g1 + m));
|
||||
byte b = (byte)(255 * (b1 + m));
|
||||
byte a = (byte)(255 * hsl.A);
|
||||
|
||||
return new(r, g, b, a);
|
||||
}
|
||||
|
||||
public HslColor ToHsl()
|
||||
{
|
||||
const double toDouble = 1.0 / 255;
|
||||
double r = toDouble * R;
|
||||
double g = toDouble * G;
|
||||
double b = toDouble * B;
|
||||
double max = Math.Max(Math.Max(r, g), b);
|
||||
double min = Math.Min(Math.Min(r, g), b);
|
||||
double chroma = max - min;
|
||||
double h1;
|
||||
|
||||
if (chroma == 0)
|
||||
{
|
||||
h1 = 0;
|
||||
}
|
||||
else if (max == r)
|
||||
{
|
||||
// The % operator doesn't do proper modulo on negative
|
||||
// numbers, so we'll add 6 before using it
|
||||
h1 = (((g - b) / chroma) + 6) % 6;
|
||||
}
|
||||
else if (max == g)
|
||||
{
|
||||
h1 = 2 + ((b - r) / chroma);
|
||||
}
|
||||
else
|
||||
{
|
||||
h1 = 4 + ((r - g) / chroma);
|
||||
}
|
||||
|
||||
double lightness = 0.5 * (max + min);
|
||||
double saturation = chroma == 0 ? 0 : chroma / (1 - Math.Abs((2 * lightness) - 1));
|
||||
|
||||
HslColor ret;
|
||||
ret.H = 60 * h1;
|
||||
ret.S = saturation;
|
||||
ret.L = lightness;
|
||||
ret.A = toDouble * A;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Core.Logging;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
@@ -236,12 +237,17 @@ public class ImageCache : IImageCache
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (message.StatusCode == HttpStatusCode.TooManyRequests)
|
||||
{
|
||||
retryCount++;
|
||||
TimeSpan delay = message.Headers.RetryAfter?.Delta ?? RetryCountToDelay[retryCount];
|
||||
logger.LogInformation("Retry after {delay}.", delay);
|
||||
await Task.Delay(delay).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (retryCount == 3)
|
||||
|
||||
@@ -25,6 +25,17 @@ public class CommandLineBuilder
|
||||
return condition ? Append(name, value) : this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当参数不为 null 时添加参数
|
||||
/// </summary>
|
||||
/// <param name="name">参数名称</param>
|
||||
/// <param name="value">值</param>
|
||||
/// <returns>命令行建造器</returns>
|
||||
public CommandLineBuilder AppendIfNotNull(string name, object? value = null)
|
||||
{
|
||||
return AppendIf(name, value != null, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加参数
|
||||
/// </summary>
|
||||
@@ -37,12 +48,6 @@ public class CommandLineBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ToString"/>
|
||||
public string Build()
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
|
||||
@@ -5,8 +5,10 @@ using Microsoft.Win32;
|
||||
using Snap.Hutao.Core.Convert;
|
||||
using Snap.Hutao.Core.Json;
|
||||
using Snap.Hutao.Extension;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.Win32.Foundation;
|
||||
|
||||
namespace Snap.Hutao.Core;
|
||||
|
||||
@@ -20,10 +22,15 @@ internal static class CoreEnvironment
|
||||
/// </summary>
|
||||
public const string HoyolabUA = $"Mozilla/5.0 (Windows NT 10.0; Win64; x64) miHoYoBBS/{HoyolabXrpcVersion}";
|
||||
|
||||
/// <summary>
|
||||
/// 米游社移动端请求UA
|
||||
/// </summary>
|
||||
public const string HoyolabMobileUA = $"Mozilla/5.0 (Linux; Android 12) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/106.0.5249.126 Mobile Safari/537.36 miHoYoBBS/{HoyolabXrpcVersion}";
|
||||
|
||||
/// <summary>
|
||||
/// 米游社 Rpc 版本
|
||||
/// </summary>
|
||||
public const string HoyolabXrpcVersion = "2.41.0";
|
||||
public const string HoyolabXrpcVersion = "2.42.1";
|
||||
|
||||
/// <summary>
|
||||
/// 标准UA
|
||||
|
||||
@@ -23,33 +23,6 @@ public static class DbSetExtension
|
||||
return dbSet.GetService<ICurrentDbContext>().Context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或添加一个对应的实体
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">实体类型</typeparam>
|
||||
/// <param name="dbSet">数据库集</param>
|
||||
/// <param name="predicate">谓词</param>
|
||||
/// <param name="entityFactory">实体工厂</param>
|
||||
/// <param name="added">是否添加</param>
|
||||
/// <returns>实体</returns>
|
||||
public static TEntity SingleOrAdd<TEntity>(this DbSet<TEntity> dbSet, Func<TEntity, bool> predicate, Func<TEntity> entityFactory, out bool added)
|
||||
where TEntity : class
|
||||
{
|
||||
added = false;
|
||||
TEntity? entry = dbSet.SingleOrDefault(predicate);
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
entry = entityFactory();
|
||||
dbSet.Add(entry);
|
||||
dbSet.Context().SaveChanges();
|
||||
|
||||
added = true;
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加并保存
|
||||
/// </summary>
|
||||
@@ -64,6 +37,48 @@ public static class DbSetExtension
|
||||
return dbSet.Context().SaveChanges();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步添加并保存
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">实体类型</typeparam>
|
||||
/// <param name="dbSet">数据库集</param>
|
||||
/// <param name="entity">实体</param>
|
||||
/// <returns>影响条数</returns>
|
||||
public static async ValueTask<int> AddAndSaveAsync<TEntity>(this DbSet<TEntity> dbSet, TEntity entity)
|
||||
where TEntity : class
|
||||
{
|
||||
dbSet.Add(entity);
|
||||
return await dbSet.Context().SaveChangesAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加列表并保存
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">实体类型</typeparam>
|
||||
/// <param name="dbSet">数据库集</param>
|
||||
/// <param name="entities">实体</param>
|
||||
/// <returns>影响条数</returns>
|
||||
public static int AddRangeAndSave<TEntity>(this DbSet<TEntity> dbSet, IEnumerable<TEntity> entities)
|
||||
where TEntity : class
|
||||
{
|
||||
dbSet.AddRange(entities);
|
||||
return dbSet.Context().SaveChanges();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步添加列表并保存
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">实体类型</typeparam>
|
||||
/// <param name="dbSet">数据库集</param>
|
||||
/// <param name="entities">实体</param>
|
||||
/// <returns>影响条数</returns>
|
||||
public static async ValueTask<int> AddRangeAndSaveAsync<TEntity>(this DbSet<TEntity> dbSet, IEnumerable<TEntity> entities)
|
||||
where TEntity : class
|
||||
{
|
||||
dbSet.AddRange(entities);
|
||||
return await dbSet.Context().SaveChangesAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除并保存
|
||||
/// </summary>
|
||||
@@ -78,6 +93,20 @@ public static class DbSetExtension
|
||||
return dbSet.Context().SaveChanges();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步移除并保存
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">实体类型</typeparam>
|
||||
/// <param name="dbSet">数据库集</param>
|
||||
/// <param name="entity">实体</param>
|
||||
/// <returns>影响条数</returns>
|
||||
public static async ValueTask<int> RemoveAndSaveAsync<TEntity>(this DbSet<TEntity> dbSet, TEntity entity)
|
||||
where TEntity : class
|
||||
{
|
||||
dbSet.Remove(entity);
|
||||
return await dbSet.Context().SaveChangesAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新并保存
|
||||
/// </summary>
|
||||
@@ -91,4 +120,18 @@ public static class DbSetExtension
|
||||
dbSet.Update(entity);
|
||||
return dbSet.Context().SaveChanges();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步更新并保存
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">实体类型</typeparam>
|
||||
/// <param name="dbSet">数据库集</param>
|
||||
/// <param name="entity">实体</param>
|
||||
/// <returns>影响条数</returns>
|
||||
public static async ValueTask<int> UpdateAndSaveAsync<TEntity>(this DbSet<TEntity> dbSet, TEntity entity)
|
||||
where TEntity : class
|
||||
{
|
||||
dbSet.Update(entity);
|
||||
return await dbSet.Context().SaveChangesAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
81
src/Snap.Hutao/Snap.Hutao/Core/Database/ScopedDbCurrent.cs
Normal file
81
src/Snap.Hutao/Snap.Hutao/Core/Database/ScopedDbCurrent.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Snap.Hutao.Core.Database;
|
||||
|
||||
/// <summary>
|
||||
/// 范围化的数据库当前项
|
||||
/// 简化对数据库中选中项的管理
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">实体的类型</typeparam>
|
||||
/// <typeparam name="TMessage">消息的类型</typeparam>
|
||||
internal class ScopedDbCurrent<TEntity, TMessage>
|
||||
where TEntity : class, ISelectable
|
||||
where TMessage : Message.ValueChangedMessage<TEntity>, new()
|
||||
{
|
||||
private readonly IServiceScopeFactory scopeFactory;
|
||||
private readonly Func<IServiceProvider, DbSet<TEntity>> dbSetFunc;
|
||||
private readonly IMessenger messenger;
|
||||
|
||||
private TEntity? current;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的数据库当前项
|
||||
/// </summary>
|
||||
/// <param name="scopeFactory">范围工厂</param>
|
||||
/// <param name="dbSetFunc">数据集</param>
|
||||
/// <param name="messenger">消息器</param>
|
||||
public ScopedDbCurrent(IServiceScopeFactory scopeFactory, Func<IServiceProvider, DbSet<TEntity>> dbSetFunc, IMessenger messenger)
|
||||
{
|
||||
this.scopeFactory = scopeFactory;
|
||||
this.dbSetFunc = dbSetFunc;
|
||||
this.messenger = messenger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前选中的项
|
||||
/// </summary>
|
||||
public TEntity? Current
|
||||
{
|
||||
get => current;
|
||||
set
|
||||
{
|
||||
// prevent useless sets
|
||||
if (current == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (IServiceScope scope = scopeFactory.CreateScope())
|
||||
{
|
||||
DbSet<TEntity> dbSet = dbSetFunc(scope.ServiceProvider);
|
||||
|
||||
// only update when not processing a deletion
|
||||
if (value != null)
|
||||
{
|
||||
if (current != null)
|
||||
{
|
||||
current.IsSelected = false;
|
||||
dbSet.UpdateAndSave(current);
|
||||
}
|
||||
}
|
||||
|
||||
TMessage message = new() { OldValue = current, NewValue = value };
|
||||
|
||||
current = value;
|
||||
|
||||
if (current != null)
|
||||
{
|
||||
current.IsSelected = true;
|
||||
dbSet.UpdateAndSave(current);
|
||||
}
|
||||
|
||||
messenger.Send(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,16 @@ namespace Snap.Hutao.Core.Database;
|
||||
/// </summary>
|
||||
public static class SettingEntryHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// "True"
|
||||
/// </summary>
|
||||
public static readonly string TrueString = true.ToString();
|
||||
|
||||
/// <summary>
|
||||
/// "False"
|
||||
/// </summary>
|
||||
public static readonly string FalseString = false.ToString();
|
||||
|
||||
/// <summary>
|
||||
/// 获取或添加一个对应的设置
|
||||
/// </summary>
|
||||
@@ -37,17 +47,16 @@ public static class SettingEntryHelper
|
||||
/// </summary>
|
||||
/// <param name="dbSet">设置集</param>
|
||||
/// <param name="key">键</param>
|
||||
/// <param name="valueFactory">值工厂</param>
|
||||
/// <param name="value">值</param>
|
||||
/// <returns>设置</returns>
|
||||
public static SettingEntry SingleOrAdd(this DbSet<SettingEntry> dbSet, string key, Func<string> valueFactory)
|
||||
public static async Task<SettingEntry> SingleOrAddAsync(this DbSet<SettingEntry> dbSet, string key, string value)
|
||||
{
|
||||
SettingEntry? entry = dbSet.SingleOrDefault(entry => key == entry.Key);
|
||||
SettingEntry? entry = await dbSet.SingleOrDefaultAsync(entry => key == entry.Key).ConfigureAwait(false);
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
entry = new(key, valueFactory());
|
||||
dbSet.Add(entry);
|
||||
dbSet.Context().SaveChanges();
|
||||
entry = new(key, value);
|
||||
await dbSet.AddAndSaveAsync(entry).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return entry;
|
||||
|
||||
@@ -40,7 +40,6 @@ internal readonly struct ValueStopwatch
|
||||
/// 获取经过的时间
|
||||
/// </summary>
|
||||
/// <returns>经过的时间</returns>
|
||||
/// <exception cref="InvalidOperationException">当前的停表未合理的初始化</exception>
|
||||
public long GetElapsedTimestamp()
|
||||
{
|
||||
// Start timestamp can't be zero in an initialized ValueStopwatch.
|
||||
@@ -59,7 +58,6 @@ internal readonly struct ValueStopwatch
|
||||
/// 获取经过的时间
|
||||
/// </summary>
|
||||
/// <returns>经过的时间</returns>
|
||||
/// <exception cref="InvalidOperationException">当前的停表未合理的初始化</exception>
|
||||
public TimeSpan GetElapsedTime()
|
||||
{
|
||||
return new TimeSpan(GetElapsedTimestamp());
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Core.Exception;
|
||||
|
||||
/// <summary>
|
||||
/// Error codes used by COM-based APIs.
|
||||
/// </summary>
|
||||
public enum COMError : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// could not be found.
|
||||
/// </summary>
|
||||
STG_E_FILENOTFOUND = 0x80030002,
|
||||
|
||||
/// <summary>
|
||||
/// The component cannot be found.
|
||||
/// </summary>
|
||||
WINCODEC_ERR_COMPONENTNOTFOUND = 0x88982F50,
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Snap.Hutao.Core.Exception;
|
||||
|
||||
/// <summary>
|
||||
/// COM异常扩展
|
||||
/// </summary>
|
||||
internal static class COMExceptionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 比较COM异常是否与某个错误代码等价
|
||||
/// </summary>
|
||||
/// <param name="exception">异常</param>
|
||||
/// <param name="code">错误代码</param>
|
||||
/// <returns>是否为该错误</returns>
|
||||
public static bool Is(this COMException exception, COMError code)
|
||||
{
|
||||
return exception.HResult == unchecked((int)code);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Snap.Hutao.Core.Convert;
|
||||
namespace Snap.Hutao.Core.ExpressionService;
|
||||
|
||||
/// <summary>
|
||||
/// Class to cast to type <see cref="TTo"/>
|
||||
@@ -30,8 +30,13 @@ public static class CastTo<TTo>
|
||||
|
||||
private static Func<TCachedFrom, TTo> Get()
|
||||
{
|
||||
// 参数表达式,表示 传入源类型
|
||||
ParameterExpression param = Expression.Parameter(typeof(TCachedFrom));
|
||||
|
||||
// 一元转换 调用 相关类的显式或隐式转换运算符
|
||||
UnaryExpression convert = Expression.ConvertChecked(param, typeof(TTo));
|
||||
|
||||
// 生成一个源类型入,目标类型出的 lamdba
|
||||
return Expression.Lambda<Func<TCachedFrom, TTo>>(convert, param).Compile();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Snap.Hutao.Core.ExpressionService;
|
||||
|
||||
/// <summary>
|
||||
/// 枚举帮助类
|
||||
/// </summary>
|
||||
public static class EnumExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 判断枚举是否有对应的Flag
|
||||
/// </summary>
|
||||
/// <typeparam name="T">枚举类型</typeparam>
|
||||
/// <param name="enum">待检查的枚举</param>
|
||||
/// <param name="value">值</param>
|
||||
/// <returns>是否有对应的Flag</returns>
|
||||
public static bool HasOption<T>(this T @enum, T value)
|
||||
where T : struct, Enum
|
||||
{
|
||||
return ExpressionCache<T>.Entry(@enum, value);
|
||||
}
|
||||
|
||||
private static class ExpressionCache<T>
|
||||
{
|
||||
public static readonly Func<T, T, bool> Entry = Get();
|
||||
|
||||
private static Func<T, T, bool> Get()
|
||||
{
|
||||
ParameterExpression paramSource = Expression.Parameter(typeof(T));
|
||||
ParameterExpression paramValue = Expression.Parameter(typeof(T));
|
||||
|
||||
BinaryExpression logicalAnd = Expression.AndAssign(paramSource, paramValue);
|
||||
BinaryExpression equal = Expression.Equal(logicalAnd, paramValue);
|
||||
|
||||
// 生成一个源类型入,目标类型出的 lamdba
|
||||
return Expression.Lambda<Func<T, T, bool>>(equal, paramSource, paramValue).Compile();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.Storage.Streams;
|
||||
|
||||
namespace Snap.Hutao.Core.IO.DataTransfer;
|
||||
|
||||
@@ -31,9 +32,22 @@ internal static class Clipboard
|
||||
/// <param name="text">文本</param>
|
||||
public static void SetText(string text)
|
||||
{
|
||||
DataPackage content = new();
|
||||
DataPackage content = new() { RequestedOperation = DataPackageOperation.Copy };
|
||||
content.SetText(text);
|
||||
Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(content);
|
||||
Windows.ApplicationModel.DataTransfer.Clipboard.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置位图
|
||||
/// </summary>
|
||||
/// <param name="stream">位图流</param>
|
||||
public static void SetBitmapStream(IRandomAccessStream stream)
|
||||
{
|
||||
RandomAccessStreamReference reference = RandomAccessStreamReference.CreateFromStream(stream);
|
||||
DataPackage content = new() { RequestedOperation = DataPackageOperation.Copy };
|
||||
content.SetBitmap(reference);
|
||||
Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(content);
|
||||
Windows.ApplicationModel.DataTransfer.Clipboard.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,12 +28,18 @@ internal sealed class TemporaryFile : IDisposable
|
||||
/// </summary>
|
||||
/// <param name="file">源文件</param>
|
||||
/// <returns>临时文件</returns>
|
||||
public static TemporaryFile CreateFromFileCopy(string file)
|
||||
public static TemporaryFile? CreateFromFileCopy(string file)
|
||||
{
|
||||
TemporaryFile temporaryFile = new();
|
||||
File.Copy(file, temporaryFile.Path, true);
|
||||
|
||||
return temporaryFile;
|
||||
try
|
||||
{
|
||||
File.Copy(file, temporaryFile.Path, true);
|
||||
return temporaryFile;
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.Json.Converter;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
|
||||
namespace Snap.Hutao.Core.Json.Annotation;
|
||||
|
||||
/// <summary>
|
||||
@@ -9,6 +12,18 @@ namespace Snap.Hutao.Core.Json.Annotation;
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
|
||||
internal class JsonEnumAttribute : Attribute
|
||||
{
|
||||
private static readonly Type ConfigurableEnumConverterType = typeof(ConfigurableEnumConverter<>);
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的Json枚举声明
|
||||
/// </summary>
|
||||
/// <param name="readAndWriteAs">读取与写入</param>
|
||||
public JsonEnumAttribute(JsonSerializeType readAndWriteAs)
|
||||
{
|
||||
ReadAs = readAndWriteAs;
|
||||
WriteAs = readAndWriteAs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的Json枚举声明
|
||||
/// </summary>
|
||||
@@ -29,4 +44,15 @@ internal class JsonEnumAttribute : Attribute
|
||||
/// 写入形式
|
||||
/// </summary>
|
||||
public JsonSerializeType WriteAs { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个新的转换器
|
||||
/// </summary>
|
||||
/// <param name="info">属性信息</param>
|
||||
/// <returns>Json转换器</returns>
|
||||
internal JsonConverter CreateConverter(JsonPropertyInfo info)
|
||||
{
|
||||
Type converterType = ConfigurableEnumConverterType.MakeGenericType(info.PropertyType);
|
||||
return (JsonConverter)Activator.CreateInstance(converterType, ReadAs, WriteAs)!;
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,12 @@
|
||||
namespace Snap.Hutao.Core.Json.Annotation;
|
||||
|
||||
/// <summary>
|
||||
/// Json 文本字符串序列化类型
|
||||
/// Json 序列化类型
|
||||
/// </summary>
|
||||
public enum JsonSerializeType
|
||||
{
|
||||
/// <summary>
|
||||
/// 数字
|
||||
/// Int32
|
||||
/// </summary>
|
||||
Int32,
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.Convert;
|
||||
using Snap.Hutao.Core.ExpressionService;
|
||||
using Snap.Hutao.Core.Json.Annotation;
|
||||
|
||||
namespace Snap.Hutao.Core.Json.Converter;
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Core.Json.Converter;
|
||||
|
||||
/// <summary>
|
||||
/// 枚举 - 字符串数字 转换器
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">枚举的类型</typeparam>
|
||||
internal class EnumStringValueConverter<TEnum> : JsonConverter<TEnum>
|
||||
where TEnum : struct, Enum
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
if (reader.GetString() is string str)
|
||||
{
|
||||
return Enum.Parse<TEnum>(str);
|
||||
}
|
||||
|
||||
throw Must.NeverHappen();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStringValue(value.ToString("D"));
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.Json.Annotation;
|
||||
using Snap.Hutao.Core.Json.Converter;
|
||||
using System.Reflection;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
|
||||
namespace Snap.Hutao.Core.Json;
|
||||
@@ -14,7 +12,6 @@ namespace Snap.Hutao.Core.Json;
|
||||
internal static class JsonTypeInfoResolvers
|
||||
{
|
||||
private static readonly Type JsonEnumAttributeType = typeof(JsonEnumAttribute);
|
||||
private static readonly Type ConfigurableEnumConverterType = typeof(ConfigurableEnumConverter<>);
|
||||
|
||||
/// <summary>
|
||||
/// 解析枚举类型
|
||||
@@ -32,10 +29,9 @@ internal static class JsonTypeInfoResolvers
|
||||
|
||||
foreach (JsonPropertyInfo enumProperty in enumProperties)
|
||||
{
|
||||
JsonEnumAttribute attr = enumProperty.PropertyType.GetCustomAttribute<JsonEnumAttribute>()!;
|
||||
Type converterType = ConfigurableEnumConverterType.MakeGenericType(enumProperty.PropertyType);
|
||||
JsonEnumAttribute attr = enumProperty.AttributeProvider!.GetCustomAttributes(false).OfType<JsonEnumAttribute>().Single();
|
||||
|
||||
enumProperty.CustomConverter = (JsonConverter)Activator.CreateInstance(converterType, attr.ReadAs, attr.WriteAs)!;
|
||||
enumProperty.CustomConverter = attr.CreateConverter(enumProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ public static class JumpListHelper
|
||||
/// 异步配置跳转列表
|
||||
/// </summary>
|
||||
/// <returns>任务</returns>
|
||||
public static async Task ConfigAsync()
|
||||
public static async Task ConfigureAsync()
|
||||
{
|
||||
if (JumpList.IsSupported())
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.WinUI.Notifications;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Snap.Hutao.Extension;
|
||||
using Snap.Hutao.Service.Abstraction;
|
||||
@@ -48,7 +49,21 @@ internal static class Activation
|
||||
_ = sender;
|
||||
if (!ToastNotificationManagerCompat.WasCurrentProcessToastActivated())
|
||||
{
|
||||
HandleActivationAsync(args).SafeForget();
|
||||
HandleActivationAsync(args, true).SafeForget();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发激活事件
|
||||
/// </summary>
|
||||
/// <param name="sender">发送方</param>
|
||||
/// <param name="args">激活参数</param>
|
||||
public static void NonRedirectToActivate(object? sender, AppActivationArguments args)
|
||||
{
|
||||
_ = sender;
|
||||
if (!ToastNotificationManagerCompat.WasCurrentProcessToastActivated())
|
||||
{
|
||||
HandleActivationAsync(args, false).SafeForget();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,25 +90,24 @@ internal static class Activation
|
||||
/// 异步响应激活事件
|
||||
/// </summary>
|
||||
/// <returns>任务</returns>
|
||||
private static async Task HandleActivationAsync(AppActivationArguments args)
|
||||
private static async Task HandleActivationAsync(AppActivationArguments args, bool isRedirected)
|
||||
{
|
||||
if (ActivateSemaphore.CurrentCount > 0)
|
||||
{
|
||||
using (await ActivateSemaphore.EnterAsync().ConfigureAwait(false))
|
||||
{
|
||||
await HandleActivationCoreAsync(args).ConfigureAwait(false);
|
||||
await HandleActivationCoreAsync(args, isRedirected).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task HandleActivationCoreAsync(AppActivationArguments args)
|
||||
private static async Task HandleActivationCoreAsync(AppActivationArguments args, bool isRedirected)
|
||||
{
|
||||
if (args.Kind == ExtendedActivationKind.Protocol)
|
||||
{
|
||||
if (args.TryGetProtocolActivatedUri(out Uri? uri))
|
||||
{
|
||||
Ioc.Default.GetRequiredService<IInfoBarService>().Information(uri.ToString());
|
||||
await HandleUrlActivationAsync(uri).ConfigureAwait(false);
|
||||
await HandleUrlActivationAsync(uri, isRedirected).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else if (args.Kind == ExtendedActivationKind.Launch)
|
||||
@@ -131,7 +145,7 @@ internal static class Activation
|
||||
.SafeForget();
|
||||
}
|
||||
|
||||
private static async Task HandleUrlActivationAsync(Uri uri)
|
||||
private static async Task HandleUrlActivationAsync(Uri uri, bool isRedirected)
|
||||
{
|
||||
UriBuilder builder = new(uri);
|
||||
|
||||
@@ -144,21 +158,22 @@ internal static class Activation
|
||||
case "achievement":
|
||||
{
|
||||
await WaitMainWindowAsync().ConfigureAwait(false);
|
||||
await HandleAchievementActionAsync(action, parameter).ConfigureAwait(false);
|
||||
await HandleAchievementActionAsync(action, parameter, isRedirected).ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
|
||||
case "dailynote":
|
||||
{
|
||||
await HandleDailyNoteActionAsync(action, parameter).ConfigureAwait(false);
|
||||
await HandleDailyNoteActionAsync(action, parameter, isRedirected).ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task HandleAchievementActionAsync(string action, string parameter)
|
||||
private static async Task HandleAchievementActionAsync(string action, string parameter, bool isRedirected)
|
||||
{
|
||||
_ = parameter;
|
||||
_ = isRedirected;
|
||||
switch (action)
|
||||
{
|
||||
case "/import":
|
||||
@@ -175,7 +190,7 @@ internal static class Activation
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task HandleDailyNoteActionAsync(string action, string parameter)
|
||||
private static async Task HandleDailyNoteActionAsync(string action, string parameter, bool isRedirected)
|
||||
{
|
||||
_ = parameter;
|
||||
switch (action)
|
||||
@@ -186,6 +201,14 @@ internal static class Activation
|
||||
.GetRequiredService<IDailyNoteService>()
|
||||
.RefreshDailyNotesAsync(true)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// Check if it's redirected.
|
||||
if (!isRedirected)
|
||||
{
|
||||
// It's a direct open process, should exit immediately.
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -193,9 +216,9 @@ internal static class Activation
|
||||
|
||||
private static async Task HandleLaunchGameActionAsync(string? uid = null)
|
||||
{
|
||||
Ioc.Default.GetRequiredService<IMemoryCache>().Set(ViewModel.LaunchGameViewModel.DesiredUid, uid);
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
|
||||
// TODO auto switch to account
|
||||
if (!MainWindow.IsPresent)
|
||||
{
|
||||
_ = Ioc.Default.GetRequiredService<LaunchGameWindow>();
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.Security;
|
||||
using Windows.Win32.System.Com;
|
||||
using static Windows.Win32.PInvoke;
|
||||
|
||||
namespace Snap.Hutao.Core.LifeCycle;
|
||||
|
||||
/// <summary>
|
||||
/// App 实例拓展
|
||||
/// </summary>
|
||||
internal static class AppInstanceExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 同步非阻塞重定向
|
||||
/// </summary>
|
||||
/// <param name="appInstance">app实例</param>
|
||||
/// <param name="args">参数</param>
|
||||
[SuppressMessage("", "VSTHRD110")]
|
||||
public static void RedirectActivationTo(this AppInstance appInstance, AppActivationArguments args)
|
||||
{
|
||||
HANDLE redirectEventHandle = UnsafeCreateEvent();
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await appInstance.RedirectActivationToAsync(args);
|
||||
SetEvent(redirectEventHandle);
|
||||
});
|
||||
|
||||
ReadOnlySpan<HANDLE> handles = new(in redirectEventHandle);
|
||||
CoWaitForMultipleObjects((uint)CWMO_FLAGS.CWMO_DEFAULT, INFINITE, handles, out uint _);
|
||||
}
|
||||
|
||||
private static unsafe HANDLE UnsafeCreateEvent()
|
||||
{
|
||||
return CreateEvent(default(SECURITY_ATTRIBUTES*), true, false, null);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.Win32.TaskScheduler;
|
||||
using System.Runtime.InteropServices;
|
||||
using SchedulerTask = Microsoft.Win32.TaskScheduler.Task;
|
||||
|
||||
namespace Snap.Hutao.Core;
|
||||
@@ -9,7 +10,7 @@ namespace Snap.Hutao.Core;
|
||||
/// <summary>
|
||||
/// 任务计划器服务
|
||||
/// </summary>
|
||||
internal static class TaskSchedulerHelper
|
||||
internal static class ScheduleTaskHelper
|
||||
{
|
||||
private const string DailyNoteRefreshTaskName = "SnapHutaoDailyNoteRefreshTask";
|
||||
|
||||
@@ -39,5 +40,35 @@ internal static class TaskSchedulerHelper
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch (COMException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卸载全部注册的任务
|
||||
/// </summary>
|
||||
/// <returns>是否卸载成功</returns>
|
||||
public static bool UnregisterAllTasks()
|
||||
{
|
||||
try
|
||||
{
|
||||
SchedulerTask? targetTask = TaskService.Instance.GetTask(DailyNoteRefreshTaskName);
|
||||
if (targetTask != null)
|
||||
{
|
||||
TaskService.Instance.RootFolder.DeleteTask(DailyNoteRefreshTaskName);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch (COMException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ namespace Snap.Hutao.Core.Threading;
|
||||
|
||||
/// <summary>
|
||||
/// 调度器队列切换操作
|
||||
/// 等待此类型对象后上下文会被切换至主线程
|
||||
/// </summary>
|
||||
public readonly struct DispatherQueueSwitchOperation : IAwaitable<DispatherQueueSwitchOperation>, IAwaiter
|
||||
{
|
||||
@@ -29,9 +30,9 @@ public readonly struct DispatherQueueSwitchOperation : IAwaitable<DispatherQueue
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnCompleted(Action continuation)
|
||||
public DispatherQueueSwitchOperation GetAwaiter()
|
||||
{
|
||||
dispatherQueue.TryEnqueue(() => { continuation(); });
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -40,8 +41,11 @@ public readonly struct DispatherQueueSwitchOperation : IAwaitable<DispatherQueue
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DispatherQueueSwitchOperation GetAwaiter()
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
return this;
|
||||
dispatherQueue.TryEnqueue(() =>
|
||||
{
|
||||
continuation();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Snap.Hutao.Core.Threading;
|
||||
|
||||
/// <summary>
|
||||
@@ -8,13 +10,25 @@ namespace Snap.Hutao.Core.Threading;
|
||||
/// </summary>
|
||||
internal static class ThreadHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用此静态方法以 异步切换到 后台线程
|
||||
/// </summary>
|
||||
/// <remarks>使用 <see cref="SwitchToMainThreadAsync"/> 异步切换到 主线程</remarks>
|
||||
/// <returns>等待体</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ThreadPoolSwitchOperation SwitchToBackgroundAsync()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用此静态方法以 异步切换到 主线程
|
||||
/// </summary>
|
||||
/// <remarks>使用 <see cref="Task.Yield"/> 异步切换到 后台线程</remarks>
|
||||
/// <remarks>使用 <see cref="SwitchToBackgroundAsync"/> 异步切换到 后台线程</remarks>
|
||||
/// <returns>等待体</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static DispatherQueueSwitchOperation SwitchToMainThreadAsync()
|
||||
{
|
||||
return new(Program.DispatcherQueue!);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.Threading.Abstraction;
|
||||
|
||||
namespace Snap.Hutao.Core.Threading;
|
||||
|
||||
/// <summary>
|
||||
/// 线程池切换操作
|
||||
/// 等待此类型对象后上下文会被切换至线程池线程
|
||||
/// </summary>
|
||||
public readonly struct ThreadPoolSwitchOperation : IAwaitable<ThreadPoolSwitchOperation>, IAwaiter, ICriticalAwaiter
|
||||
{
|
||||
private static readonly WaitCallback WaitCallbackRunAction = RunAction;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsCompleted { get => false; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ThreadPoolSwitchOperation GetAwaiter()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void GetResult()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
QueueContinuation(continuation, flowContext: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
QueueContinuation(continuation, flowContext: false);
|
||||
}
|
||||
|
||||
private static void QueueContinuation(Action continuation, bool flowContext)
|
||||
{
|
||||
if (flowContext)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(WaitCallbackRunAction, continuation);
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadPool.UnsafeQueueUserWorkItem(WaitCallbackRunAction, continuation);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RunAction(object? state)
|
||||
{
|
||||
((Action)state!)();
|
||||
}
|
||||
}
|
||||
@@ -38,19 +38,6 @@ public static class Must
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 任务异常
|
||||
/// </summary>
|
||||
/// <typeparam name="T">任务结果类型</typeparam>
|
||||
/// <param name="message">异常消息</param>
|
||||
/// <returns>异常的任务</returns>
|
||||
[SuppressMessage("", "VSTHRD200")]
|
||||
public static Task<T> Fault<T>(string message)
|
||||
{
|
||||
InvalidOperationException exception = new(message);
|
||||
return Task.FromException<T>(exception);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unconditionally throws an <see cref="NotSupportedException"/>.
|
||||
/// </summary>
|
||||
|
||||
@@ -50,6 +50,10 @@ internal abstract class WebView2Helper
|
||||
/// </summary>
|
||||
public static string Version
|
||||
{
|
||||
get => version;
|
||||
get
|
||||
{
|
||||
_ = IsSupported;
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace Snap.Hutao.Core.Windowing;
|
||||
/// <summary>
|
||||
/// <see cref="AppWindow"/> 扩展
|
||||
/// </summary>
|
||||
public static class AppWindowExtensions
|
||||
public static class AppWindowExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前 <see cref="AppWindow"/> 的呈现矩形
|
||||
@@ -23,7 +23,7 @@ namespace Snap.Hutao.Core.Windowing;
|
||||
/// </summary>
|
||||
/// <typeparam name="TWindow">窗体类型</typeparam>
|
||||
[SuppressMessage("", "CA1001")]
|
||||
internal sealed class ExtendedWindow<TWindow> : IRecipient<BackdropTypeChangedMessage>
|
||||
internal sealed class ExtendedWindow<TWindow> : IRecipient<BackdropTypeChangedMessage>, IRecipient<FlyoutOpenCloseMessage>
|
||||
where TWindow : Window, IExtendedWindowSource
|
||||
{
|
||||
private readonly HWND handle;
|
||||
@@ -82,6 +82,12 @@ internal sealed class ExtendedWindow<TWindow> : IRecipient<BackdropTypeChangedMe
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Receive(FlyoutOpenCloseMessage message)
|
||||
{
|
||||
UpdateDragRectangles(appWindow.TitleBar, message.IsOpen);
|
||||
}
|
||||
|
||||
private static void UpdateTitleButtonColor(AppWindowTitleBar appTitleBar)
|
||||
{
|
||||
appTitleBar.ButtonBackgroundColor = Colors.Transparent;
|
||||
@@ -128,7 +134,8 @@ internal sealed class ExtendedWindow<TWindow> : IRecipient<BackdropTypeChangedMe
|
||||
(string pos, string size) = GetPostionAndSize(appWindow);
|
||||
logger.LogInformation(EventIds.WindowState, "Postion: [{pos}], Size: [{size}]", pos, size);
|
||||
|
||||
appWindow.Show(true);
|
||||
// appWindow.Show(true);
|
||||
window.Activate();
|
||||
|
||||
systemBackdrop = new(window);
|
||||
bool micaApplied = systemBackdrop.TryApply();
|
||||
@@ -137,7 +144,9 @@ internal sealed class ExtendedWindow<TWindow> : IRecipient<BackdropTypeChangedMe
|
||||
bool subClassApplied = subclassManager.TrySetWindowSubclass();
|
||||
logger.LogInformation(EventIds.SubClassing, "Apply {name} : {result}", nameof(WindowSubclassManager<TWindow>), subClassApplied ? "succeed" : "failed");
|
||||
|
||||
Ioc.Default.GetRequiredService<IMessenger>().Register(this);
|
||||
IMessenger messenger = Ioc.Default.GetRequiredService<IMessenger>();
|
||||
messenger.Register<BackdropTypeChangedMessage>(this);
|
||||
messenger.Register<FlyoutOpenCloseMessage>(this);
|
||||
window.Closed += OnWindowClosed;
|
||||
}
|
||||
|
||||
@@ -172,17 +181,25 @@ internal sealed class ExtendedWindow<TWindow> : IRecipient<BackdropTypeChangedMe
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe void UpdateDragRectangles(AppWindowTitleBar appTitleBar)
|
||||
private void UpdateDragRectangles(AppWindowTitleBar appTitleBar, bool isFlyoutOpened = false)
|
||||
{
|
||||
double scale = Persistence.GetScaleForWindow(handle);
|
||||
if (isFlyoutOpened)
|
||||
{
|
||||
// set to 0
|
||||
appTitleBar.SetDragRectangles(default(RectInt32).Enumerate().ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
double scale = Persistence.GetScaleForWindow(handle);
|
||||
|
||||
// 48 is the navigation button leftInset
|
||||
RectInt32 dragRect = StructMarshal.RectInt32(new(48, 0), titleBar.ActualSize).Scale(scale);
|
||||
appTitleBar.SetDragRectangles(dragRect.Enumerate().ToArray());
|
||||
// 48 is the navigation button leftInset
|
||||
RectInt32 dragRect = StructMarshal.RectInt32(new(48, 0), titleBar.ActualSize).Scale(scale);
|
||||
appTitleBar.SetDragRectangles(dragRect.Enumerate().ToArray());
|
||||
|
||||
// workaround for https://github.com/microsoft/WindowsAppSDK/issues/2976
|
||||
SizeInt32 size = appWindow.ClientSize;
|
||||
size.Height -= (int)(31 * scale);
|
||||
appWindow.ResizeClient(size);
|
||||
// workaround for https://github.com/microsoft/WindowsAppSDK/issues/2976
|
||||
SizeInt32 size = appWindow.ClientSize;
|
||||
size.Height -= (int)(31 * scale);
|
||||
appWindow.ResizeClient(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,24 @@ public static class EnumExtension
|
||||
public static string GetDescription<TEnum>(this TEnum @enum)
|
||||
where TEnum : struct, Enum
|
||||
{
|
||||
string enumName = Must.NotNull(Enum.GetName(@enum)!);
|
||||
string enumName = Enum.GetName(@enum)!;
|
||||
FieldInfo? field = @enum.GetType().GetField(enumName);
|
||||
DescriptionAttribute? attr = field?.GetCustomAttribute<DescriptionAttribute>();
|
||||
return attr?.Description ?? enumName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取枚举的描述
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">枚举的类型</typeparam>
|
||||
/// <param name="enum">枚举值</param>
|
||||
/// <returns>描述</returns>
|
||||
public static string? GetDescriptionOrNull<TEnum>(this TEnum @enum)
|
||||
where TEnum : struct, Enum
|
||||
{
|
||||
string enumName = Enum.GetName(@enum)!;
|
||||
FieldInfo? field = @enum.GetType().GetField(enumName);
|
||||
DescriptionAttribute? attr = field?.GetCustomAttribute<DescriptionAttribute>();
|
||||
return attr?.Description;
|
||||
}
|
||||
}
|
||||
25
src/Snap.Hutao/Snap.Hutao/Extension/LoggerExtension.cs
Normal file
25
src/Snap.Hutao/Snap.Hutao/Extension/LoggerExtension.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Extension;
|
||||
|
||||
/// <summary>
|
||||
/// 日志器扩展
|
||||
/// </summary>
|
||||
[SuppressMessage("", "CA2254")]
|
||||
public static class LoggerExtension
|
||||
{
|
||||
/// <inheritdoc cref="LoggerExtensions.LogInformation(ILogger, string?, object?[])"/>
|
||||
public static T LogInformation<T>(this ILogger logger, string message, params object?[] param)
|
||||
{
|
||||
logger.LogInformation(message, param);
|
||||
return default!;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="LoggerExtensions.LogWarning(ILogger, string?, object?[])"/>
|
||||
public static T LogWarning<T>(this ILogger logger, string message, params object?[] param)
|
||||
{
|
||||
logger.LogWarning(message, param);
|
||||
return default!;
|
||||
}
|
||||
}
|
||||
@@ -46,4 +46,4 @@ public static class StringBuilderExtensions
|
||||
{
|
||||
return condition ? sb.Append(trueValue) : sb.Append(falseValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
using Snap.Hutao.Factory.Abstraction;
|
||||
using Windows.Storage.Pickers;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.UI.Shell;
|
||||
using WinRT;
|
||||
using WinRT.Interop;
|
||||
|
||||
namespace Snap.Hutao.Factory;
|
||||
@@ -37,6 +40,7 @@ internal class PickerFactory : IPickerFactory
|
||||
picker.FileTypeFilter.Add(type);
|
||||
}
|
||||
|
||||
// https://github.com/microsoft/WindowsAppSDK/issues/2931
|
||||
picker.FileTypeFilter.Add(AnyType);
|
||||
|
||||
return picker;
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
<Window
|
||||
x:Class="Snap.Hutao.LaunchGameWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
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:mxi="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
||||
xmlns:shv="using:Snap.Hutao.ViewModel"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid
|
||||
Name="RootGrid"
|
||||
d:DataContext="{d:DesignInstance shv:LaunchGameViewModel}">
|
||||
|
||||
<Grid Name="RootGrid" d:DataContext="{d:DesignInstance shv:LaunchGameViewModel}">
|
||||
|
||||
<mxi:Interaction.Behaviors>
|
||||
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
|
||||
</mxi:Interaction.Behaviors>
|
||||
@@ -27,17 +25,17 @@
|
||||
Grid.Row="0"
|
||||
Height="32">
|
||||
<TextBlock
|
||||
Text="选择账号并启动"
|
||||
TextWrapping="NoWrap"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="12,0,0,0"/>
|
||||
Margin="12,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="选择账号并启动"
|
||||
TextWrapping="NoWrap"/>
|
||||
</Grid>
|
||||
|
||||
|
||||
<ListView
|
||||
Grid.Row="1"
|
||||
ItemsSource="{Binding GameAccounts}"
|
||||
SelectedItem="{Binding SelectedGameAccount,Mode=TwoWay}">
|
||||
SelectedItem="{Binding SelectedGameAccount, Mode=TwoWay}">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
@@ -46,7 +44,7 @@
|
||||
<TextBlock
|
||||
Opacity="0.8"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding AttachUid,TargetNullValue=该账号尚未绑定 UID}"/>
|
||||
Text="{Binding AttachUid, TargetNullValue=该账号尚未绑定 UID}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
@@ -54,10 +52,10 @@
|
||||
</ListView>
|
||||
|
||||
<Button
|
||||
Margin="16"
|
||||
Grid.Row="2"
|
||||
Margin="16"
|
||||
HorizontalAlignment="Stretch"
|
||||
Content="启动游戏"
|
||||
Command="{Binding LaunchCommand}"/>
|
||||
Command="{Binding LaunchCommand}"
|
||||
Content="启动游戏"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<Window
|
||||
x:Class="Snap.Hutao.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
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:shv="using:Snap.Hutao.View"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<shv:TitleView
|
||||
Margin="48,0,0,0"
|
||||
x:Name="TitleBarView"
|
||||
Height="44"
|
||||
x:Name="TitleBarView"/>
|
||||
|
||||
Margin="48,0,0,0"/>
|
||||
|
||||
<shv:MainView/>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace Snap.Hutao.Message;
|
||||
/// <summary>
|
||||
/// 成就存档切换消息
|
||||
/// </summary>
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
||||
internal class AchievementArchiveChangedMessage : ValueChangedMessage<AchievementArchive>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Entity;
|
||||
|
||||
namespace Snap.Hutao.Message;
|
||||
|
||||
/// <summary>
|
||||
/// 养成计划切换消息
|
||||
/// </summary>
|
||||
internal class CultivateProjectChangedMessage : ValueChangedMessage<CultivateProject>
|
||||
{
|
||||
}
|
||||
24
src/Snap.Hutao/Snap.Hutao/Message/FlyoutOpenCloseMessage.cs
Normal file
24
src/Snap.Hutao/Snap.Hutao/Message/FlyoutOpenCloseMessage.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Message;
|
||||
|
||||
/// <summary>
|
||||
/// Flyout开启关闭消息
|
||||
/// </summary>
|
||||
internal class FlyoutOpenCloseMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造一个新的Flyout开启关闭消息
|
||||
/// </summary>
|
||||
/// <param name="isOpen">是否为开启状态</param>
|
||||
public FlyoutOpenCloseMessage(bool isOpen)
|
||||
{
|
||||
IsOpen = isOpen;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为开启状态
|
||||
/// </summary>
|
||||
public bool IsOpen { get; }
|
||||
}
|
||||
311
src/Snap.Hutao/Snap.Hutao/Migrations/20221128115346_ObjectCache.Designer.cs
generated
Normal file
311
src/Snap.Hutao/Snap.Hutao/Migrations/20221128115346_ObjectCache.Designer.cs
generated
Normal file
@@ -0,0 +1,311 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Snap.Hutao.Context.Database;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Snap.Hutao.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDbContext))]
|
||||
[Migration("20221128115346_ObjectCache")]
|
||||
partial class ObjectCache
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.0");
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("ArchiveId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Current")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("Time")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ArchiveId");
|
||||
|
||||
b.ToTable("achievements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.AchievementArchive", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("achievement_archives");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.AvatarInfo", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("avatar_infos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DailyNote")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("DailyTaskNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("DailyTaskNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ExpeditionNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ExpeditionNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("HomeCoinNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("HomeCoinNotifyThreshold")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ResinNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ResinNotifyThreshold")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ShowInHomeWidget")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("TransformerNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("TransformerNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("daily_notes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("gacha_archives");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("ArchiveId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("GachaType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<long>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("QueryType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("Time")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ArchiveId");
|
||||
|
||||
b.ToTable("gacha_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GameAccount", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AttachUid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("MihoyoSDK")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("game_accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.ObjectCacheEntry", b =>
|
||||
{
|
||||
b.Property<string>("Key")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset>("ExpireTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Key");
|
||||
|
||||
b.ToTable("object_cache");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.SettingEntry", b =>
|
||||
{
|
||||
b.Property<string>("Key")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Key");
|
||||
|
||||
b.ToTable("settings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.User", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Aid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CookieToken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Ltoken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Mid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Stoken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.AchievementArchive", "Archive")
|
||||
.WithMany()
|
||||
.HasForeignKey("ArchiveId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Archive");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.GachaArchive", "Archive")
|
||||
.WithMany()
|
||||
.HasForeignKey("ArchiveId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Archive");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Snap.Hutao.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ObjectCache : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "object_cache",
|
||||
columns: table => new
|
||||
{
|
||||
Key = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ExpireTime = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
||||
Value = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_object_cache", x => x.Key);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "object_cache");
|
||||
}
|
||||
}
|
||||
}
|
||||
415
src/Snap.Hutao/Snap.Hutao/Migrations/20221202052444_Cultivation.Designer.cs
generated
Normal file
415
src/Snap.Hutao/Snap.Hutao/Migrations/20221202052444_Cultivation.Designer.cs
generated
Normal file
@@ -0,0 +1,415 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Snap.Hutao.Context.Database;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Snap.Hutao.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDbContext))]
|
||||
[Migration("20221202052444_Cultivation")]
|
||||
partial class Cultivation
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.0");
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("ArchiveId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Current")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("Time")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ArchiveId");
|
||||
|
||||
b.ToTable("achievements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.AchievementArchive", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("achievement_archives");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.AvatarInfo", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("avatar_infos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("cultivate_entries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("EntryId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("EntryId");
|
||||
|
||||
b.ToTable("cultivate_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateProject", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("cultivate_projects");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DailyNote")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("DailyTaskNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("DailyTaskNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ExpeditionNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ExpeditionNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("HomeCoinNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("HomeCoinNotifyThreshold")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ResinNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ResinNotifyThreshold")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ShowInHomeWidget")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("TransformerNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("TransformerNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("daily_notes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("gacha_archives");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("ArchiveId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("GachaType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<long>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("QueryType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("Time")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ArchiveId");
|
||||
|
||||
b.ToTable("gacha_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GameAccount", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AttachUid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("MihoyoSDK")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("game_accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.ObjectCacheEntry", b =>
|
||||
{
|
||||
b.Property<string>("Key")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset>("ExpireTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Key");
|
||||
|
||||
b.ToTable("object_cache");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.SettingEntry", b =>
|
||||
{
|
||||
b.Property<string>("Key")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Key");
|
||||
|
||||
b.ToTable("settings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.User", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Aid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CookieToken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Ltoken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Mid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Stoken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.AchievementArchive", "Archive")
|
||||
.WithMany("Achievements")
|
||||
.HasForeignKey("ArchiveId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Archive");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany("Entries")
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateEntry", "Entry")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("EntryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Entry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.GachaArchive", "Archive")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("ArchiveId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Archive");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.AchievementArchive", b =>
|
||||
{
|
||||
b.Navigation("Achievements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateProject", b =>
|
||||
{
|
||||
b.Navigation("Entries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Snap.Hutao.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Cultivation : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "cultivate_projects",
|
||||
columns: table => new
|
||||
{
|
||||
InnerId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
IsSelected = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_cultivate_projects", x => x.InnerId);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "cultivate_entries",
|
||||
columns: table => new
|
||||
{
|
||||
InnerId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ProjectId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Type = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_cultivate_entries", x => x.InnerId);
|
||||
table.ForeignKey(
|
||||
name: "FK_cultivate_entries_cultivate_projects_ProjectId",
|
||||
column: x => x.ProjectId,
|
||||
principalTable: "cultivate_projects",
|
||||
principalColumn: "InnerId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "cultivate_items",
|
||||
columns: table => new
|
||||
{
|
||||
InnerId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
EntryId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ItemId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Count = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_cultivate_items", x => x.InnerId);
|
||||
table.ForeignKey(
|
||||
name: "FK_cultivate_items_cultivate_entries_EntryId",
|
||||
column: x => x.EntryId,
|
||||
principalTable: "cultivate_entries",
|
||||
principalColumn: "InnerId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_cultivate_entries_ProjectId",
|
||||
table: "cultivate_entries",
|
||||
column: "ProjectId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_cultivate_items_EntryId",
|
||||
table: "cultivate_items",
|
||||
column: "EntryId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "cultivate_items");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "cultivate_entries");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "cultivate_projects");
|
||||
}
|
||||
}
|
||||
}
|
||||
512
src/Snap.Hutao/Snap.Hutao/Migrations/20221210111128_Inventory.Designer.cs
generated
Normal file
512
src/Snap.Hutao/Snap.Hutao/Migrations/20221210111128_Inventory.Designer.cs
generated
Normal file
@@ -0,0 +1,512 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Snap.Hutao.Context.Database;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Snap.Hutao.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDbContext))]
|
||||
[Migration("20221210111128_Inventory")]
|
||||
partial class Inventory
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.0");
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("ArchiveId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Current")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("Time")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ArchiveId");
|
||||
|
||||
b.ToTable("achievements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.AchievementArchive", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("achievement_archives");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.AvatarInfo", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("avatar_infos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("cultivate_entries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("EntryId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("EntryId");
|
||||
|
||||
b.ToTable("cultivate_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateProject", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AttachedUid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("cultivate_projects");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DailyNote")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("DailyTaskNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("DailyTaskNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ExpeditionNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ExpeditionNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("HomeCoinNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("HomeCoinNotifyThreshold")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ResinNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ResinNotifyThreshold")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ShowInHomeWidget")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("TransformerNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("TransformerNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("daily_notes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("gacha_archives");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("ArchiveId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("GachaType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<long>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("QueryType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("Time")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ArchiveId");
|
||||
|
||||
b.ToTable("gacha_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GameAccount", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AttachUid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("MihoyoSDK")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("game_accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("inventory_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AppendPropIdList")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Level")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MainPropId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("inventory_reliquaries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Level")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("PromoteLevel")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("inventory_weapons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.ObjectCacheEntry", b =>
|
||||
{
|
||||
b.Property<string>("Key")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset>("ExpireTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Key");
|
||||
|
||||
b.ToTable("object_cache");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.SettingEntry", b =>
|
||||
{
|
||||
b.Property<string>("Key")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Key");
|
||||
|
||||
b.ToTable("settings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.User", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Aid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CookieToken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Ltoken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Mid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Stoken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.AchievementArchive", "Archive")
|
||||
.WithMany()
|
||||
.HasForeignKey("ArchiveId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Archive");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateEntry", "Entry")
|
||||
.WithMany()
|
||||
.HasForeignKey("EntryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Entry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.GachaArchive", "Archive")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("ArchiveId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Archive");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
116
src/Snap.Hutao/Snap.Hutao/Migrations/20221210111128_Inventory.cs
Normal file
116
src/Snap.Hutao/Snap.Hutao/Migrations/20221210111128_Inventory.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Snap.Hutao.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Inventory : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AttachedUid",
|
||||
table: "cultivate_projects",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "inventory_items",
|
||||
columns: table => new
|
||||
{
|
||||
InnerId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ProjectId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ItemId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Count = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_inventory_items", x => x.InnerId);
|
||||
table.ForeignKey(
|
||||
name: "FK_inventory_items_cultivate_projects_ProjectId",
|
||||
column: x => x.ProjectId,
|
||||
principalTable: "cultivate_projects",
|
||||
principalColumn: "InnerId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "inventory_reliquaries",
|
||||
columns: table => new
|
||||
{
|
||||
InnerId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ProjectId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ItemId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Level = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
MainPropId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
AppendPropIdList = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_inventory_reliquaries", x => x.InnerId);
|
||||
table.ForeignKey(
|
||||
name: "FK_inventory_reliquaries_cultivate_projects_ProjectId",
|
||||
column: x => x.ProjectId,
|
||||
principalTable: "cultivate_projects",
|
||||
principalColumn: "InnerId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "inventory_weapons",
|
||||
columns: table => new
|
||||
{
|
||||
InnerId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ProjectId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ItemId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Level = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
PromoteLevel = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_inventory_weapons", x => x.InnerId);
|
||||
table.ForeignKey(
|
||||
name: "FK_inventory_weapons_cultivate_projects_ProjectId",
|
||||
column: x => x.ProjectId,
|
||||
principalTable: "cultivate_projects",
|
||||
principalColumn: "InnerId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_inventory_items_ProjectId",
|
||||
table: "inventory_items",
|
||||
column: "ProjectId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_inventory_reliquaries_ProjectId",
|
||||
table: "inventory_reliquaries",
|
||||
column: "ProjectId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_inventory_weapons_ProjectId",
|
||||
table: "inventory_weapons",
|
||||
column: "ProjectId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "inventory_items");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "inventory_reliquaries");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "inventory_weapons");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AttachedUid",
|
||||
table: "cultivate_projects");
|
||||
}
|
||||
}
|
||||
}
|
||||
515
src/Snap.Hutao/Snap.Hutao/Migrations/20221217061817_ItemFinishable.Designer.cs
generated
Normal file
515
src/Snap.Hutao/Snap.Hutao/Migrations/20221217061817_ItemFinishable.Designer.cs
generated
Normal file
@@ -0,0 +1,515 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Snap.Hutao.Context.Database;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Snap.Hutao.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDbContext))]
|
||||
[Migration("20221217061817_ItemFinishable")]
|
||||
partial class ItemFinishable
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.1");
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("ArchiveId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Current")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("Time")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ArchiveId");
|
||||
|
||||
b.ToTable("achievements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.AchievementArchive", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("achievement_archives");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.AvatarInfo", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("avatar_infos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("cultivate_entries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("EntryId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsFinished")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("EntryId");
|
||||
|
||||
b.ToTable("cultivate_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateProject", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AttachedUid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("cultivate_projects");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DailyNote")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("DailyTaskNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("DailyTaskNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ExpeditionNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ExpeditionNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("HomeCoinNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("HomeCoinNotifyThreshold")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ResinNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ResinNotifyThreshold")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ShowInHomeWidget")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("TransformerNotify")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("TransformerNotifySuppressed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("daily_notes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("gacha_archives");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("ArchiveId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("GachaType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<long>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("QueryType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("Time")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ArchiveId");
|
||||
|
||||
b.ToTable("gacha_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GameAccount", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AttachUid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("MihoyoSDK")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("game_accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("Count")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("inventory_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AppendPropIdList")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Level")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MainPropId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("inventory_reliquaries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Level")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("PromoteLevel")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("inventory_weapons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.ObjectCacheEntry", b =>
|
||||
{
|
||||
b.Property<string>("Key")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset>("ExpireTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Key");
|
||||
|
||||
b.ToTable("object_cache");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.SettingEntry", b =>
|
||||
{
|
||||
b.Property<string>("Key")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Key");
|
||||
|
||||
b.ToTable("settings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.User", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Aid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CookieToken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Ltoken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Mid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Stoken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.AchievementArchive", "Archive")
|
||||
.WithMany()
|
||||
.HasForeignKey("ArchiveId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Archive");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateEntry", "Entry")
|
||||
.WithMany()
|
||||
.HasForeignKey("EntryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Entry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.GachaArchive", "Archive")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("ArchiveId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Archive");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Snap.Hutao.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ItemFinishable : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsFinished",
|
||||
table: "cultivate_items",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsFinished",
|
||||
table: "cultivate_items");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace Snap.Hutao.Migrations
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.0");
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.1");
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
|
||||
{
|
||||
@@ -82,6 +82,74 @@ namespace Snap.Hutao.Migrations
|
||||
b.ToTable("avatar_infos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("cultivate_entries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("EntryId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsFinished")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("EntryId");
|
||||
|
||||
b.ToTable("cultivate_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateProject", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AttachedUid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSelected")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.ToTable("cultivate_projects");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
@@ -212,6 +280,98 @@ namespace Snap.Hutao.Migrations
|
||||
b.ToTable("game_accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("Count")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("inventory_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AppendPropIdList")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Level")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MainPropId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("inventory_reliquaries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b =>
|
||||
{
|
||||
b.Property<Guid>("InnerId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Level")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("PromoteLevel")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("InnerId");
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.ToTable("inventory_weapons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.ObjectCacheEntry", b =>
|
||||
{
|
||||
b.Property<string>("Key")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset>("ExpireTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Key");
|
||||
|
||||
b.ToTable("object_cache");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.SettingEntry", b =>
|
||||
{
|
||||
b.Property<string>("Key")
|
||||
@@ -265,6 +425,28 @@ namespace Snap.Hutao.Migrations
|
||||
b.Navigation("Archive");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateEntry", "Entry")
|
||||
.WithMany()
|
||||
.HasForeignKey("EntryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Entry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.User", "User")
|
||||
@@ -279,13 +461,51 @@ namespace Snap.Hutao.Migrations
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.GachaArchive", "Archive")
|
||||
.WithMany()
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("ArchiveId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Archive");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b =>
|
||||
{
|
||||
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
|
||||
.WithMany()
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Snap.Hutao.Model.Binding;
|
||||
namespace Snap.Hutao.Model.Binding.Achievement;
|
||||
|
||||
/// <summary>
|
||||
/// 用于视图绑定的成就
|
||||
@@ -15,9 +15,6 @@ public class Achievement : ObservableObject
|
||||
/// </summary>
|
||||
public const int FullProgressPlaceholder = int.MaxValue;
|
||||
|
||||
private readonly Metadata.Achievement.Achievement inner;
|
||||
private readonly Entity.Achievement entity;
|
||||
|
||||
private bool isChecked;
|
||||
|
||||
/// <summary>
|
||||
@@ -27,22 +24,21 @@ public class Achievement : ObservableObject
|
||||
/// <param name="entity">实体部分</param>
|
||||
public Achievement(Metadata.Achievement.Achievement inner, Entity.Achievement entity)
|
||||
{
|
||||
this.inner = inner;
|
||||
this.entity = entity;
|
||||
Inner = inner;
|
||||
Entity = entity;
|
||||
|
||||
// Property should only be set when it's user checking.
|
||||
isChecked = (int)entity.Status >= 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实体
|
||||
/// </summary>
|
||||
public Entity.Achievement Entity { get => entity; }
|
||||
public Entity.Achievement Entity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 元数据
|
||||
/// </summary>
|
||||
public Metadata.Achievement.Achievement Inner { get => inner; }
|
||||
public Metadata.Achievement.Achievement Inner { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否选中
|
||||
@@ -57,7 +53,7 @@ public class Achievement : ObservableObject
|
||||
// Only update state when checked
|
||||
if (value)
|
||||
{
|
||||
Entity.Status = Intrinsic.AchievementInfoStatus.ACHIEVEMENT_POINT_TAKEN;
|
||||
Entity.Status = Intrinsic.AchievementInfoStatus.STATUS_REWARD_TAKEN;
|
||||
Entity.Time = DateTimeOffset.Now;
|
||||
OnPropertyChanged(nameof(Time));
|
||||
}
|
||||
@@ -69,6 +65,6 @@ public class Achievement : ObservableObject
|
||||
/// </summary>
|
||||
public string Time
|
||||
{
|
||||
get => entity.Time.ToString("yyyy.MM.dd HH:mm:ss");
|
||||
get => Entity.Time.ToString("yyyy.MM.dd HH:mm:ss");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.Achievement;
|
||||
|
||||
/// <summary>
|
||||
/// 绑定成就分类
|
||||
/// </summary>
|
||||
public class AchievementGoal : ObservableObject
|
||||
{
|
||||
private double finishPercent;
|
||||
private string? finishDescription;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的成就分类
|
||||
/// </summary>
|
||||
/// <param name="goal">分类</param>
|
||||
public AchievementGoal(Metadata.Achievement.AchievementGoal goal)
|
||||
{
|
||||
Id = goal.Id;
|
||||
Order = goal.Order;
|
||||
Name = goal.Name;
|
||||
Icon = Metadata.Converter.AchievementIconConverter.IconNameToUri(goal.Icon);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序顺序
|
||||
/// </summary>
|
||||
public int Order { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 图标
|
||||
/// </summary>
|
||||
public Uri? Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 完成百分比
|
||||
/// </summary>
|
||||
public double FinishPercent { get => finishPercent; set => SetProperty(ref finishPercent, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 完成百分比
|
||||
/// </summary>
|
||||
public string? FinishDescription { get => finishDescription; set => SetProperty(ref finishDescription, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 更新进度
|
||||
/// </summary>
|
||||
/// <param name="finished">完成项</param>
|
||||
/// <param name="count">总项</param>
|
||||
public void UpdateFinishPercent(int finished, int count)
|
||||
{
|
||||
FinishPercent = (double)finished / count;
|
||||
FinishDescription = $"{finished}/{count} - {FinishPercent:P2}";
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,17 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
using Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.AvatarProperty;
|
||||
|
||||
/// <summary>
|
||||
/// 角色信息
|
||||
/// </summary>
|
||||
public class Avatar
|
||||
public class Avatar : ICalculableSource<ICalculableAvatar>
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
@@ -25,21 +28,26 @@ public class Avatar
|
||||
/// </summary>
|
||||
public Uri SideIcon { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 名片
|
||||
/// </summary>
|
||||
public Uri NameCard { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 星级
|
||||
/// </summary>
|
||||
public ItemQuality Quality { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 元素类型
|
||||
/// </summary>
|
||||
public ElementType Element { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 等级
|
||||
/// </summary>
|
||||
public string Level { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 好感度等级
|
||||
/// </summary>
|
||||
public int FetterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 武器
|
||||
/// </summary>
|
||||
@@ -74,4 +82,25 @@ public class Avatar
|
||||
/// 双爆评分
|
||||
/// </summary>
|
||||
public string CritScore { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 好感度等级
|
||||
/// </summary>
|
||||
public int FetterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
internal AvatarId Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 等级数字
|
||||
/// </summary>
|
||||
internal int LevelNumber { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ICalculableAvatar ToCalculable()
|
||||
{
|
||||
return new CalculableAvatar(this);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,11 @@ public class Reliquary : EquipBase
|
||||
/// </summary>
|
||||
public List<ReliquarySubProperty> SecondarySubProperties { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 合成的副属性
|
||||
/// </summary>
|
||||
public List<ReliquarySubProperty> ComposedSubProperties { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 评分
|
||||
/// </summary>
|
||||
|
||||
@@ -20,13 +20,13 @@ public class ReliquarySubProperty
|
||||
Value = value;
|
||||
Score = score;
|
||||
|
||||
// only 0.2 | 0.4 | 0.6 | 0.8 | 1.0
|
||||
// only 0.25 | 0.50 | 0.75 | 1.00
|
||||
Opacity = score switch
|
||||
{
|
||||
< 25 => 0.25,
|
||||
< 50 => 0.5,
|
||||
< 75 => 0.75,
|
||||
_ => 1,
|
||||
<= 25 => 0.25,
|
||||
<= 50 => 0.50,
|
||||
<= 75 => 0.75,
|
||||
_ => 1.00,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,35 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Metadata;
|
||||
using Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.AvatarProperty;
|
||||
|
||||
/// <summary>
|
||||
/// 天赋
|
||||
/// </summary>
|
||||
public class Skill : NameIconDescription
|
||||
public class Skill : NameIconDescription, ICalculableSource<ICalculableSkill>
|
||||
{
|
||||
/// <summary>
|
||||
/// 技能属性
|
||||
/// </summary>
|
||||
public LevelParam<string, ParameterInfo> Info { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 技能组Id
|
||||
/// </summary>
|
||||
internal int GroupId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 技能等级,仅用于养成计算
|
||||
/// </summary>
|
||||
internal int LevelNumber { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ICalculableSkill ToCalculable()
|
||||
{
|
||||
return new CalculableSkill(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
using Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.AvatarProperty;
|
||||
|
||||
/// <summary>
|
||||
/// 武器
|
||||
/// </summary>
|
||||
public class Weapon : EquipBase
|
||||
public class Weapon : EquipBase, ICalculableSource<ICalculableWeapon>
|
||||
{
|
||||
/// <summary>
|
||||
/// 副属性
|
||||
@@ -27,4 +31,20 @@ public class Weapon : EquipBase
|
||||
/// 精炼被动
|
||||
/// </summary>
|
||||
public string AffixDescription { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
internal WeaponId Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 等级数字
|
||||
/// </summary>
|
||||
internal int LevelNumber { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ICalculableWeapon ToCalculable()
|
||||
{
|
||||
return new CalculableWeapon(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Binding.Gacha.Abstraction;
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.Cultivation;
|
||||
|
||||
/// <summary>
|
||||
/// 养成物品
|
||||
/// </summary>
|
||||
public class CultivateEntry : ItemBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造一个新的养成清单入口
|
||||
/// </summary>
|
||||
/// <param name="entry">实体入口</param>
|
||||
/// <param name="itemBase">对应物品</param>
|
||||
/// <param name="items">物品列表</param>
|
||||
public CultivateEntry(Entity.CultivateEntry entry, ItemBase itemBase, List<CultivateItem> items)
|
||||
{
|
||||
Id = entry.Id;
|
||||
EntryId = entry.InnerId;
|
||||
Name = itemBase.Name;
|
||||
Icon = itemBase.Icon;
|
||||
Badge = itemBase.Badge;
|
||||
Quality = itemBase.Quality;
|
||||
Items = items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 入口Id
|
||||
/// </summary>
|
||||
public Guid EntryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实体
|
||||
/// </summary>
|
||||
public List<CultivateItem> Items { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Snap.Hutao.Model.Metadata;
|
||||
using Snap.Hutao.Service.Cultivation;
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.Cultivation;
|
||||
|
||||
/// <summary>
|
||||
/// 养成物品
|
||||
/// </summary>
|
||||
public class CultivateItem : ObservableObject
|
||||
{
|
||||
private bool isFinished;
|
||||
|
||||
/// <summary>
|
||||
/// 养成物品
|
||||
/// </summary>
|
||||
/// <param name="inner">元数据</param>
|
||||
/// <param name="entity">实体</param>
|
||||
public CultivateItem(Material inner, Entity.CultivateItem entity)
|
||||
{
|
||||
Inner = inner;
|
||||
Entity = entity;
|
||||
isFinished = Entity.IsFinished;
|
||||
IsToday = CultivateItemHelper.IsTodaysMaterial(inner.Id, DateTimeOffset.Now);
|
||||
|
||||
FinishStateCommand = new RelayCommand(FlipIsFinished);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 元数据
|
||||
/// </summary>
|
||||
public Material Inner { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 实体
|
||||
/// </summary>
|
||||
public Entity.CultivateItem Entity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 调整完成状态命令
|
||||
/// </summary>
|
||||
public ICommand FinishStateCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否完成此项
|
||||
/// </summary>
|
||||
public bool IsFinished
|
||||
{
|
||||
get => isFinished; set
|
||||
{
|
||||
if (SetProperty(ref isFinished, value))
|
||||
{
|
||||
Entity.IsFinished = value;
|
||||
Ioc.Default.GetRequiredService<ICultivationService>().SaveCultivateItem(Entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为今日物品
|
||||
/// </summary>
|
||||
public bool IsToday { get; }
|
||||
|
||||
private void FlipIsFinished()
|
||||
{
|
||||
IsFinished = !IsFinished;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.Cultivation;
|
||||
|
||||
/// <summary>
|
||||
/// 养成物品帮助类
|
||||
/// </summary>
|
||||
public static class CultivateItemHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 判断是否为当日物品
|
||||
/// </summary>
|
||||
/// <param name="itemId">材料Id</param>
|
||||
/// <param name="now">时间</param>
|
||||
/// <returns>是否为当日物品</returns>
|
||||
public static bool IsTodaysMaterial(int itemId, DateTimeOffset now)
|
||||
{
|
||||
DateTimeOffset utcNow = now.ToUniversalTime();
|
||||
utcNow = utcNow.AddHours(4);
|
||||
DayOfWeek dayOfWeek = utcNow.DayOfWeek;
|
||||
|
||||
return dayOfWeek switch
|
||||
{
|
||||
DayOfWeek.Monday or DayOfWeek.Thursday => itemId switch
|
||||
{
|
||||
104301 or 104302 or 104303 => true, // 「自由」
|
||||
104310 or 104311 or 104312 => true, // 「繁荣」
|
||||
104320 or 104321 or 104322 => true, // 「浮世」
|
||||
104329 or 104330 or 104331 => true, // 「诤言」
|
||||
114001 or 114002 or 114003 or 114004 => true, // 高塔孤王
|
||||
114013 or 114014 or 114015 or 114016 => true, // 孤云寒林
|
||||
114025 or 114026 or 114027 or 114028 => true, // 远海夷地
|
||||
114037 or 114038 or 114039 or 114040 => true, // 谧林涓露
|
||||
_ => false,
|
||||
},
|
||||
DayOfWeek.Tuesday or DayOfWeek.Friday => itemId switch
|
||||
{
|
||||
104304 or 104305 or 104306 => true, // 「抗争」
|
||||
104313 or 104314 or 104315 => true, // 「勤劳」
|
||||
104323 or 104324 or 104325 => true, // 「风雅」
|
||||
104332 or 104333 or 104334 => true, // 「巧思」
|
||||
114005 or 114006 or 114007 or 114008 => true, // 凛风奔狼
|
||||
114017 or 114018 or 114019 or 114020 => true, // 雾海云间
|
||||
114029 or 114030 or 114031 or 114032 => true, // 鸣神御灵
|
||||
114041 or 114042 or 114043 or 114044 => true, // 绿洲花园
|
||||
_ => false,
|
||||
},
|
||||
DayOfWeek.Wednesday or DayOfWeek.Saturday => itemId switch
|
||||
{
|
||||
104307 or 104308 or 104309 => true, // 「诗文」
|
||||
104316 or 104317 or 104318 => true, // 「黄金」
|
||||
104326 or 104327 or 104328 => true, // 「天光」
|
||||
104335 or 104336 or 104337 => true, // 「笃行」
|
||||
114009 or 114010 or 114011 or 114012 => true, // 狮牙斗士
|
||||
114021 or 114022 or 114023 or 114024 => true, // 漆黑陨铁
|
||||
114033 or 114034 or 114035 or 114036 => true, // 今昔剧画
|
||||
114045 or 114046 or 114047 or 114048 => true, // 谧林涓露
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.Cultivation;
|
||||
|
||||
/// <summary>
|
||||
/// 养成主体的类型
|
||||
/// </summary>
|
||||
public enum CultivateType
|
||||
{
|
||||
/// <summary>
|
||||
/// 无
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// 角色与技能
|
||||
/// </summary>
|
||||
AvatarAndSkill,
|
||||
|
||||
/// <summary>
|
||||
/// 武器
|
||||
/// </summary>
|
||||
Weapon,
|
||||
|
||||
/// <summary>
|
||||
/// 家具
|
||||
/// </summary>
|
||||
Furniture,
|
||||
}
|
||||
@@ -41,6 +41,14 @@ public class TypedWishSummary : WishBase
|
||||
/// </summary>
|
||||
public int LastOrangePull { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 据上个五星抽数格式化
|
||||
/// </summary>
|
||||
public string LastOrangePullFormatted
|
||||
{
|
||||
get => $"已垫 {LastOrangePull} 抽";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 五星保底阈值
|
||||
/// </summary>
|
||||
@@ -51,6 +59,14 @@ public class TypedWishSummary : WishBase
|
||||
/// </summary>
|
||||
public int LastPurplePull { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 据上个四星抽数格式化
|
||||
/// </summary>
|
||||
public string LastPurplePullFormatted
|
||||
{
|
||||
get => $"已垫 {LastPurplePull} 抽";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 四星保底阈值
|
||||
/// </summary>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Metadata.Avatar;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.Hutao;
|
||||
@@ -9,18 +8,8 @@ namespace Snap.Hutao.Model.Binding.Hutao;
|
||||
/// <summary>
|
||||
/// 角色搭配
|
||||
/// </summary>
|
||||
public class ComplexAvatarCollocation : ComplexAvatar
|
||||
public class ComplexAvatarCollocation
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造一个新的角色搭配
|
||||
/// </summary>
|
||||
/// <param name="avatar">角色</param>
|
||||
/// <param name="rate">比率</param>
|
||||
public ComplexAvatarCollocation(Avatar avatar)
|
||||
: base(avatar, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 角色Id
|
||||
/// </summary>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Metadata.Converter;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
using Snap.Hutao.Web.Hutao.Model;
|
||||
using System.Text;
|
||||
|
||||
@@ -17,7 +18,7 @@ public class ComplexReliquarySet
|
||||
/// </summary>
|
||||
/// <param name="reliquarySetRate">圣遗物套装率</param>
|
||||
/// <param name="idReliquarySetMap">圣遗物套装映射</param>
|
||||
public ComplexReliquarySet(ItemRate<ReliquarySets, double> reliquarySetRate, Dictionary<int, Metadata.Reliquary.ReliquarySet> idReliquarySetMap)
|
||||
public ComplexReliquarySet(ItemRate<ReliquarySets, double> reliquarySetRate, Dictionary<EquipAffixId, Metadata.Reliquary.ReliquarySet> idReliquarySetMap)
|
||||
{
|
||||
ReliquarySets sets = reliquarySetRate.Item;
|
||||
|
||||
@@ -43,7 +44,7 @@ public class ComplexReliquarySet
|
||||
}
|
||||
else
|
||||
{
|
||||
Name = "无圣遗物";
|
||||
Name = "无圣遗物或散件";
|
||||
}
|
||||
|
||||
Rate = $"{reliquarySetRate.Rate:P3}";
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Metadata.Avatar;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
using Snap.Hutao.Web.Hutao.Model;
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.Hutao;
|
||||
@@ -16,7 +17,7 @@ internal class ComplexTeamRank
|
||||
/// </summary>
|
||||
/// <param name="teamRank">队伍排行</param>
|
||||
/// <param name="idAvatarMap">映射</param>
|
||||
public ComplexTeamRank(TeamAppearance teamRank, Dictionary<int, Avatar> idAvatarMap)
|
||||
public ComplexTeamRank(TeamAppearance teamRank, Dictionary<AvatarId, Avatar> idAvatarMap)
|
||||
{
|
||||
Floor = $"第 {teamRank.Floor} 层";
|
||||
Up = teamRank.Up.Select(teamRate => new Team(teamRate, idAvatarMap)).ToList();
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.Hutao;
|
||||
|
||||
/// <summary>
|
||||
/// 武器搭配
|
||||
/// </summary>
|
||||
public class ComplexWeaponCollocation
|
||||
{
|
||||
/// <summary>
|
||||
/// 武器Id
|
||||
/// </summary>
|
||||
public WeaponId WeaponId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色
|
||||
/// </summary>
|
||||
public List<ComplexAvatar> Avatars { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Metadata;
|
||||
using Snap.Hutao.Model.Metadata.Avatar;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
|
||||
namespace Snap.Hutao.Model.Binding.Hutao;
|
||||
|
||||
/// <summary>
|
||||
/// 料理奖励视图
|
||||
/// </summary>
|
||||
public class CookBonusView
|
||||
{
|
||||
/// <summary>
|
||||
/// 原型
|
||||
/// </summary>
|
||||
public Material OriginItem { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public Material Item { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个新的料理奖励视图
|
||||
/// </summary>
|
||||
/// <param name="cookBonus">料理奖励</param>
|
||||
/// <param name="idMaterialMap">材料映射</param>
|
||||
/// <returns>新的料理奖励视图</returns>
|
||||
public static CookBonusView? Create(CookBonus? cookBonus, Dictionary<MaterialId, Material> idMaterialMap)
|
||||
{
|
||||
if (cookBonus == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
CookBonusView view = new()
|
||||
{
|
||||
OriginItem = idMaterialMap[cookBonus.OriginItemId],
|
||||
Item = idMaterialMap[cookBonus.ItemId],
|
||||
};
|
||||
|
||||
return view;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user