frontend: video-manager: Add block list support for MCM sources#3846
Draft
joaoantoniocardoso wants to merge 8 commits intobluerobotics:masterfrom
Draft
frontend: video-manager: Add block list support for MCM sources#3846joaoantoniocardoso wants to merge 8 commits intobluerobotics:masterfrom
joaoantoniocardoso wants to merge 8 commits intobluerobotics:masterfrom
Conversation
…d fix blob URL cleanup Debounce stopGetThumbnailForDevice by 15 seconds to ride through transient backend restarts without interrupting thumbnail polling. Move blob URL revocation to beforeDestroy to prevent premature cleanup.
…state Move thumbnail sources, busy set, and OneMoreTime task to a window-global singleton that persists across hot module reloads. Add reentrant guard to prevent duplicate fetchThumbnails execution from the double @module decorator. Reduce polling delay to 100ms and preserve last valid thumbnail on 503 errors.
…nail controls Default to paused thumbnail fetching to avoid unnecessary resource usage. Add snapshot (single-fetch) and play/pause (continuous 1s polling) controls. Show a warning that thumbnails use stream resources and may affect video quality. Replace v-avatar with a 16:9 aspect ratio frame for consistent placeholder and image dimensions.
…xtended config booleans and fix form state reset Add disable_lazy, disable_thumbnails, and disable_zenoh checkboxes to the extra configuration panel. Fix stale form state on dialog reopen by re-syncing all fields from the stream prop via a watcher.
…amStatus Add support for the new stream status state field from MCM with three possible values: 'running', 'idle', and 'stopped'. This enables the frontend to distinguish between healthy idle streams and stopped streams.
…s handling for new state field Replace binary running check with state-based logic: - Thumbnails now fetch when state is running or idle (not stopped) - Status indicator shows green for running, blue for idle, red for stopped - Add computed properties for has_healthy_streams, has_active_streams, has_idle_streams, and status_color
…ay for new state field - Replace Running/Not running text with state-based display (Running, Idle, Stopped) - Only show errors when stream state is stopped (not when idle) - Add stream_state_text computed property for status text mapping
Integrate the block list API from mavlink-camera-manager PR bluerobotics#561. Pirate-mode users can toggle source blocking via a switch; all users see the blocked state reflected in the status indicator and tooltip.
Reviewer's GuideImplements video source block-list support and richer thumbnail/stream controls in the video manager, including shared thumbnail polling state, new extended configuration flags, and UI wiring for blocking sources and disabling thumbnails per stream. Sequence diagram for blocking and unblocking a video sourcesequenceDiagram
title Block list sequence for video sources
actor User
participant VideoDeviceComponent
participant VideoStore
participant Backend
User->>VideoDeviceComponent: toggleBlocked()
alt device.blocked is true (user unblocks)
VideoDeviceComponent->>VideoStore: unblockSource(device.source)
VideoStore->>Backend: POST /unblock_source
else device.blocked is false (user blocks)
VideoDeviceComponent->>VideoStore: blockSource(device.source)
VideoStore->>Backend: POST /block_source
end
Backend-->>VideoStore: 200 OK
VideoStore->>VideoStore: fetchDevices()
VideoStore->>Backend: GET /devices
Backend-->>VideoStore: devices list (with blocked flag)
VideoStore->>VideoStore: fetchStreams()
VideoStore->>Backend: GET /streams
Backend-->>VideoStore: streams list
VideoStore-->>VideoDeviceComponent: updated device and streams
VideoDeviceComponent-->>User: updated status text, icon color, block switch
Sequence diagram for shared thumbnail polling and controlssequenceDiagram
title Shared thumbnail polling and controls
actor User
participant VideoDeviceComponent
participant VideoThumbnailComponent
participant VideoStore
participant Backend
Note over VideoStore: Global thumbnailState with task, sources, busy, inProgress
User->>VideoDeviceComponent: open controls / view device
VideoDeviceComponent->>VideoThumbnailComponent: set register=true (if streams healthy and thumbnails enabled)
VideoThumbnailComponent->>VideoStore: startGetThumbnailForDevice(source)
VideoStore->>VideoStore: thumbnailState.sources.add(source)
VideoStore->>VideoStore: start or resume thumbnailState.task
loop every 1s (thumbnailState.task)
VideoStore->>VideoStore: fetchThumbnails()
alt thumbnailState.inProgress
VideoStore-->>VideoStore: return (skip cycle)
else not inProgress
VideoStore->>Backend: GET /thumbnail?source=... for each non busy source
Backend-->>VideoStore: image blob or error
VideoStore->>VideoStore: update thumbnails map with Thumbnail{source,status,roundtripMs}
end
end
VideoStore-->>VideoThumbnailComponent: thumbnails map updated
VideoThumbnailComponent->>VideoThumbnailComponent: updateThumbnail()
VideoThumbnailComponent->>VideoThumbnailComponent: set last_fetch_ms and thumbnail
User->>VideoThumbnailComponent: click single snapshot
VideoThumbnailComponent->>VideoThumbnailComponent: snapshot_in_progress=true
VideoThumbnailComponent->>VideoStore: startGetThumbnailForDevice(source)
VideoStore->>Backend: GET /thumbnail
Backend-->>VideoStore: image blob
VideoStore-->>VideoThumbnailComponent: updated Thumbnail
VideoThumbnailComponent->>VideoThumbnailComponent: snapshot_in_progress=false, snapshot_cooldown=true
VideoThumbnailComponent->>VideoStore: stopGetThumbnailForDevice(source)
User->>VideoThumbnailComponent: toggleContinuous()
alt continuous_mode becomes true
VideoThumbnailComponent->>VideoStore: startGetThumbnailForDevice(source)
else continuous_mode becomes false
VideoThumbnailComponent->>VideoStore: stopGetThumbnailForDevice(source)
end
alt all sources removed from thumbnailState.sources
VideoStore->>VideoStore: thumbnailState.task.stop()
end
Class diagram for updated video manager types and storeclassDiagram
direction LR
class Thumbnail {
+string source
+number status
+number roundtripMs
}
class ThumbnailFetchState {
+OneMoreTime task
+Set~string~ sources
+Set~string~ busy
+boolean inProgress
}
class Device {
+string id
+string name
+string source
+Format[] formats
+Control[] controls
+boolean blocked
}
class ExtendedConfiguration {
+boolean thermal
+boolean disable_lazy
+boolean disable_mavlink
+boolean disable_thumbnails
+boolean disable_zenoh
}
class StreamStatus {
+string id
+boolean running
+StreamStatusState state
+string error
+VideoAndStreamInformation video_and_stream
}
class StreamPrototype {
+string name
+string encode
+FrameDimensions dimensions
+FrameInterval interval
+string[] endpoints
+boolean thermal
+boolean disable_lazy
+boolean disable_mavlink
+boolean disable_thumbnails
+boolean disable_zenoh
}
class VideoStore {
+string API_URL
+Map~string, Thumbnail~ thumbnails
+fetchThumbnails()
+blockSource(source)
+unblockSource(source)
+startGetThumbnailForDevice(source)
+stopGetThumbnailForDevice(source)
+fetchDevices()
+fetchStreams()
}
class VideoThumbnailComponent {
<<component>>
+string source
+string width
+boolean register
+boolean disabled
+Thumbnail thumbnail
+boolean continuous_mode
+boolean snapshot_in_progress
+boolean snapshot_cooldown
+number last_fetch_ms
+updateThumbnail()
+fetchSingleThumbnail()
+toggleContinuous()
}
class VideoDeviceComponent {
<<component>>
+Device device
+boolean show_stream_creation_dialog
+boolean show_controls_dialog
+boolean are_video_streams_available
+boolean has_healthy_streams
+boolean thumbnails_disabled
+boolean is_pirate_mode
+string status_color
+openStreamCreationDialog()
+toggleBlocked()
}
class VideoStreamCreationDialogComponent {
<<component>>
+StreamPrototype stream
+boolean is_thermal
+boolean is_disable_lazy
+boolean is_disable_mavlink
+boolean is_disable_thumbnails
+boolean is_disable_zenoh
+resetFormFromStream()
}
VideoStore "1" --> "*" Thumbnail : manages
VideoStore "1" --> "1" ThumbnailFetchState : uses
StreamStatus "1" --> "1" VideoAndStreamInformation : wraps
VideoAndStreamInformation "1" --> "1" ExtendedConfiguration : has
StreamPrototype "1" --> "1" ExtendedConfiguration : builds_from
VideoDeviceComponent "1" --> "1" Device : displays
VideoDeviceComponent "1" --> "*" StreamStatus : derives_state
VideoDeviceComponent "1" --> "1" VideoStore : uses
VideoDeviceComponent "1" --> "1" VideoThumbnailComponent : owns
VideoThumbnailComponent "1" --> "1" VideoStore : requests_thumbnails
VideoStreamCreationDialogComponent "1" --> "1" Device : configures_for
VideoStreamCreationDialogComponent "1" --> "1" StreamPrototype : edits
VideoStreamCreationDialogComponent "1" --> "1" ExtendedConfiguration : sets_flags
VideoStreamCreationDialogComponent "1" --> "1" VideoStore : creates_streams
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
mastercounterpart of the 1.4 PR: #3837This branch includes the commits from the thumbnail rework and MCM Idle
masterPRs so the UI and types stay consistent and CI can pass.Suggested merge order: merge the thumbnail and Idle PRs to
masterfirst, then rebase this branch ontomasterso this PR collapses to a single commit (the block-list change) before final merge.Related
masterPRs:Block-list commit:
33e42773(equivalent to the rebased 1.4 head).Summary by Sourcery
Add video source block list support and enhanced thumbnail controls to the video manager UI and store.
New Features:
Enhancements: