Skip to content

feat(HikVision): add Login/Logout/StartRealPlay/StopRealPlay callback#787

Merged
ArgoZhang merged 3 commits intomasterfrom
dev-hik
Dec 5, 2025
Merged

feat(HikVision): add Login/Logout/StartRealPlay/StopRealPlay callback#787
ArgoZhang merged 3 commits intomasterfrom
dev-hik

Conversation

@ArgoZhang
Copy link
Copy Markdown
Member

@ArgoZhang ArgoZhang commented Dec 5, 2025

Link issues

fixes #786

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 callback hooks to the HikVision web plugin component for login/logout and real-play start/stop events and simplify the JS real-play implementation.

New Features:

  • Expose optional async callbacks for successful login, logout, start real play, and stop real play in the HikVision web plugin component.

Enhancements:

  • Ensure internal login/logout and real-play state changes trigger the corresponding callbacks and adjust stop-real-play behavior to no longer depend on login state.
  • Remove unnecessary debug logging from the HikVision JavaScript real-play function.

Copilot AI review requested due to automatic review settings December 5, 2025 03:11
@bb-auto bb-auto Bot added the enhancement New feature or request label Dec 5, 2025
@bb-auto bb-auto Bot added this to the v9.2.0 milestone Dec 5, 2025
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Dec 5, 2025

Reviewer's Guide

Adds optional Blazor component callbacks for HikVision login/logout and start/stop real play events, wires them into the existing methods, slightly adjusts the stop-real-play logic, and removes a debug log from the JS plugin.

Sequence diagram for HikVisionWebPlugin login and real-play callbacks

sequenceDiagram
    actor Page
    participant HikVisionWebPlugin as HikVisionWebPlugin
    participant JSRuntime
    participant HikVisionJs as hikvision_js

    Page->>HikVisionWebPlugin: Login(ip, port, userName, password, loginType)
    HikVisionWebPlugin->>JSRuntime: InvokeAsync login(Id, ip, port, userName, password, loginType)
    JSRuntime->>HikVisionJs: login(...)
    HikVisionJs-->>JSRuntime: bool isLogined
    JSRuntime-->>HikVisionWebPlugin: bool isLogined
    alt login success
        HikVisionWebPlugin->>HikVisionWebPlugin: TriggerLogined()
        alt OnLoginedAsync set
            HikVisionWebPlugin-->>Page: await OnLoginedAsync()
        end
    end

    Page->>HikVisionWebPlugin: StartRealPlay(streamType, channelId)
    HikVisionWebPlugin->>HikVisionWebPlugin: check IsLogined and IsRealPlaying
    alt IsLogined and not IsRealPlaying
        HikVisionWebPlugin->>JSRuntime: InvokeAsync startRealPlay(Id, streamType, channelId)
        JSRuntime->>HikVisionJs: startRealPlay(...)
        HikVisionJs-->>JSRuntime: bool isRealPlaying
        JSRuntime-->>HikVisionWebPlugin: bool isRealPlaying
        alt start real play success
            HikVisionWebPlugin->>HikVisionWebPlugin: TriggerStartRealPlay()
            alt OnStartRealPlayedAsync set
                HikVisionWebPlugin-->>Page: await OnStartRealPlayedAsync()
            end
        end
    end

    Page->>HikVisionWebPlugin: StopRealPlay()
    HikVisionWebPlugin->>HikVisionWebPlugin: check IsRealPlaying
    alt IsRealPlaying
        HikVisionWebPlugin->>JSRuntime: InvokeVoidAsync stopRealPlay(Id)
        JSRuntime->>HikVisionJs: stopRealPlay(...)
        HikVisionJs-->>JSRuntime: void
        JSRuntime-->>HikVisionWebPlugin: void
        HikVisionWebPlugin->>HikVisionWebPlugin: IsRealPlaying = false
        HikVisionWebPlugin->>HikVisionWebPlugin: TriggerStopRealPlay()
        alt OnStopRealPlayedAsync set
            HikVisionWebPlugin-->>Page: await OnStopRealPlayedAsync()
        end
    end

    Page->>HikVisionWebPlugin: Logout()
    alt IsLogined
        HikVisionWebPlugin->>JSRuntime: InvokeVoidAsync logout(Id)
        JSRuntime->>HikVisionJs: logout(...)
        HikVisionJs-->>JSRuntime: void
        JSRuntime-->>HikVisionWebPlugin: void
    end
    HikVisionWebPlugin->>HikVisionWebPlugin: IsRealPlaying = false
    HikVisionWebPlugin->>HikVisionWebPlugin: IsLogined = false
    HikVisionWebPlugin->>HikVisionWebPlugin: TriggerLogouted()
    alt OnLogoutedAsync set
        HikVisionWebPlugin-->>Page: await OnLogoutedAsync()
    end
Loading

Class diagram for updated HikVisionWebPlugin callbacks

classDiagram
    class HikVisionWebPlugin {
        +Func~bool, Task~ OnInitedAsync
        +Func~Task~ OnLoginedAsync
        +Func~Task~ OnLogoutedAsync
        +Func~Task~ OnStartRealPlayedAsync
        +Func~Task~ OnStopRealPlayedAsync
        -bool IsLogined
        -bool IsRealPlaying
        +Task~bool~ Login(string ip, int port, string userName, string password, int loginType)
        +Task Logout()
        +Task StartRealPlay(int streamType, int channelId)
        +Task StopRealPlay()
        -Task TriggerLogined()
        -Task TriggerLogouted()
        -Task TriggerStartRealPlay()
        -Task TriggerStopRealPlay()
    }
Loading

File-Level Changes

Change Details Files
Make the initialization callback optional and introduce new Blazor parameters for login/logout and start/stop real play events, with corresponding trigger helpers wired into the existing methods.
  • Change the initialization callback parameter to be nullable to make it optional for consumers.
  • Add four new optional component parameters to expose login, logout, start-real-play, and stop-real-play completion callbacks.
  • Introduce private Trigger* helper methods that check for null and await the corresponding callback if provided.
  • Invoke the login and start-real-play callbacks only when the respective operation reports success.
  • Invoke the logout and stop-real-play callbacks after updating the component’s internal state flags.
src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.cs
Adjust real-play stop logic and clean up a debug log in the JavaScript plugin.
  • Relax the StopRealPlay guard to only check the real-playing flag instead of also requiring login, then always call the JS stop function and update state.
  • Switch from a result-based stop-real-play call to a fire-and-forget void invocation for the JS interop.
  • Remove a console.log debugging statement from the startRealPlay JavaScript implementation.
src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.cs
src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js

Assessment against linked issues

Issue Objective Addressed Explanation
#786 Expose callback parameters on the HikVision component for Login, Logout, StartRealPlay, and StopRealPlay events.
#786 Invoke the corresponding callbacks at the appropriate times: after successful login, after logout, after starting real play, and after stopping real play.

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

@ArgoZhang ArgoZhang merged commit deaf194 into master Dec 5, 2025
6 of 7 checks passed
@ArgoZhang ArgoZhang deleted the dev-hik branch December 5, 2025 03:12
Copy link
Copy Markdown

@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 there - I've reviewed your changes - here's some feedback:

  • In Logout, TriggerLogouted is invoked even when IsLogined is false, which may surprise consumers expecting the callback only on actual logout; consider guarding the callback with the same IsLogined check or documenting the semantics explicitly.
  • The new StopRealPlay implementation no longer considers the success/failure of the underlying JS call and unconditionally clears IsRealPlaying and fires the callback; if the stop operation can fail, you may want to retain a success flag or error handling to keep state and callbacks aligned with the actual player state.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `Logout`, `TriggerLogouted` is invoked even when `IsLogined` is false, which may surprise consumers expecting the callback only on actual logout; consider guarding the callback with the same `IsLogined` check or documenting the semantics explicitly.
- The new `StopRealPlay` implementation no longer considers the success/failure of the underlying JS call and unconditionally clears `IsRealPlaying` and fires the callback; if the stop operation can fail, you may want to retain a success flag or error handling to keep state and callbacks aligned with the actual player state.

## Individual Comments

### Comment 1
<location> `src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.cs:206` </location>
<code_context>
-            {
-                IsRealPlaying = false;
-            }
+            await InvokeVoidAsync("stopRealPlay", Id);
+            IsRealPlaying = false;
+            await TriggerStopRealPlay();
</code_context>

<issue_to_address>
**issue (bug_risk):** Consider preserving stop result handling to avoid inconsistent IsRealPlaying state.

Previously we only set `IsRealPlaying = false` when `stopRealPlay` reported success. Now `InvokeVoidAsync` is used and we always set `IsRealPlaying` to false and trigger `OnStopRealPlayedAsync`, even if the underlying JS `I_Stop` fails. This can leave C# thinking the stream is stopped while the plugin is still playing. If the JS call can fail, please preserve a success/failure result or expose an error path so C# state and callbacks stay aligned with the actual player state.
</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.

Copy link
Copy Markdown

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 callback functionality to the HikVision web plugin component, enabling developers to respond to login, logout, and video playback state changes. The changes include adding four new async callback parameters and removing a debug console.log statement from the JavaScript code.

Key Changes

  • Added four new callback parameters: OnLoginedAsync, OnLogoutedAsync, OnStartRealPlayedAsync, and OnStopRealPlayedAsync
  • Modified state management in Logout() to set IsRealPlaying = false before triggering the logout callback
  • Changed StopRealPlay() to use InvokeVoidAsync instead of checking return values
  • Removed debug console.log statement from JavaScript

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
HikVisionWebPlugin.razor.cs Added four new callback parameters and trigger methods for login, logout, start/stop real play events with corresponding state management updates
hikvision.js Removed debug console.log statement

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

Comment on lines +206 to +208
await InvokeVoidAsync("stopRealPlay", Id);
IsRealPlaying = false;
await TriggerStopRealPlay();
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

The method now calls InvokeVoidAsync instead of checking the return value from the JavaScript function. However, the JavaScript stopRealPlay function still returns a Promise with a boolean result. This discrepancy means potential errors from the JavaScript side will be silently ignored. The callback OnStopRealPlayedAsync is now always triggered even if the JavaScript operation fails. Consider either: (1) reverting to InvokeAsync<bool?> and checking the result, or (2) updating the JavaScript function to properly handle and throw errors.

Suggested change
await InvokeVoidAsync("stopRealPlay", Id);
IsRealPlaying = false;
await TriggerStopRealPlay();
var result = await InvokeAsync<bool?>("stopRealPlay", Id);
if (result ?? false)
{
IsRealPlaying = false;
await TriggerStopRealPlay();
}
// Optionally handle failure here (e.g., log, throw, notify user)

Copilot uses AI. Check for mistakes.
Comment on lines +138 to +143
await TriggerLogined();
}
return IsLogined;
}

private async Task TriggerLogined()
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

The method name TriggerLogined uses incorrect grammar. "Logined" is not a valid past participle. This should be renamed to TriggerLoggedIn to match the suggested parameter name correction.

Suggested change
await TriggerLogined();
}
return IsLogined;
}
private async Task TriggerLogined()
await TriggerLoggedIn();
}
return IsLogined;
}
private async Task TriggerLoggedIn()

Copilot uses AI. Check for mistakes.
Comment on lines +163 to +170
await TriggerLogouted();
}

private async Task TriggerLogouted()
{
if (OnLogoutedAsync != null)
{
await OnLogoutedAsync();
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

The method name TriggerLogouted uses incorrect grammar. "Logouted" is not a valid past participle. This should be renamed to TriggerLoggedOut to match the suggested parameter name correction.

Suggested change
await TriggerLogouted();
}
private async Task TriggerLogouted()
{
if (OnLogoutedAsync != null)
{
await OnLogoutedAsync();
await TriggerLoggedOut();
}
private async Task TriggerLoggedOut()
{
if (OnLoggedOutAsync != null)
{
await OnLoggedOutAsync();

Copilot uses AI. Check for mistakes.
/// 获得/设置 登录成功后回调方法
/// </summary>
[Parameter]
public Func<Task>? OnLoginedAsync { get; set; }
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

The callback name OnLoginedAsync uses incorrect grammar. "Logined" is not a valid past participle in English. Consider renaming to OnLoggedInAsync to be grammatically correct and consistent with standard English usage, or use OnLoginSuccessAsync as an alternative.

Suggested change
public Func<Task>? OnLoginedAsync { get; set; }
public Func<Task>? OnLoggedInAsync { get; set; }

Copilot uses AI. Check for mistakes.
/// 获得/设置 注销成功后回调方法
/// </summary>
[Parameter]
public Func<Task>? OnLogoutedAsync { get; set; }
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

The callback name OnLogoutedAsync uses incorrect grammar. "Logouted" is not a valid past participle in English. Consider renaming to OnLoggedOutAsync to be grammatically correct and consistent with standard English usage, or use OnLogoutSuccessAsync as an alternative.

Suggested change
public Func<Task>? OnLogoutedAsync { get; set; }
public Func<Task>? OnLoggedOutAsync { get; set; }

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 Login/Logout/StartRealPlay/StopRealPlay callback

2 participants