- Create useWebcamCapture composable for camera/stream management
- Move camera initialization, capture, and upload logic to composable
- Reduce WidgetWebcam.vue size by separating concerns
- Add onCameraStart callback for widget setup after camera initializes
- Move canvas and persistentVideo creation to onMounted
- Store as refs for proper lifecycle management
- Clean up elements in onUnmounted to prevent memory leaks
- Prevents potential conflicts if multiple webcam widgets exist
- Store cleanup function reference for pending video event listeners
- Call cleanup in onUnmounted to prevent memory leaks if component
unmounts while waiting for video metadata
- Add isInitializingCamera flag to prevent concurrent calls to startCameraPreview
- Use finally block to ensure flag is always reset after initialization
- Add stopStreamTracks() call in catch block to release any partially
acquired media tracks when camera access fails
- Prevents privacy and resource leaks from orphaned media streams
- Add refreshVueWidgets call in hideWidgets to sync Vue state on mount
- Update stop camera button with rounded container and square icon
- Use bg-destructive-background design token for stop button
- Clear captured image and restart camera preview when toggling to On Run
- Restore capture button when switching back to Manual mode
- Ensures smooth UX when changing capture modes
- Add refreshVueWidgets function to GraphNodeManager for manually syncing
LiteGraph widget changes with Vue reactive state
- Use refreshVueWidgets after widget modifications (capture, retake, show)
- Fixes retake button not appearing after capturing an image
- Add updateVueWidgetOptions to GraphNodeManager to update widget options
and trigger Vue reactivity
- Implement capture button visibility toggle based on capture_on_queue value
- Default capture mode to 'Manually' (false)
- Use Vue watch to reactively hide/show capture button when mode changes
Mutate widget objects in place instead of creating new instances to fix
a reactivity issue where serializeValue closure captured stale widget
references. Also adds persistent video element for background capture
when UI video is hidden.
Fixes capture_on_queue toggle not being read correctly during serialization.
## Summary
- add workflow to tag merged backport-labeled PRs into cloud/* with
cloud/v<package.json version>
- validate branch/version alignment and skip when tag already exists
- use .nvmrc (Node 24) for setup-node
## Question
- This workflow expects the version bump to already be in the PR when
you merge, as it fails if the tag already exists to keep immutability.
Should we autobump in this case?
## Summary
Catch more user visible (or audible) text that isn't
internationalizable.
## Changes
- **What**: Linter now checks other attributes for raw text.
## Review Focus
What other properties have leaked English text to non-English locales
that aren't in here?
This pull request introduces improvements to widget customization and UI
consistency in the application. The most notable changes are the
addition of support for icon classes in widget options, updates to
button rendering logic, and enhanced visual consistency for button
components.
Widget customization enhancements:
* Added an optional `iconClass` property to the `IWidgetOptions`
interface in `widgets.ts`, allowing widgets to specify custom icons.
UI and rendering updates:
* Updated `WidgetButton.vue` to render the widget label and, if
provided, an icon using the new `iconClass` option. Also standardized
button styling and label usage.
* Improved button styling in `WidgetRecordAudio.vue` for better visual
consistency with other components.
<img width="662" height="534" alt="Screenshot 2025-11-25 at 01 36 45"
src="https://github.com/user-attachments/assets/43bbe226-07fd-48be-9b98-78b08a726b1b"
/>
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6900-Style-button-widgets-2b66d73d3650818ebeadd9315a47ba0f)
by [Unito](https://www.unito.io)
Updated button widget to support icon display and improved styling to match design system.
- Add icon rendering using widget.options.iconClass
- Update styling to use semantic tokens
- Use widget.label for display instead of widget.name
- Apply consistent button styling with design system tokens
Added programmatic capture button that appears when camera is turned on. The button uses node.addWidget() to integrate with LiteGraph canvas.
- Add captureImage() function to draw video frame to canvas and store in node.imgs
- Add capture button widget in showWidgets() using node.addWidget()
- Create canvas element at module level for efficient reuse
- Widget restoration handled by existing restoreWidgets() cleanup
Add video preview functionality with hover overlay that allows users to:
- Click button to start camera and show live preview
- Hover over video to see stop overlay
- Click anywhere on video to hide preview (keeps camera active)
- Click button again to re-show preview without re-requesting permissions
Uses VueUse's useElementHover for automatic hover detection and proper
MediaStream handling with cleanup on unmount.