Skip to content

feat(HikVision): add ChangeWindowNum function#7436

Merged
ArgoZhang merged 3 commits intomainfrom
doc-hik
Dec 27, 2025
Merged

feat(HikVision): add ChangeWindowNum function#7436
ArgoZhang merged 3 commits intomainfrom
doc-hik

Conversation

@ArgoZhang
Copy link
Copy Markdown
Member

@ArgoZhang ArgoZhang commented Dec 27, 2025

Link issues

fixes #7435

Summary By Copilot

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • Merge the latest code from the main branch

Summary by Sourcery

Add support for changing HikVision preview window layouts and adjust the sample UI accordingly.

New Features:

  • Introduce a window layout selector in the HikVision sample to change the number and arrangement of preview windows via ChangeWindowNum.

Enhancements:

  • Disable login, playback, sound, and recording controls when the HikVision component is in multiple-window mode to reflect unsupported operations.
  • Refine the HikVision control layout using a dedicated CSS class for improved button grid styling and text wrapping.

Copilot AI review requested due to automatic review settings December 27, 2025 02:44
@bb-auto bb-auto Bot added the enhancement New feature or request label Dec 27, 2025
@bb-auto bb-auto Bot added this to the v10.1.0 milestone Dec 27, 2025
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Dec 27, 2025

Reviewer's Guide

Adds multi-window layout support to the HikVision sample by introducing a window type selector, wiring it to a new ChangeWindowNum API, and refactoring the control layout styling into a dedicated CSS class.

Sequence diagram for changing HikVision window layout

sequenceDiagram
    actor User
    participant HikVisions as HikVisionsComponent
    participant HikVision as HikVisionClient

    User->>HikVisions: Select window type from dropdown
    HikVisions->>HikVisions: OnWndTypeChanged(item)
    HikVisions->>HikVisions: _iWndType = item.Value
    HikVisions->>HikVision: ChangeWindowNum(_iWndType)
    HikVision-->>HikVisions: Update IsMultipleWindowType and layout
    HikVisions->>HikVisions: StateHasChanged()
    HikVisions-->>User: Re-render with updated layout and disabled controls
Loading

Updated class diagram for HikVisions multi-window support

classDiagram
    class HikVisions {
        -string _ip
        -int _port
        -string _userName
        -string _password
        -bool _inited
        -List~SelectedItem~ _analogChannels
        -int _channelId
        -List~SelectedItem~ _iWndTypes
        -string _iWndType
        -bool _loginStatus
        -bool _logoutStatus
        -bool _startRealPlayStatus
        -bool _stopRealPlayStatus
        -bool _openSoundStatus
        -bool _closeSoundStatus
        -bool _startRecordStatus
        -bool _stopRecordStatus
        +Task OnLogin()
        +Task OnLogout()
        +Task OnStartRealPlay()
        +Task OnStopRealPlay()
        +Task OnOpenSound()
        +Task OnCloseSound()
        +Task OnStartRecord()
        +Task OnStopRecord()
        +Task OnWndTypeChanged(SelectedItem item)
    }

    class HikVisionClient {
        +bool IsLogin
        +bool IsRealPlaying
        +bool IsOpenSound
        +bool IsStartRecord
        +bool IsMultipleWindowType
        +Task Login(string ip, int port, string userName, string password, HikVisionLoginType loginType)
        +Task Logout()
        +Task StartRealPlay(int channelId)
        +Task StopRealPlay()
        +Task OpenSound()
        +Task CloseSound()
        +Task StartRecord()
        +Task StopRecord()
        +Task ChangeWindowNum(string iWndType)
    }

    class SelectedItem {
        +string Value
        +string Text
        +SelectedItem(string value, string text)
    }

    HikVisions --> HikVisionClient : uses
    HikVisions "1" o-- "*" SelectedItem : defines_iWndTypes_and_channels
    HikVisions ..> SelectedItem : OnWndTypeChanged_parameter
    HikVisionClient ..> HikVisionLoginType : uses_login_type
Loading

File-Level Changes

Change Details Files
Gate existing HikVision control buttons when multiple-window mode is active and track selected window layout type.
  • Updated computed status properties to return disabled-state values when multiple-window mode is detected via IsMultipleWindowType.
  • Introduced a list of selectable window layout options and backing field to hold the currently selected layout type.
  • Implemented an event handler that updates the selected layout type and calls the ChangeWindowNum method on the HikVision component.
src/BootstrapBlazor.Server/Components/Samples/HikVisions.razor.cs
Integrate a UI control for selecting the HikVision window layout and adjust button layout styling.
  • Replaced the inline grid style on the control container with a semantic hik-controls CSS class.
  • Added a dropdown to the control toolbar bound to the window type options and the OnWndTypeChanged handler to allow users to change the split-screen layout.
src/BootstrapBlazor.Server/Components/Samples/HikVisions.razor
src/BootstrapBlazor.Server/Components/Samples/HikVisions.razor.css

Assessment against linked issues

Issue Objective Addressed Explanation
#7435 Add support in the HikVision sample/component to change the window layout/number by calling the HikVision ChangeWindowNum function (including wiring it into the UI).

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The new _loginStatus/_logoutStatus/playback/sound/recording status expressions invert the intended behavior in multi-window mode: IsMultipleWindowType ? false : ... leaves the controls enabled when multiple windows are active, whereas to disable them you likely want IsMultipleWindowType || <existing-condition> (or IsMultipleWindowType ? true : <existing-condition> depending on how IsDisabled is interpreted).
  • The repeated IsMultipleWindowType ? false : ... ternary pattern on the status properties could be simplified and made clearer by extracting a helper (e.g., IsControlDisabled(baseCondition)) or by composing the conditions directly (e.g., _hikVision.IsMultipleWindowType || <existing-condition>), which would reduce duplication and make the intent more obvious.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `_loginStatus`/`_logoutStatus`/playback/sound/recording status expressions invert the intended behavior in multi-window mode: `IsMultipleWindowType ? false : ...` leaves the controls enabled when multiple windows are active, whereas to disable them you likely want `IsMultipleWindowType || <existing-condition>` (or `IsMultipleWindowType ? true : <existing-condition>` depending on how `IsDisabled` is interpreted).
- The repeated `IsMultipleWindowType ? false : ...` ternary pattern on the status properties could be simplified and made clearer by extracting a helper (e.g., `IsControlDisabled(baseCondition)`) or by composing the conditions directly (e.g., `_hikVision.IsMultipleWindowType || <existing-condition>`), which would reduce duplication and make the intent more obvious.

## Individual Comments

### Comment 1
<location> `src/BootstrapBlazor.Server/Components/Samples/HikVisions.razor.cs:29-36` </location>
<code_context>
+    private bool _loginStatus => _hikVision.IsMultipleWindowType ? false : _hikVision.IsLogin;
</code_context>

<issue_to_address>
**issue (bug_risk):** Re-check the `IsMultipleWindowType` logic for these status flags, as it may invert the disabled state for all actions.

These flags are bound to `IsDisabled`, so `true` means the button is disabled. With the new ternary, when `IsMultipleWindowType` is `true`, `_loginStatus` becomes `false`, which will enable actions even when login / playback / recording should be blocked. If multiple-window mode is meant to *prevent* these actions, this logic likely needs to be inverted or folded into the underlying conditions (e.g. `private bool _loginStatus => _hikVision.IsMultipleWindowType || _hikVision.IsLogin;`).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 27, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (bd6b13b) to head (283d62c).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #7436   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          749       749           
  Lines        32845     32845           
  Branches      4563      4563           
=========================================
  Hits         32845     32845           
Flag Coverage Δ
BB 100.00% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ArgoZhang ArgoZhang merged commit 814a8c4 into main Dec 27, 2025
9 of 10 checks passed
@ArgoZhang ArgoZhang deleted the doc-hik branch December 27, 2025 02:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds window layout switching functionality to the HikVision component, allowing users to change the video display grid (1x1, 2x2, 3x3, 4x4, 1x2, 2x1) through a new dropdown control. The implementation includes UI updates, backend logic changes to handle multiple window types, and upgrades the HikVision package dependency.

Key changes:

  • Adds ChangeWindowNum function integration with a dropdown selector for different window grid layouts
  • Updates button disable logic to account for multiple window mode
  • Upgrades BootstrapBlazor.HikVision package from version 10.0.9 to 10.0.10

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
src/BootstrapBlazor.Server/Components/Samples/HikVisions.razor.css Adds new CSS styles for the control button grid layout
src/BootstrapBlazor.Server/Components/Samples/HikVisions.razor.cs Implements window type selection logic, adds status checks for multiple window mode, and includes the OnWndTypeChanged handler
src/BootstrapBlazor.Server/Components/Samples/HikVisions.razor Integrates the window layout dropdown into the UI controls section
src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj Updates HikVision package reference to version 10.0.10

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +48 to +56
private readonly List<SelectedItem> _iWndTypes =
[
new SelectedItem("1", "1*1"),
new SelectedItem("2", "2*2"),
new SelectedItem("3", "3*3"),
new SelectedItem("4", "4*4"),
new SelectedItem("1*2", "1*2"),
new SelectedItem("2*1", "2*1")
];
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming of this collection is inconsistent with C# naming conventions and lacks clarity. The abbreviation _iWndTypes (presumably "iWindow Types") is unclear. Consider renaming to _windowLayoutTypes or _windowGridTypes to better describe that these represent different grid layout options (1x1, 2x2, etc.) for the video display window.

Copilot uses AI. Check for mistakes.
<Button OnClick="OnStopRecord" IsDisabled="_stopRecordStatus">
<span>停止录像</span>
</Button>
<Dropdown Value="@_iWndType" IsDisabled="false" Items="_iWndTypes"
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IsDisabled="false" attribute is redundant as false is the default value for the IsDisabled property. This explicit assignment should be removed for cleaner code.

Suggested change
<Dropdown Value="@_iWndType" IsDisabled="false" Items="_iWndTypes"
<Dropdown Value="@_iWndType" Items="_iWndTypes"

Copilot uses AI. Check for mistakes.
Comment on lines +29 to 37
private bool _loginStatus => _hikVision.IsMultipleWindowType ? false : _hikVision.IsLogin;
private bool _logoutStatus => _hikVision.IsMultipleWindowType ? false : !_hikVision.IsLogin;
private bool _startRealPlayStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: false };
private bool _stopRealPlayStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: true };
private bool _openSoundStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: true, IsOpenSound: false };
private bool _closeSoundStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: true, IsOpenSound: true };
private bool _startRecordStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: true, IsStartRecord: false };
private bool _stopRecordStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: true, IsStartRecord: true };

Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These boolean status properties have confusing logic due to double negatives. The pattern _hikVision is not { IsLogin: true, IsRealPlaying: false } is negating a property check, which when combined with the IsMultipleWindowType check makes it difficult to understand when buttons should be disabled. Consider using positive logic patterns and adding comments to clarify the intended button state (enabled/disabled) for each scenario.

Suggested change
private bool _loginStatus => _hikVision.IsMultipleWindowType ? false : _hikVision.IsLogin;
private bool _logoutStatus => _hikVision.IsMultipleWindowType ? false : !_hikVision.IsLogin;
private bool _startRealPlayStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: false };
private bool _stopRealPlayStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: true };
private bool _openSoundStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: true, IsOpenSound: false };
private bool _closeSoundStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: true, IsOpenSound: true };
private bool _startRecordStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: true, IsStartRecord: false };
private bool _stopRecordStatus => _hikVision.IsMultipleWindowType ? false : _hikVision is not { IsLogin: true, IsRealPlaying: true, IsStartRecord: true };
// true when in single-window mode and the plugin reports a logged-in state
private bool _loginStatus => !_hikVision.IsMultipleWindowType && _hikVision.IsLogin;
// true when in single-window mode and the plugin reports a logged-out state
private bool _logoutStatus => !_hikVision.IsMultipleWindowType && !_hikVision.IsLogin;
// true when in single-window mode and NOT (logged in and currently not playing)
private bool _startRealPlayStatus =>
!_hikVision.IsMultipleWindowType &&
!(_hikVision.IsLogin && !_hikVision.IsRealPlaying);
// true when in single-window mode and NOT (logged in and currently playing)
private bool _stopRealPlayStatus =>
!_hikVision.IsMultipleWindowType &&
!(_hikVision.IsLogin && _hikVision.IsRealPlaying);
// true when in single-window mode and NOT (logged in, playing, and sound is closed)
private bool _openSoundStatus =>
!_hikVision.IsMultipleWindowType &&
!(_hikVision.IsLogin && _hikVision.IsRealPlaying && !_hikVision.IsOpenSound);
// true when in single-window mode and NOT (logged in, playing, and sound is open)
private bool _closeSoundStatus =>
!_hikVision.IsMultipleWindowType &&
!(_hikVision.IsLogin && _hikVision.IsRealPlaying && _hikVision.IsOpenSound);
// true when in single-window mode and NOT (logged in, playing, and recording is stopped)
private bool _startRecordStatus =>
!_hikVision.IsMultipleWindowType &&
!(_hikVision.IsLogin && _hikVision.IsRealPlaying && !_hikVision.IsStartRecord);
// true when in single-window mode and NOT (logged in, playing, and recording is started)
private bool _stopRecordStatus =>
!_hikVision.IsMultipleWindowType &&
!(_hikVision.IsLogin && _hikVision.IsRealPlaying && _hikVision.IsStartRecord);

Copilot uses AI. Check for mistakes.
}

private async Task OnWndTypeChanged(SelectedItem item)
{
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method lacks null safety checking. If item or item.Value is null, this will cause a runtime exception. Consider adding null checks or using null-coalescing operators to handle edge cases gracefully.

Suggested change
{
{
if (item is null || string.IsNullOrEmpty(item.Value))
{
return;
}

Copilot uses AI. Check for mistakes.
Comment on lines +8 to +10
.hik-controls ::deep .btn {
white-space: nowrap;
}
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is inconsistent indentation in this CSS file. The .hik-controls selector starts with indentation, but the nested selector .hik-controls ::deep .btn has even more indentation. CSS at the root level should not have leading indentation for consistency with standard CSS formatting conventions.

Suggested change
.hik-controls ::deep .btn {
white-space: nowrap;
}
.hik-controls ::deep .btn {
white-space: nowrap;
}

Copilot uses AI. Check for mistakes.
new SelectedItem("1*2", "1*2"),
new SelectedItem("2*1", "2*1")
];
private string _iWndType = "1";
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming of this variable is inconsistent with the existing naming convention in the file. Other similar variables use camelCase with descriptive names like _streamType, _channelId, but this uses an abbreviation _iWndType. Consider renaming to _windowType or _windowLayoutType for better clarity and consistency with the codebase naming patterns.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(HikVision): add ChangeWindowNum function

2 participants