Files
webstudio/apps/builder/app/canvas/collaborative-instance.ts
Oleg Isonen 9fd5ce0552 experimental: Abort controller (#4195)
## Description

I tried how the code will look like with abort controller, if you don't
like it - we can close this without merging


## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2024-10-03 13:55:43 +02:00

55 lines
1.3 KiB
TypeScript

import {
getAllElementsBoundingBox,
getVisibleElementsByInstanceSelector,
} from "~/shared/dom-utils";
import {
$collaborativeInstanceSelector,
$collaborativeInstanceRect,
} from "~/shared/nano-states";
export const updateCollaborativeInstanceRect = ({
signal,
}: {
signal: AbortSignal;
}) => {
let frameHandler: number = -1;
let elements: HTMLElement[] = [];
const frameLoop = () => {
const newRect = getAllElementsBoundingBox(elements);
const prevRect = $collaborativeInstanceRect.get();
if (
newRect.x !== prevRect?.x ||
newRect.y !== prevRect?.y ||
newRect.width !== prevRect?.width ||
newRect.height !== prevRect?.height
) {
$collaborativeInstanceRect.set(newRect);
}
frameHandler = requestAnimationFrame(frameLoop);
};
const unsubscribe = $collaborativeInstanceSelector.subscribe((selector) => {
if (selector === undefined) {
cancelAnimationFrame(frameHandler);
$collaborativeInstanceRect.set(undefined);
elements = [];
return;
}
elements = getVisibleElementsByInstanceSelector(selector);
if (elements.length > 0) {
cancelAnimationFrame(frameHandler);
frameLoop();
}
});
signal.addEventListener("abort", () => {
unsubscribe();
cancelAnimationFrame(frameHandler);
});
};