Skip to content

add: drawIcons for extensions, SettingsPanel for extension fixed.#459

Open
ExtraBinoss wants to merge 16 commits intowebadderallorg:mainfrom
ExtraBinoss:feat/settings-panel-auto-props-extension-ui
Open

add: drawIcons for extensions, SettingsPanel for extension fixed.#459
ExtraBinoss wants to merge 16 commits intowebadderallorg:mainfrom
ExtraBinoss:feat/settings-panel-auto-props-extension-ui

Conversation

@ExtraBinoss
Copy link
Copy Markdown
Collaborator

@ExtraBinoss ExtraBinoss commented May 8, 2026

Summary

This PR introduces two main changes :

  • Using Icons inside JS code with drawIcons in the extension
  • Added the drawIcon function in the EXTENSION.md
  • Settings Panel for extensions now uses SliderControl for a consistent UI between normal options.
  • Parameters changed inside an extension will be reflected instantly on the canvas.

Type of Change

  • New Feature / Enhancements

Related Issue(s)

I needed icons in my extension, so I added it. It's very useful if your extension needs to use Phospor react icons.

I also found the "range" HTML element very lacking. The [SliderControl] is much more nicer. Extension UI feels less lacking compared to the real UI.

Screenshots / Video

image image

Code is from my extension for creating frames. We can create Terminal/Browser or Minimal framing.
It will be available after this PR is merged, since I need the icons to make it work. and we need to see if it should be a builtin. .

Testing Guide

Add an extension with a slider parameter, should look like the screenshots

Checklist

  • I have performed a self-review of my code.
  • I have added any necessary screenshots or videos.
  • I have linked related issue(s) and updated the changelog if applicable.

Thank you for contributing!

Summary by CodeRabbit

  • New Features

    • Extensions can draw Phosphor icons directly onto the project canvas (position, size, color, weight).
  • Improvements

    • Numeric slider controls in settings now show consistent formatting and behavior.
    • Frame handling reloads/repositions reliably on extension updates; frame assets teardown more robustly.
    • Settings persistence is more reliable and flushed on unload/deactivation.
    • Background/wallpaper and frame reset behavior expanded.
  • Documentation

    • Added docs and usage example for the icon-drawing API.

…phor/react

fix: SliderControl is now the default for Settings Panel of the extensions
fix: resetting of values on shadows/corner radius
Copilot AI review requested due to automatic review settings May 8, 2026 21:46
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds drawIcon extension API and Path2D resolver/caching, introduces a debounced in-memory full settings store, and updates SettingsPanel and VideoPlayback to respond to extension-host changes; docs include a Drawing Icons example.

Changes

Extension Icon API and Settings System

Layer / File(s) Summary
Extension API Types
src/lib/extensions/types.ts
RecordlyExtensionAPI gains drawIcon(ctx, name, x, y, size, color, weight?).
Icon Path Extraction
src/lib/extensions/iconDraw.ts
New resolver renders Phosphor components by weight, extracts SVG d strings recursively, composes a Path2D, and caches by name:weight.
Extension Host: caching & persistence
src/lib/extensions/extensionHost.ts
Adds fullSettingsStore in-memory cache, persistTimeout debounce, getFullSettingsStore(), uses cached store for load/persist, registers beforeunload flush, and adds iconPathCache + import of resolveIconPath.
drawIcon binding (extensionHost)
src/lib/extensions/extensionHost.ts
drawIcon() resolves/caches Path2D via resolveIconPath and draws it on the provided canvas context with translation, scaling (256-grid), centering, and fillStyle.
SettingsPanel UI
src/components/video-editor/SettingsPanel.tsx
Extension numeric sliders use SliderControl (min/max/step, formatting/parsing); customImages prepend logic refactored; wallpaper reset prefers valid initial value then fallbacks; frame reset expanded to include shadowIntensity, borderRadius, padding, and validated frame.
Frame Sprite Lifecycle
src/components/video-editor/VideoPlayback.tsx
Adds signatures and frameUpdateCounter subscribed to extensionHost.onChange; includes it in the effect deps; strengthens sprite teardown to remove and destroy texture/baseTexture before destroying sprite.
Documentation
EXTENSIONS.md
Adds api.drawIcon(...) to API list and a "Drawing Icons" section with usage example and parameter docs.

Sequence Diagram(s)

sequenceDiagram
  participant Extension
  participant extensionHost
  participant iconPathCache
  participant Canvas
  Extension->>extensionHost: drawIcon(ctx,name,x,y,size,color,weight)
  extensionHost->>iconPathCache: lookup resolveIconPath(name,weight)
  alt cached
    iconPathCache-->>extensionHost: Path2D
  else not cached
    extensionHost->>iconPathCache: generate & cache Path2D
  end
  extensionHost->>Canvas: translate/scale + fill Path2D
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰✨ I nibble paths and stitch them fine,

I scale and cache each phosphor line,
Settings hum, sprites bow and part,
On canvas fields the small icons start,
A hop, a draw — the editor's heart.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title partially covers the changeset but is incomplete and somewhat unclear; it mentions drawIcons and SettingsPanel fixes but misses key aspects like frame settings updates and instant canvas reflection. Consider a clearer title like 'Add drawIcon API for extensions and improve SettingsPanel with SliderControl' to better reflect all major changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description covers main features, type of change, and includes helpful screenshots/testing guide, though it lacks detailed related issue links and some checklist items remain unchecked.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

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 extends the extensions API and UI to support drawing Phosphor icons onto canvases and to improve extension settings sliders, while attempting to make extension-driven parameter changes reflect immediately in the preview.

Changes:

  • Added api.drawIcon(...) to the extension API and documented it in EXTENSIONS.md.
  • Switched extension “slider” fields in the Settings panel to use the shared SliderControl.
  • Added preview invalidation wiring so extension host changes can trigger frame redraws, and optimized extension settings persistence with an in-memory cache + debounced localStorage writes.

Reviewed changes

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

Show a summary per file
File Description
src/lib/extensions/types.ts Extends the public extension API typing to include drawIcon.
src/lib/extensions/extensionHost.ts Implements drawIcon, adds settings-store caching + debounced persistence, and expands host change notifications.
src/components/video-editor/VideoPlayback.tsx Subscribes to extensionHost changes and forces frame sprite regeneration to reflect updates.
src/components/video-editor/SettingsPanel.tsx Replaces <input type="range"> with SliderControl for extension slider fields; adjusts wallpaper/custom image effects and reset behavior.
EXTENSIONS.md Documents drawIcon usage for extension authors.

Comment thread src/components/video-editor/VideoPlayback.tsx
Comment thread src/lib/extensions/extensionHost.ts
Comment thread src/lib/extensions/extensionHost.ts
Comment thread src/lib/extensions/extensionHost.ts
Comment thread src/lib/extensions/extensionHost.ts Outdated
Comment thread src/lib/extensions/extensionHost.ts Outdated
Comment thread src/components/video-editor/SettingsPanel.tsx Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/lib/extensions/extensionHost.ts (1)

1006-1024: 🏗️ Heavy lift

Avoid coupling drawIcon() to React component internals.

This extraction path walks Icon.render, element.props.weights, and nested children, but Phosphor documents rendering icon components and defining custom icons via IconBase/weights—not reading those internals back out. That makes the helper fragile across React or Phosphor upgrades. Prefer a stable source such as @phosphor-icons/core or a generated path map for canvas rendering. (github.com)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/extensions/extensionHost.ts` around lines 1006 - 1024, The drawIcon()
helper currently reaches into React/Phosphor internals (Icon.render,
element.props.weights, children) to extract SVG path data which is fragile;
instead provide a stable path source: add or import a dedicated path map (e.g.,
a generated record mapping icon name+weight to SVG path strings) and use that
map in drawIcon() to create Path2D and populate host.iconPathCache (using the
existing cacheKey/Path2D logic); update any callers that rely on Icon.render to
use the map, and remove the internal-inspection code block (Icon.render,
element, weights, children, pathElement) so drawIcon() only reads from the
stable path map or a `@phosphor-icons/core` export.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/video-editor/SettingsPanel.tsx`:
- Around line 1461-1467: initialEditorPreferences.wallpaper is used
unconditionally as the reset target in onWallpaperChange which can keep a stale
path (e.g., removed extension or deleted custom asset); before preferring
initialEditorPreferences.wallpaper, validate it exists in the current sets by
checking that the value is included in builtInWallpaperPaths,
extensionWallpaperPaths, or matches any BUILT_IN_WALLPAPERS[].publicPath (or the
current custom assets collection), and only pass it to onWallpaperChange if
found; otherwise fall back to builtInWallpaperPaths[0] →
extensionWallpaperPaths[0] → BUILT_IN_WALLPAPERS[0]?.publicPath → "".

In `@src/lib/extensions/extensionHost.ts`:
- Line 475: The call to notifyListeners() in setVideoLayout() and
setShadowConfig() is wrong because onChange()/notifyListeners() is meant only
for extension-registry changes (used by SettingsPanel) and is causing unrelated
refreshes and feedback loops (VideoPlayback/frameUpdateCounter). Remove the
notifyListeners() calls from setVideoLayout() and setShadowConfig(), and instead
add a dedicated layout/project-state signal (e.g., new methods
registerLayoutListener/onLayoutChange and notifyLayoutListeners or
emitProjectStateChange) that layoutVideoContent() and VideoPlayback can
subscribe to; ensure SettingsPanel continues to use onChange()/notifyListeners()
for registry updates only.
- Around line 995-996: The drawIcon() lookup currently does a direct
PhosphorIcons[name] lookup and silently fails; update drawIcon() to reuse the
normalization strategy from ExtensionIcon.tsx/resolvePhosphorIcon(): attempt the
provided name first, then try name + "Icon", and also consult ICON_NAME_ALIASES
if present, so names like "CaretLeft" and "ArrowClockwise" resolve to their
exported symbols; remove the duplicated lookup logic (the pair at the current
lookup and the later block around lines 1000-1004) and consolidate into a single
normalized resolution path that returns the resolved Icon or null if none found.

---

Nitpick comments:
In `@src/lib/extensions/extensionHost.ts`:
- Around line 1006-1024: The drawIcon() helper currently reaches into
React/Phosphor internals (Icon.render, element.props.weights, children) to
extract SVG path data which is fragile; instead provide a stable path source:
add or import a dedicated path map (e.g., a generated record mapping icon
name+weight to SVG path strings) and use that map in drawIcon() to create Path2D
and populate host.iconPathCache (using the existing cacheKey/Path2D logic);
update any callers that rely on Icon.render to use the map, and remove the
internal-inspection code block (Icon.render, element, weights, children,
pathElement) so drawIcon() only reads from the stable path map or a
`@phosphor-icons/core` export.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e58abad-0e09-42b4-bc25-933086b39063

📥 Commits

Reviewing files that changed from the base of the PR and between 4813032 and c6dbced.

📒 Files selected for processing (5)
  • EXTENSIONS.md
  • src/components/video-editor/SettingsPanel.tsx
  • src/components/video-editor/VideoPlayback.tsx
  • src/lib/extensions/extensionHost.ts
  • src/lib/extensions/types.ts

Comment thread src/components/video-editor/SettingsPanel.tsx
Comment thread src/lib/extensions/extensionHost.ts Outdated
Comment thread src/lib/extensions/extensionHost.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/video-editor/SettingsPanel.tsx`:
- Around line 1555-1559: When resetting preferences in SettingsPanel, validate
initialEditorPreferences.frame against availableFrames before calling
onFrameChange: if availableFrames contains that frame id call
onFrameChange?.(initialEditorPreferences.frame) as before, otherwise call
onFrameChange?.(undefined) (or the component's “empty” frame value) to clear the
selection; reference the initialEditorPreferences.frame, availableFrames array,
and onFrameChange handler when making this change.
- Around line 267-280: The SliderControl currently forces one decimal place via
formatValue={(v) => v.toFixed(1)}, which misrepresents sliders with different
step precision; compute the number of decimal places from field.step (falling
back to 0 or 1 as appropriate) by counting decimals in the step (e.g., convert
step to string or repeatedly multiply by 10 until integer) and use that
precision in formatValue (e.g., v.toFixed(precision)); ensure the same precision
logic is used for displaying defaultValue/current value and leave parseInput as
parseFloat so typed input round-trips correctly; update the SliderControl usage
in SettingsPanel (the component around SliderControl, field.step,
field.defaultValue, and the onChange/formatValue props) to use this derived
precision.

In `@src/lib/extensions/extensionHost.ts`:
- Around line 612-619: Debounced writes can be lost on quick exit; ensure any
pending persist is flushed during teardown by checking this.persistTimeout in
the extension host's shutdown path (e.g., deactivate/dispose/unload handler) and
if set, clearTimeout(this.persistTimeout), call
this.writePersistedSettingsStore(store) immediately with the current store
state, and set this.persistTimeout = null so the pending change is persisted
before exit; update any relevant teardown methods where lifecycle ends to
perform this flush using the existing persistTimeout and
writePersistedSettingsStore symbols.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b85460ac-70c2-449e-8743-05082b2dbd15

📥 Commits

Reviewing files that changed from the base of the PR and between c6dbced and 09b6651.

📒 Files selected for processing (4)
  • src/components/video-editor/SettingsPanel.tsx
  • src/components/video-editor/VideoPlayback.tsx
  • src/lib/extensions/extensionHost.ts
  • src/lib/extensions/iconDraw.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/video-editor/VideoPlayback.tsx

Comment thread src/components/video-editor/SettingsPanel.tsx
Comment thread src/components/video-editor/SettingsPanel.tsx Outdated
Comment thread src/lib/extensions/extensionHost.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/video-editor/SettingsPanel.tsx`:
- Around line 265-278: The SliderControl fallback values were changed to min=0,
max=1, step=0.01 which breaks extensions expecting native range defaults; in
SettingsPanel (the code around the SliderControl render where field.step,
field.min, field.max are read) restore the original native HTML input defaults
when the plugin/field doesn't provide them by using min = field.min ?? 0, max =
field.max ?? 100, and step = field.step ?? 1 (or otherwise coerce/compute
precision from step when provided) so omitted values get 0–100 integer semantics
instead of 0–1 fractional semantics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3d617057-bb85-4c9c-86db-6f26b20e5f6c

📥 Commits

Reviewing files that changed from the base of the PR and between 774fd6a and 4aeb2b6.

📒 Files selected for processing (2)
  • src/components/video-editor/SettingsPanel.tsx
  • src/lib/extensions/extensionHost.ts

Comment thread src/components/video-editor/SettingsPanel.tsx
@webadderall
Copy link
Copy Markdown
Collaborator

Extension icons for their own settings sections will not render correctly in the sidebar

"In VideoEditor.tsx (line 1666), the derived extensionSectionButtons state keeps only id, label, and icon, so by the time the button renders at VideoEditor.tsx (line 5985), ExtensionIcon is called without an extensionPath. But ExtensionIcon.tsx (line 72) requires extensionPath to resolve relative image paths; otherwise it returns the raw relative string at ExtensionIcon.tsx (line 90), which won’t resolve to the extension directory. Any extension using icon: "icons/panel.svg" will therefore break in this new sidebar path."

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@ExtraBinoss
Copy link
Copy Markdown
Collaborator Author

Extension icons for their own settings sections will not render correctly in the sidebar

"In VideoEditor.tsx (line 1666), the derived extensionSectionButtons state keeps only id, label, and icon, so by the time the button renders at VideoEditor.tsx (line 5985), ExtensionIcon is called without an extensionPath. But ExtensionIcon.tsx (line 72) requires extensionPath to resolve relative image paths; otherwise it returns the raw relative string at ExtensionIcon.tsx (line 90), which won’t resolve to the extension directory. Any extension using icon: "icons/panel.svg" will therefore break in this new sidebar path."

This is valid. and is fixed in 730d5d0 sorry for the inconvenience

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

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

Comment thread src/components/video-editor/VideoPlayback.tsx
Comment thread src/components/video-editor/VideoPlayback.tsx
Comment thread src/components/video-editor/SettingsPanel.tsx
Comment thread src/lib/extensions/iconDraw.ts
@ExtraBinoss
Copy link
Copy Markdown
Collaborator Author

Waiitng for copilot review again. but most of the issues are fixed

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

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

Comment thread src/lib/extensions/iconDraw.ts Outdated
Comment thread src/lib/extensions/iconDraw.ts Outdated
Comment thread src/lib/extensions/extensionHost.ts
Comment thread src/lib/extensions/extensionHost.ts
Comment thread src/components/video-editor/SettingsPanel.tsx Outdated
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.

4 participants