Add click ripple extension example#425
Conversation
📝 WalkthroughWalkthroughA new cursor-effect extension example "Click Ripple" is added, demonstrating Recordly's extension API with TypeScript implementation of ripple, pulse, and burst click animations. Includes complete project structure with build configuration, type definitions, settings UI, and documentation. ChangesClick Ripple Extension Example
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
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 `@extension-examples/willytop8.click-ripple/src/index.ts`:
- Around line 9-35: registerSettingsPanel(...) and registerCursorEffect(...)
return dispose functions that are currently ignored, causing duplicate
registrations on re-activation; capture their return values (e.g., const
disposeSettings = api.registerSettingsPanel(...); const disposeEffect =
api.registerCursorEffect(...); or push them into a disposers array) and
implement deactivate() to call each stored disposer (and clear the array) so
panels/effects are removed on deactivate; reference the registerSettingsPanel,
registerCursorEffect and deactivate function names when making the change.
🪄 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: c265f039-e710-45f2-8084-2aacfbddc293
⛔ Files ignored due to path filters (2)
extension-examples/willytop8.click-ripple/dist/index.jsis excluded by!**/dist/**extension-examples/willytop8.click-ripple/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (10)
EXTENSIONS.mdextension-examples/willytop8.click-ripple/.gitignoreextension-examples/willytop8.click-ripple/LICENSEextension-examples/willytop8.click-ripple/README.mdextension-examples/willytop8.click-ripple/build.mjsextension-examples/willytop8.click-ripple/package.jsonextension-examples/willytop8.click-ripple/recordly-extension.jsonextension-examples/willytop8.click-ripple/src/index.tsextension-examples/willytop8.click-ripple/src/recordly-types.d.tsextension-examples/willytop8.click-ripple/tsconfig.json
| api.registerSettingsPanel({ | ||
| id: "click-ripple-settings", | ||
| label: "Click Effects", | ||
| icon: "sparkles", | ||
| parentSection: "cursor", | ||
| fields: [ | ||
| { id: "enabled", label: "Enable click effects", type: "toggle", defaultValue: true }, | ||
| { | ||
| id: "style", | ||
| label: "Style", | ||
| type: "select", | ||
| defaultValue: "ripple", | ||
| options: [ | ||
| { label: "Ripple (concentric rings)", value: "ripple" }, | ||
| { label: "Pulse (soft halo)", value: "pulse" }, | ||
| { label: "Burst (radial spokes)", value: "burst" }, | ||
| ], | ||
| }, | ||
| { id: "color", label: "Color", type: "color", defaultValue: "#2563EB" }, | ||
| { id: "size", label: "Size", type: "slider", defaultValue: 1.0, min: 0.5, max: 2.5, step: 0.1 }, | ||
| { id: "durationMs", label: "Duration (ms)", type: "slider", defaultValue: 600, min: 200, max: 1500, step: 50 }, | ||
| { id: "thickness", label: "Line thickness", type: "slider", defaultValue: 2, min: 1, max: 8, step: 1 }, | ||
| { id: "differentiateRightClick", label: "Distinct right-click style", type: "toggle", defaultValue: true }, | ||
| ], | ||
| }); | ||
|
|
||
| api.registerCursorEffect((ctx: CursorEffectContext): boolean => { |
There was a problem hiding this comment.
Persist disposers and clean up on deactivate.
registerSettingsPanel() and registerCursorEffect() return dispose functions, but they’re ignored, while deactivate() is empty. On re-activation this can stack duplicate panel/effect registrations.
♻️ Proposed fix
import type { RecordlyExtensionAPI, CursorEffectContext } from "./recordly-types";
type Style = "ripple" | "pulse" | "burst";
+const disposers: Array<() => void> = [];
const easeOut2 = (t: number) => 1 - Math.pow(1 - t, 2);
const easeOut3 = (t: number) => 1 - Math.pow(1 - t, 3);
export function activate(api: RecordlyExtensionAPI) {
- api.registerSettingsPanel({
+ disposers.push(api.registerSettingsPanel({
id: "click-ripple-settings",
label: "Click Effects",
icon: "sparkles",
parentSection: "cursor",
fields: [
@@
{ id: "thickness", label: "Line thickness", type: "slider", defaultValue: 2, min: 1, max: 8, step: 1 },
{ id: "differentiateRightClick", label: "Distinct right-click style", type: "toggle", defaultValue: true },
],
- });
+ }));
- api.registerCursorEffect((ctx: CursorEffectContext): boolean => {
+ disposers.push(api.registerCursorEffect((ctx: CursorEffectContext): boolean => {
if (!api.getSetting("enabled")) return false;
@@
- return true;
- });
+ return true;
+ }));
}
-export function deactivate() {}
+export function deactivate() {
+ while (disposers.length > 0) {
+ const dispose = disposers.pop();
+ dispose?.();
+ }
+}Also applies to: 77-77
🤖 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 `@extension-examples/willytop8.click-ripple/src/index.ts` around lines 9 - 35,
registerSettingsPanel(...) and registerCursorEffect(...) return dispose
functions that are currently ignored, causing duplicate registrations on
re-activation; capture their return values (e.g., const disposeSettings =
api.registerSettingsPanel(...); const disposeEffect =
api.registerCursorEffect(...); or push them into a disposers array) and
implement deactivate() to call each stored disposer (and clear the array) so
panels/effects are removed on deactivate; reference the registerSettingsPanel,
registerCursorEffect and deactivate function names when making the change.
|
i think this would be better served as an upload to extensions :) |
What
Adds
extension-examples/willytop8.click-ripple, a cursor-effect example with ripple, pulse, and burst click animations.Why
EXTENSIONS.mddocumentsregisterCursorEffect(), but there was no packaged cursor-effect example.Testing
npm run buildnpx tsc --noEmitSummary by CodeRabbit
New Features
Documentation