Skip to content

Commit 745c99f

Browse files
authored
feat(Memorial): add Memorial Mode (#5584)
* style: memorial mode * refactor: 撤销格式化 * refactor: 撤销格式化 * doc: 更改注释为英文 * feat: 增加 IsMemorialMode 参数 * style: 增加追悼样式 * doc: 更新注释 * feat: 增加 setMemorialMode 方法 * doc: 增加追悼模式实战网页 * doc: 更新文档 * doc: 移除主题菜单 * test: 增加单元测试
1 parent b25e6fb commit 745c99f

File tree

12 files changed

+185
-89
lines changed

12 files changed

+185
-89
lines changed

src/BootstrapBlazor.Server/Components/Components/Header.razor

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
<li class="nav-item">
2121
<a class="nav-link" href="tutorials">@TutorialsText</a>
2222
</li>
23-
@if (CultureInfo.CurrentUICulture.Name == "zh-CN")
23+
@* @if (CultureInfo.CurrentUICulture.Name == "zh-CN")
2424
{
2525
<li class="nav-item">
2626
<a class="nav-link" href="https://theme.blazor.zone">主题</a>
2727
</li>
28-
}
28+
} *@
2929
</ul>
3030
</div>
3131
<div class="d-flex flex-fill"></div>

src/BootstrapBlazor.Server/Components/Layout/TutorialsNavMenu.razor.cs

+5
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ protected override async Task OnInitializedAsync()
110110
{
111111
Text = Localizer["OnlineSheet"],
112112
Url = "tutorials/online-sheet",
113+
},
114+
new()
115+
{
116+
Text = Localizer["MemorialMode"],
117+
Url = "tutorials/memorial",
113118
}
114119
]);
115120
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@page "/tutorials/memorial"
2+
3+
<Button Text="切换哀悼模式" OnClick="OnToggle" class="mb-3"></Button>
4+
5+
<p class="code-label">1. 加载 <code>Utlity</code> 工具</p>
6+
<Pre>var module = await JSRuntime.LoadUtility();</Pre>
7+
8+
<p class="code-label">2. 设置哀悼模式</p>
9+
<Pre>await module.InvokeVoidAsync("SetMemorial", true);</Pre>
10+
11+
<p class="code-label">3. 全站默认设置追悼模式方法</p>
12+
<p>更新 <code>App.razor</code> 文档内容如下</p>
13+
<Pre>&lt;html lang="en" data-bs-theme='dark' data-bb-theme="memorial"&gt;</Pre>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the Apache 2.0 License
3+
// See the LICENSE file in the project root for more information.
4+
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
5+
6+
using Microsoft.JSInterop;
7+
8+
namespace BootstrapBlazor.Server.Components.Samples.Tutorials;
9+
10+
/// <summary>
11+
/// 追悼模式
12+
/// </summary>
13+
public partial class Memorial
14+
{
15+
[Inject, NotNull]
16+
private IJSRuntime? JSRuntime { get; set; }
17+
18+
private bool _isMemorial = false;
19+
20+
private async Task OnToggle()
21+
{
22+
var module = await JSRuntime.LoadUtility();
23+
24+
_isMemorial = !_isMemorial;
25+
await module.SetMemorialModeAsync(_isMemorial);
26+
}
27+
}

src/BootstrapBlazor.Server/Locales/en-US.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"TranslateSummary": "Translate",
2323
"DrawingSummary": "Drawing",
2424
"AdminSummary": "Admin",
25-
"OnlineSheet": "UniverSheet"
25+
"OnlineSheet": "UniverSheet",
26+
"MemorialMode": "Memorial"
2627
},
2728
"BootstrapBlazor.Server.Components.Components.Pre": {
2829
"LoadingText": "Loading ...",

src/BootstrapBlazor.Server/Locales/zh-CN.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"TranslateSummary": "翻译工具 Translate",
2323
"DrawingSummary": "画图 Drawing",
2424
"AdminSummary": "中台 Admin",
25-
"OnlineSheet": "在线表格 UniverSheet"
25+
"OnlineSheet": "在线表格 UniverSheet",
26+
"MemorialMode": "追悼模式"
2627
},
2728
"BootstrapBlazor.Server.Components.Components.Pre": {
2829
"LoadingText": "正在加载 ...",

src/BootstrapBlazor/Extensions/JSModuleExtensions.cs

+54-46
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,33 @@ namespace BootstrapBlazor.Components;
1111
public static class JSModuleExtensions
1212
{
1313
/// <summary>
14-
/// 导入 utility js 模块
14+
/// Load utility js module
1515
/// </summary>
16-
/// <param name="jsRuntime"></param>
17-
/// <param name="version"></param>
18-
/// <returns>A <see cref="Task"/><![CDATA[<]]><see cref="JSModule"/><![CDATA[>]]> 模块加载器</returns>
16+
/// <param name="jsRuntime">The <see cref="IJSRuntime"/> instance</param>
17+
/// <param name="version">The version of the module</param>
18+
/// <returns>A <see cref="Task"/><![CDATA[<]]><see cref="JSModule"/><![CDATA[>]]> module loader</returns>
1919
public static Task<JSModule> LoadUtility(this IJSRuntime jsRuntime, string? version = null) => LoadModuleByName(jsRuntime, "utility", version);
2020

2121
/// <summary>
22-
/// 通过名称导入内置脚本模块
22+
/// Load built-in script module by name
2323
/// </summary>
24-
/// <param name="jsRuntime"></param>
25-
/// <param name="moduleName"></param>
26-
/// <param name="version"></param>
27-
/// <returns>A <see cref="Task"/><![CDATA[<]]><see cref="JSModule"/><![CDATA[>]]> 模块加载器</returns>
24+
/// <param name="jsRuntime">The <see cref="IJSRuntime"/> instance</param>
25+
/// <param name="moduleName">The name of the module</param>
26+
/// <param name="version">The version of the module</param>
27+
/// <returns>A <see cref="Task"/><![CDATA[<]]><see cref="JSModule"/><![CDATA[>]]> module loader</returns>
2828
public static Task<JSModule> LoadModuleByName(this IJSRuntime jsRuntime, string moduleName, string? version = null)
2929
{
3030
var fileName = $"./_content/BootstrapBlazor/modules/{moduleName}.js";
3131
return LoadModule(jsRuntime, fileName, version);
3232
}
3333

3434
/// <summary>
35-
/// IJSRuntime 扩展方法 动态加载脚本
35+
/// IJSRuntime extension method to dynamically load scripts
3636
/// </summary>
37-
/// <param name="jsRuntime"></param>
38-
/// <param name="fileName"></param>
39-
/// <param name="version"></param>
40-
/// <returns>A <see cref="Task"/><![CDATA[<]]><see cref="JSModule"/><![CDATA[>]]> 模块加载器</returns>
37+
/// <param name="jsRuntime">The <see cref="IJSRuntime"/> instance</param>
38+
/// <param name="fileName">The file name of the script</param>
39+
/// <param name="version">The version of the script</param>
40+
/// <returns>A <see cref="Task"/><![CDATA[<]]><see cref="JSModule"/><![CDATA[>]]> module loader</returns>
4141
public static async Task<JSModule> LoadModule(this IJSRuntime jsRuntime, string fileName, string? version = null)
4242
{
4343
if (!string.IsNullOrEmpty(version))
@@ -64,10 +64,10 @@ public static async Task<JSModule> LoadModule(this IJSRuntime jsRuntime, string
6464
}
6565

6666
/// <summary>
67-
/// 获得指定类型的加载 Module 名称
67+
/// Get the module name of the specified type
6868
/// </summary>
69-
/// <param name="type"></param>
70-
/// <returns></returns>
69+
/// <param name="type">The type</param>
70+
/// <returns>The module name</returns>
7171
public static string GetTypeModuleName(this Type type)
7272
{
7373
var name = type.Name;
@@ -80,47 +80,47 @@ public static string GetTypeModuleName(this Type type)
8080
}
8181

8282
/// <summary>
83-
/// 在新标签页打开指定网址
83+
/// Open the specified URL in a new tab
8484
/// </summary>
85-
/// <param name="module"><see cref="JSModule"/> 实例</param>
86-
/// <param name="url">打开网页地址</param>
87-
/// <param name="target">默认 _blank</param>
88-
/// <param name="features">默认 null</param>
85+
/// <param name="module"><see cref="JSModule"/> instance</param>
86+
/// <param name="url">The URL to open</param>
87+
/// <param name="target">The target window, default is _blank</param>
88+
/// <param name="features">The features of the new window, default is null</param>
8989
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous invocation operation.</returns>
9090
public static ValueTask OpenUrl(this JSModule module, string url, string? target = "_blank", string? features = null) => module.InvokeVoidAsync("openUrl", url, target, features);
9191

9292
/// <summary>
93-
/// 动态运行js代码
93+
/// Dynamically run js code
9494
/// </summary>
95-
/// <param name="module"><see cref="JSModule"/> 实例</param>
96-
/// <param name="script"></param>
95+
/// <param name="module"><see cref="JSModule"/> instance</param>
96+
/// <param name="script">The script to run</param>
9797
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous invocation operation.</returns>
9898
public static async ValueTask Eval(this JSModule module, string script) => await module.InvokeVoidAsync("runEval", script);
9999

100100
/// <summary>
101-
/// 通过 Eval 动态运行 JavaScript 代码
101+
/// Dynamically run JavaScript code via Eval
102102
/// </summary>
103-
/// <param name="module"><see cref="JSModule"/> 实例</param>
104-
/// <param name="script"></param>
103+
/// <param name="module"><see cref="JSModule"/> instance</param>
104+
/// <param name="script">The script to run</param>
105105
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous invocation operation.</returns>
106106
public static ValueTask<TValue?> Eval<TValue>(this JSModule module, string script) => module.InvokeAsync<TValue?>("runEval", script);
107107

108108
/// <summary>
109-
/// 通过 Function 动态运行 JavaScript 代码
109+
/// Dynamically run JavaScript code via Function
110110
/// </summary>
111-
/// <param name="module"><see cref="JSModule"/> 实例</param>
112-
/// <param name="script"></param>
113-
/// <param name="args"></param>
111+
/// <param name="module"><see cref="JSModule"/> instance</param>
112+
/// <param name="script">The script to run</param>
113+
/// <param name="args">The arguments to pass to the script</param>
114114
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous invocation operation.</returns>
115115
public static ValueTask Function(this JSModule module, string script, params object?[]? args) => module.InvokeVoidAsync("runFunction", script, args);
116116

117117
/// <summary>
118-
/// 动态运行js代码
118+
/// Dynamically run js code
119119
/// </summary>
120-
/// <typeparam name="TValue"></typeparam>
121-
/// <param name="module"><see cref="JSModule"/> 实例</param>
122-
/// <param name="script"></param>
123-
/// <param name="args"></param>
120+
/// <typeparam name="TValue">The return type</typeparam>
121+
/// <param name="module"><see cref="JSModule"/> instance</param>
122+
/// <param name="script">The script to run</param>
123+
/// <param name="args">The arguments to pass to the script</param>
124124
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous invocation operation.</returns>
125125
public static async ValueTask<TValue?> Function<TValue>(this JSModule module, string script, params object?[]? args)
126126
{
@@ -133,41 +133,49 @@ public static string GetTypeModuleName(this Type type)
133133
}
134134

135135
/// <summary>
136-
/// 获取当前终端是否为移动设备
136+
/// Check if the current terminal is a mobile device
137137
/// </summary>
138-
/// <param name="module"><see cref="JSModule"/> 实例</param>
138+
/// <param name="module"><see cref="JSModule"/> instance</param>
139139
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous invocation operation.</returns>
140140
public static ValueTask<bool> IsMobile(this JSModule module) => module.InvokeAsync<bool>("isMobile");
141141

142142
/// <summary>
143-
/// 获取一个页面上不重复的元素ID
143+
/// Get a unique element ID on a page
144144
/// </summary>
145145
/// <param name="module">An instance of <see cref="JSModule"/></param>
146146
/// <param name="prefix">A prefix of type <see cref="string"/></param>
147147
/// <returns>Returns a <see cref="string"/> formatted element ID</returns>
148148
public static ValueTask<string?> GenerateId(this JSModule module, string? prefix = null) => module.InvokeAsync<string?>("getUID", prefix);
149149

150150
/// <summary>
151-
/// 获取一个页面内指定元素 Html 字符串
151+
/// Get the HTML string of a specified element on a page
152152
/// </summary>
153153
/// <param name="module">An instance of <see cref="JSModule"/></param>
154-
/// <param name="id"></param>
155-
/// <param name="selector"></param>
154+
/// <param name="id">The ID of the element</param>
155+
/// <param name="selector">The selector of the element</param>
156156
/// <returns>Returns a <see cref="string"/> formatted element ID</returns>
157157
public static ValueTask<string?> GetHtml(this JSModule module, string? id = null, string? selector = null) => module.InvokeAsync<string?>("getHtml", new { id, selector });
158158

159159
/// <summary>
160-
/// 设置主题方法
160+
/// Set the theme method
161161
/// </summary>
162162
/// <param name="module">An instance of <see cref="JSModule"/></param>
163-
/// <param name="themeName">theme name</param>
163+
/// <param name="themeName">The name of the theme</param>
164164
/// <returns></returns>
165165
public static ValueTask SetThemeAsync(this JSModule module, string themeName) => module.InvokeVoidAsync("setTheme", themeName, true);
166166

167167
/// <summary>
168-
/// 设置主题方法
168+
/// Get the theme method
169169
/// </summary>
170170
/// <param name="module">An instance of <see cref="JSModule"/></param>
171171
/// <returns></returns>
172172
public static ValueTask<string?> GetThemeAsync(this JSModule module) => module.InvokeAsync<string?>("getTheme");
173+
174+
/// <summary>
175+
/// Set memorial mode
176+
/// </summary>
177+
/// <param name="module">An instance of <see cref="JSModule"/></param>
178+
/// <param name="isMemorial">Whether it is memorial mode</param>
179+
/// <returns></returns>
180+
public static ValueTask SetMemorialModeAsync(this JSModule module, bool isMemorial) => module.InvokeVoidAsync("setMemorialMode", isMemorial);
173181
}

0 commit comments

Comments
 (0)