Skip to content

Conversation

@asynclizard
Copy link
Contributor

@asynclizard asynclizard commented Aug 8, 2025

Add Interactive Resize Handles to Audio Visualizer Components

Reason for Change

The audio visualizer currently has fixed heights for waveform and spectrogram components, which limits user customization. Users need the ability to dynamically resize these components to optimize their workflow - for example, they might want a larger spectrogram for detailed frequency analysis while keeping a compact waveform for overview.

Problem: Users cannot adjust component heights after initialization, forcing them to compromise on visualization quality or work with suboptimal layouts.

Solution: Implement interactive resize handles that allow users to dynamically adjust waveform and spectrogram heights with real-time visual feedback and optimized performance.

Screenshots

Here is a loom video

https://www.loom.com/share/93867e28a8464e759ff18421eb7688d8

Rollout Strategy

Feature Flag: This feature is controlled by the existing FF_AUDIO_SPECTROGRAMS feature flag for spectrogram functionality. The waveform resize is always available when spectrograms are enabled.

Environment: No additional environment variables required. The feature integrates with existing audio annotation workflows.

Testing

Manual Testing

  1. Basic Functionality:

    • Hover over waveform/spectrogram components to verify resize handles appear
    • Drag handles to resize components and verify smooth operation
    • Verify size badge appears during drag showing current dimensions
    • Test minimum (50px) and maximum (500px) height constraints
  2. Performance Testing:

    • Verify spectrogram resize doesn't trigger expensive FFT recalculations
    • Confirm waveform resize doesn't cause performance degradation
    • Test rapid resize operations for smoothness
  3. Cross-browser Testing:

    • Chrome, Firefox, Safari compatibility
    • Touch device support (if applicable)
  4. Edge Cases:

    • Resize during audio playback
    • Resize with multiple audio channels
    • Resize with timeline visible/hidden
    • Mouse leaving component area during drag

Automated Testing

  • Unit tests for ResizeRenderer hit testing and cursor management
  • Integration tests for InteractionManager event routing
  • Visual regression tests for resize handle appearance

Risks

Performance Risks

  • Low Risk: Resize operations are optimized to avoid expensive recalculations
    • Spectrogram: Direct config updates without FFT recalculation
    • Waveform: Direct height updates without full redraw
    • Canvas transfer operations are rate-limited

UX Risks

  • Low Risk: Resize handles may be initially hard to discover
    • Mitigation: Handles are always visible with subtle styling
    • Hover states provide clear visual feedback
    • Size badge provides immediate feedback during resize

Compatibility Risks

  • Low Risk: Touch device support may need refinement
    • Current implementation uses mouse events
    • Touch events can be added in future iteration

Reviewer Notes

Key Implementation Details

  1. Architecture:

    • ResizeRenderer implements both Renderer and Interactive interfaces
    • InteractionManager handles event routing for offscreen canvases
    • Layer composition system maintains performance during resize
  2. Performance Optimizations:

    • Direct config updates avoid expensive operations
    • Global mouse tracking ensures smooth drag operations
    • Rate-limited canvas transfers prevent performance issues
  3. Visual Design:

    • Rounded handles with shadows for modern appearance
    • Dynamic colors with blend modes for visibility
    • Size badge with dark/light mode support

Files to Review

Core Implementation:

  • libs/editor/src/lib/AudioUltra/Visual/Renderer/ResizeRenderer.ts - Main resize logic
  • libs/editor/src/lib/AudioUltra/Interaction/InteractionManager.ts - Event management
  • libs/editor/src/lib/AudioUltra/Interaction/Interactive.ts - Interface definition
  • libs/editor/src/lib/AudioUltra/Visual/Visualizer.ts - Integration and height management

Key Changes:

  • Added waveform-resize and spectrogram-resize layers
  • Implemented handleHeightChange method for dynamic height updates
  • Integrated InteractionManager for offscreen canvas event handling
  • Optimized renderer config updates to avoid expensive operations

Testing Focus Areas

  1. Event Handling: Verify mouse events are properly routed through InteractionManager
  2. Performance: Confirm resize operations don't trigger expensive recalculations
  3. Visual Feedback: Test resize handle visibility and drag feedback
  4. Edge Cases: Test rapid resizing and mouse leaving component area

General Notes

Technical Implementation

The resize functionality uses a layered approach:

  1. Visual Layer: ResizeRenderer draws handles and borders on dedicated layers
  2. Interaction Layer: InteractionManager routes mouse events to interactive elements
  3. Composition Layer: LayerM composes multiple canvases for performance
  4. Update Layer: Direct config updates avoid expensive recalculations

User Experience

  • Discoverability: Handles are always visible with subtle styling
  • Feedback: Size badge shows current dimensions during resize
  • Constraints: Min/max heights prevent unusable sizes
  • Performance: Smooth resize operations with optimized updates

Future Enhancements

  • Touch device support for mobile workflows
  • Keyboard shortcuts for precise height adjustments
  • Preset height configurations for common use cases
  • Animation during resize for smoother visual feedback

This implementation provides a solid foundation for user-customizable audio visualization while maintaining performance and compatibility with existing workflows.

…rogram components

- Add ResizeRenderer with rounded handle design and shadow effects
- Implement hover states with area borders and handle highlighting
- Add size badge that displays current dimensions during drag operations
- Support both light and dark themes with adaptive colors
- Integrate with InteractionManager for robust mouse event handling
- Ensure playhead updates correctly after resize operations

Technical changes:
- Create ResizeRenderer class implementing Renderer and Interactive interfaces
- Add shadow properties to ResizeRendererConfig for enhanced visibility
- Implement global mouse tracking for reliable drag operations
- Add handle border that changes color on hover (gray to white)
- Create area border that only appears on hover with increased width
- Add size badge (100x28px) with theme-adaptive colors
- Update Visualizer to register resize renderers with InteractionManager
- Ensure proper layer composition with resize handles
- Add height change handling for both waveform and spectrogram components

UI/UX improvements:
- Rounded resize handles (60x6px) with subtle shadows
- Hover feedback with area borders and handle highlighting
- Real-time size display during drag operations
- Clean interface with minimal visual clutter
- Professional appearance with modern shadow effects
- Consistent behavior across waveform and spectrogram components

The resize handles provide intuitive height adjustment for audio visualization
components while maintaining a clean, professional interface.
@asynclizard asynclizard requested a review from a team as a code owner August 8, 2025 06:57
@netlify
Copy link

netlify bot commented Aug 8, 2025

Deploy Preview for label-studio-docs-new-theme canceled.

Name Link
🔨 Latest commit f88789d
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-docs-new-theme/deploys/68988abd9b46530008d56697

@netlify
Copy link

netlify bot commented Aug 8, 2025

Deploy Preview for heartex-docs canceled.

Name Link
🔨 Latest commit f88789d
🔍 Latest deploy log https://app.netlify.com/projects/heartex-docs/deploys/68988abd0a6c490008955049

@netlify
Copy link

netlify bot commented Aug 8, 2025

Deploy Preview for label-studio-playground ready!

Name Link
🔨 Latest commit f88789d
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-playground/deploys/68988abd0a6c49000895504f
😎 Deploy Preview https://deploy-preview-8116--label-studio-playground.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions bot added the feat label Aug 8, 2025
@netlify
Copy link

netlify bot commented Aug 8, 2025

Deploy Preview for label-studio-storybook ready!

Name Link
🔨 Latest commit f88789d
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-storybook/deploys/68988abdd740ba0008c86597
😎 Deploy Preview https://deploy-preview-8116--label-studio-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov
Copy link

codecov bot commented Aug 8, 2025

Codecov Report

❌ Patch coverage is 0% with 335 lines in your changes missing coverage. Please review.
✅ Project coverage is 9.42%. Comparing base (42b5f1e) to head (f88789d).

Files with missing lines Patch % Lines
...c/lib/AudioUltra/Visual/Renderer/ResizeRenderer.ts 0.00% 131 Missing ⚠️
...c/lib/AudioUltra/Interaction/InteractionManager.ts 0.00% 106 Missing ⚠️
...ibs/editor/src/lib/AudioUltra/Visual/Visualizer.ts 0.00% 98 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (42b5f1e) and HEAD (f88789d). Click for more details.

HEAD has 3 uploads less than BASE
Flag BASE (42b5f1e) HEAD (f88789d)
pytests 1 0
lsf-integration 1 0
lsf-e2e 1 0
Additional details and impacted files
@@             Coverage Diff             @@
##           develop   #8116       +/-   ##
===========================================
- Coverage    70.41%   9.42%   -60.99%     
===========================================
  Files          719     451      -268     
  Lines        51560   29337    -22223     
  Branches      8734    7811      -923     
===========================================
- Hits         36304    2764    -33540     
- Misses       15253   26570    +11317     
  Partials         3       3               
Flag Coverage Δ
lsf-e2e ?
lsf-integration ?
lsf-unit 9.42% <0.00%> (-0.11%) ⬇️
pytests ?

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:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@niklub
Copy link
Collaborator

niklub commented Aug 8, 2025

cursor review

@cursor
Copy link

cursor bot commented Aug 8, 2025

🚨 Bugbot couldn't run

Something went wrong. Try again by commenting "Cursor review" or "bugbot run", or contact support (requestId: serverGenReqId_30aca6e8-0a10-4619-9666-e674c373345e).

@niklub
Copy link
Collaborator

niklub commented Aug 8, 2025

Cursor review

if (this.isDragging) {
this.isDragging = false;
this.removeGlobalMouseListeners();
console.log(`Finished resizing ${this.componentName} (global)`);
Copy link

Choose a reason for hiding this comment

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

Bug: Renderer Height Mismatch and Debug Logs

The ResizeRenderer has two issues:

  1. Inconsistent Minimum Height: It allows dragging to a minimum height of 20px, but the Visualizer's handleHeightChange method enforces a 50px minimum. This creates a confusing user experience where the component appears unresponsive or snaps back.
  2. Debug Logs: Unnecessary console.log statements are present in the code.
Fix in Cursor Fix in Web

const badgeY = (height - badgeHeight) / 2;

// Detect dark mode and set appropriate colors
const isDarkMode = getCurrentTheme() === "dark";
Copy link

Choose a reason for hiding this comment

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

Bug: Theme Detection Inconsistency

Dark mode detection in ResizeRenderer.ts uses getCurrentTheme() === "dark", which is inconsistent with the capitalized "Dark" used elsewhere (e.g., Visualizer.ts). This prevents dark mode styling from being applied to the size badge.

Fix in Cursor Fix in Web

@niklub
Copy link
Collaborator

niklub commented Aug 10, 2025

/git merge

Workflow run
Successfully merged: create mode 100644 label_studio/tests/data_import/test_streaming_import.py

@niklub niklub self-requested a review August 10, 2025 12:21
@niklub niklub enabled auto-merge (squash) August 10, 2025 12:21
@niklub niklub merged commit 6b85982 into develop Aug 10, 2025
44 of 46 checks passed
@robot-ci-heartex robot-ci-heartex deleted the fb-bros-202 branch August 10, 2025 12:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants