-
-
Notifications
You must be signed in to change notification settings - Fork 362
feat(NetworkMonitor): add NetworkMonitor component #6405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
edb44d1
refactor: 增加 NetworkMonitor 组件
ArgoZhang c16bbe3
doc: 增加使用示例
ArgoZhang c4f8793
feat: 增加 Indicator 参数
ArgoZhang 742e74a
style: 增加样式
ArgoZhang af6bbb2
feat: 增加网络状态指示器组件
ArgoZhang 6dc4289
feat: 增加离线状态指示
ArgoZhang 2ce3876
refactor: 撤销更改
ArgoZhang b6971fd
doc: 更新示例
ArgoZhang 1b0dbaa
feat: 增加恢复 Online 状态后重置数据方法
ArgoZhang 6263986
refactor: 减少一次网络请求
ArgoZhang 413ba2b
style: 更新样式
ArgoZhang 266e61e
refactor: 调整参数顺序
ArgoZhang d74f79d
refactor: 复用代码
ArgoZhang 60af62d
doc: 增加资源文件
ArgoZhang bc40ecd
test: 增加单元测试
ArgoZhang 292e6a0
test: 更新单元测试
ArgoZhang bfa0d8c
doc: 更新资源文件
ArgoZhang 87fa1c0
test: 增加单元测试
ArgoZhang f569fe4
doc: 更新示例
ArgoZhang 127de2b
refactor: 重构代码
ArgoZhang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
src/BootstrapBlazor/Components/NetworkMonitor/NetworkMonitor.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the Apache 2.0 License | ||
| // See the LICENSE file in the project root for more information. | ||
| // Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone | ||
|
|
||
| namespace BootstrapBlazor.Components; | ||
|
|
||
| /// <summary> | ||
| /// 客户端链接组件 | ||
| /// </summary> | ||
| [BootstrapModuleAutoLoader(ModuleName = "net", JSObjectReference = true)] | ||
| public class NetworkMonitor : BootstrapModuleComponentBase | ||
| { | ||
| /// <summary> | ||
| /// Gets or sets the callback function that is invoked when the network state changes. | ||
| /// </summary> | ||
| [Parameter] | ||
| public Func<NetworkMonitorState, Task>? OnNetworkStateChanged { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the list of indicators used for display info. | ||
| /// </summary> | ||
| [Parameter] | ||
| public List<string>? Indicators { get; set; } | ||
|
|
||
| private NetworkMonitorState _state = new(); | ||
|
|
||
| /// <summary> | ||
| /// <inheritdoc/> | ||
| /// </summary> | ||
| /// <returns></returns> | ||
| protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, new | ||
| { | ||
| Invoke = Interop, | ||
| OnlineStateChangedCallback = nameof(TriggerOnlineStateChanged), | ||
| OnNetworkStateChangedCallback = nameof(TriggerNetworkStateChanged), | ||
| Indicators | ||
| }); | ||
|
|
||
| /// <summary> | ||
| /// JSInvoke 回调方法 | ||
| /// </summary> | ||
| /// <returns></returns> | ||
| [JSInvokable] | ||
| public async Task TriggerOnlineStateChanged(bool online) | ||
| { | ||
| _state.IsOnline = online; | ||
| if (OnNetworkStateChanged != null) | ||
| { | ||
| await OnNetworkStateChanged(_state); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// JSInvoke 回调方法 | ||
| /// </summary> | ||
| /// <returns></returns> | ||
| [JSInvokable] | ||
| public async Task TriggerNetworkStateChanged(NetworkMonitorState state) | ||
| { | ||
| // 网络状态变化回调方法 | ||
| _state = state; | ||
| _state.IsOnline = true; | ||
| if (OnNetworkStateChanged != null) | ||
| { | ||
| await OnNetworkStateChanged(_state); | ||
| } | ||
| } | ||
| } |
26 changes: 26 additions & 0 deletions
26
src/BootstrapBlazor/Components/NetworkMonitor/NetworkMonitorIndicator.razor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| @namespace BootstrapBlazor.Components | ||
| @inherits IdComponentBase | ||
|
|
||
| <Popover Title="@Title" Trigger="@Trigger" Placement="@PopoverPlacement"> | ||
| <ChildContent> | ||
| <span @attributes="@AdditionalAttributes" id="@Id" tabindex="0" class="@ClassString"></span> | ||
| </ChildContent> | ||
| <Template> | ||
| <div class="bb-nt-main"> | ||
| <div class="bb-nt-item"> | ||
| <span>NetworkType:</span> | ||
| <div>@_state.NetworkType</div> | ||
| </div> | ||
| <div class="bb-nt-item"> | ||
| <span>Downlink:</span> | ||
| <div>@_state.Downlink Mbps</div> | ||
| </div> | ||
| <div class="bb-nt-item"> | ||
| <span>RTT:</span> | ||
| <div>@_state.RTT ms</div> | ||
| </div> | ||
| </div> | ||
| </Template> | ||
| </Popover> | ||
|
|
||
| <NetworkMonitor OnNetworkStateChanged="OnNetworkStateChanged" Indicators="@_indicators"></NetworkMonitor> | ||
83 changes: 83 additions & 0 deletions
83
src/BootstrapBlazor/Components/NetworkMonitor/NetworkMonitorIndicator.razor.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the Apache 2.0 License | ||
| // See the LICENSE file in the project root for more information. | ||
| // Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone | ||
|
|
||
| using Microsoft.Extensions.Localization; | ||
|
|
||
| namespace BootstrapBlazor.Components; | ||
|
|
||
| /// <summary> | ||
| /// Represents a network monitor indicator with customizable tooltip settings. | ||
| /// </summary> | ||
| /// <remarks>This component allows you to configure the text, placement, and trigger behavior of a tooltip that | ||
| /// appears when interacting with the network monitor indicator. The tooltip can be customized to provide additional | ||
| /// information to users.</remarks> | ||
| public partial class NetworkMonitorIndicator | ||
| { | ||
| /// <summary> | ||
| /// 获得/设置 Popover 弹窗标题 默认为 null | ||
| /// </summary> | ||
| [Parameter] | ||
| public string? Title { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// 获得/设置 Popover 显示位置 默认为 Top | ||
| /// </summary> | ||
| [Parameter] | ||
| public Placement PopoverPlacement { get; set; } = Placement.Top; | ||
|
|
||
| /// <summary> | ||
| /// 获得/设置 Popover 触发方式 默认为 hover focus | ||
| /// </summary> | ||
| [Parameter] | ||
| [NotNull] | ||
| public string? Trigger { get; set; } | ||
|
|
||
| [Inject, NotNull] | ||
| private IStringLocalizer<NetworkMonitorIndicator>? Localizer { get; set; } | ||
|
|
||
| private NetworkMonitorState _state = new(); | ||
| private readonly List<string> _indicators = []; | ||
| private string _networkTypeString = ""; | ||
| private string _downlinkString = ""; | ||
| private string _rttString = ""; | ||
|
|
||
| private string? ClassString => CssBuilder.Default("bb-nt-indicator") | ||
| .AddClass("bb-nt-indicator-4g", _state.NetworkType == "4g") | ||
| .AddClass("bb-nt-indicator-3g", _state.NetworkType == "3g") | ||
| .AddClass("bb-nt-indicator-2g", _state.NetworkType == "2g") | ||
| .AddClassFromAttributes(AdditionalAttributes) | ||
| .Build(); | ||
|
|
||
| /// <summary> | ||
| /// <inheritdoc/> | ||
| /// </summary> | ||
| protected override void OnInitialized() | ||
| { | ||
| base.OnInitialized(); | ||
|
|
||
| _indicators.Add(Id); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// <inheritdoc/> | ||
| /// </summary> | ||
| protected override void OnParametersSet() | ||
| { | ||
| base.OnParametersSet(); | ||
|
|
||
| Trigger ??= "hover focus"; | ||
| Title ??= Localizer["Title"]; | ||
| _networkTypeString = Localizer["NetworkType"]; | ||
| _downlinkString = Localizer["Downlink"]; | ||
| _rttString = Localizer["RTT"]; | ||
| } | ||
|
|
||
| private Task OnNetworkStateChanged(NetworkMonitorState state) | ||
| { | ||
| _state = state; | ||
| StateHasChanged(); | ||
| return Task.CompletedTask; | ||
| } | ||
| } |
52 changes: 52 additions & 0 deletions
52
src/BootstrapBlazor/Components/NetworkMonitor/NetworkMonitorIndicator.razor.scss
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| .bb-nt-indicator { | ||
| --bb-nt-indicator-width: .5rem; | ||
| --bb-nt-indicator-border-radius: 50%; | ||
| --bb-nt-indicator-bg: var(--bs-secondary); | ||
| background: var(--bb-nt-indicator-bg); | ||
| cursor: pointer; | ||
| width: var(--bb-nt-indicator-width); | ||
| height: var(--bb-nt-indicator-width); | ||
| border-radius: var(--bb-nt-indicator-border-radius); | ||
| display: inline-block; | ||
|
|
||
| &.bb-nt-indicator-4g { | ||
| background-color: var(--bs-success); | ||
| } | ||
|
|
||
| &.bb-nt-indicator-3g { | ||
| background-color: var(--bs-warning); | ||
| } | ||
|
|
||
| &.bb-nt-indicator-2g { | ||
| background-color: var(--bs-danger); | ||
| } | ||
|
|
||
| &.offline { | ||
| background-color: var(--bs-secondary); | ||
| } | ||
| } | ||
|
|
||
| [data-bs-toggle="popover"]:has(.offline) { | ||
| pointer-events: none; | ||
| } | ||
|
|
||
| .bb-nt-main { | ||
| .bb-nt-item { | ||
| display: flex; | ||
| align-items: center; | ||
|
|
||
| > span { | ||
| width: 120px; | ||
| } | ||
|
|
||
| > div { | ||
| flex: 1; | ||
| min-width: 0; | ||
| width: 1%; | ||
| } | ||
|
|
||
| &:not(:last-child) { | ||
| margin-bottom: .5rem; | ||
| } | ||
| } | ||
| } |
32 changes: 32 additions & 0 deletions
32
src/BootstrapBlazor/Components/NetworkMonitor/NetworkMonitorState.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the Apache 2.0 License | ||
| // See the LICENSE file in the project root for more information. | ||
| // Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone | ||
|
|
||
| namespace BootstrapBlazor.Components; | ||
|
|
||
| /// <summary> | ||
| /// 网络状态信息类 | ||
| /// </summary> | ||
| public class NetworkMonitorState | ||
| { | ||
| /// <summary> | ||
| /// Gets or sets a value indicating whether the network is online | ||
| /// </summary> | ||
| public bool IsOnline { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the current network type | ||
| /// </summary> | ||
| public string? NetworkType { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the downlink speed in megabits per second (Mbps). | ||
| /// </summary> | ||
| public double? Downlink { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the round-trip time (RTT) in milliseconds. | ||
| /// </summary> | ||
| public int RTT { get; set; } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| import Data from "./data.js" | ||
| import EventHandler from "./event-handler.js"; | ||
|
|
||
| export function init(id, options) { | ||
| const { invoke, onlineStateChangedCallback, onNetworkStateChangedCallback, indicators } = options; | ||
| const updateState = nt => { | ||
| const { downlink, effectiveType, rtt } = nt; | ||
| invoke.invokeMethodAsync(onNetworkStateChangedCallback, { | ||
| downlink, networkType: effectiveType, rTT: rtt | ||
ArgoZhang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }); | ||
| } | ||
| navigator.connection.onchange = e => { | ||
ArgoZhang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| updateState(e.target); | ||
| } | ||
|
|
||
| const onlineStateChanged = () => { | ||
| if (Array.isArray(indicators)) { | ||
| indicators.forEach(indicator => { | ||
| const el = document.getElementById(indicator); | ||
| if (el) { | ||
| el.classList.remove('offline'); | ||
| } | ||
| }); | ||
| } | ||
| invoke.invokeMethodAsync(onlineStateChangedCallback, true); | ||
| } | ||
| const offlineStateChanged = () => { | ||
| if (Array.isArray(indicators)) { | ||
| indicators.forEach(indicator => { | ||
| const el = document.getElementById(indicator); | ||
| if (el) { | ||
| el.classList.add('offline'); | ||
| } | ||
| }); | ||
| } | ||
| invoke.invokeMethodAsync(onlineStateChangedCallback, false); | ||
| } | ||
| EventHandler.on(window, 'online', onlineStateChanged); | ||
| EventHandler.on(window, 'offline', offlineStateChanged); | ||
|
|
||
| Data.set(id, { | ||
| onlineStateChanged, | ||
| offlineStateChanged | ||
| }); | ||
|
|
||
| updateState(navigator.connection); | ||
| } | ||
|
|
||
| export async function dispose(id) { | ||
| const nt = Data.get(id); | ||
| Data.remove(id); | ||
|
|
||
| if (nt) { | ||
| const { onlineStateChanged, offlineStateChanged } = nt; | ||
| EventHandler.off(window, 'online', onlineStateChanged); | ||
| EventHandler.off(window, 'offline', offlineStateChanged); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.