feat: poll to detect if position of excalidraw was updated and allow consumer to disable it
This commit is contained in:
parent
c19c8ecd27
commit
bfc8415554
@ -46,6 +46,7 @@ import {
|
|||||||
CURSOR_TYPE,
|
CURSOR_TYPE,
|
||||||
DEFAULT_UI_OPTIONS,
|
DEFAULT_UI_OPTIONS,
|
||||||
DEFAULT_VERTICAL_ALIGN,
|
DEFAULT_VERTICAL_ALIGN,
|
||||||
|
DETECT_POSITION_CHANGE_INTERVAL,
|
||||||
DRAGGING_THRESHOLD,
|
DRAGGING_THRESHOLD,
|
||||||
ELEMENT_SHIFT_TRANSLATE_AMOUNT,
|
ELEMENT_SHIFT_TRANSLATE_AMOUNT,
|
||||||
ELEMENT_TRANSLATE_AMOUNT,
|
ELEMENT_TRANSLATE_AMOUNT,
|
||||||
@ -305,6 +306,8 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
private scene: Scene;
|
private scene: Scene;
|
||||||
private resizeObserver: ResizeObserver | undefined;
|
private resizeObserver: ResizeObserver | undefined;
|
||||||
private nearestScrollableContainer: HTMLElement | Document | undefined;
|
private nearestScrollableContainer: HTMLElement | Document | undefined;
|
||||||
|
private detectPositionChangeIntervalId: NodeJS.Timeout | undefined;
|
||||||
|
|
||||||
constructor(props: AppProps) {
|
constructor(props: AppProps) {
|
||||||
super(props);
|
super(props);
|
||||||
const defaultAppState = getDefaultAppState();
|
const defaultAppState = getDefaultAppState();
|
||||||
@ -788,6 +791,13 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
this.scene.addCallback(this.onSceneUpdated);
|
this.scene.addCallback(this.onSceneUpdated);
|
||||||
this.addEventListeners();
|
this.addEventListeners();
|
||||||
|
|
||||||
|
if (this.props.detectPositionChange) {
|
||||||
|
this.detectPositionChangeIntervalId = setInterval(
|
||||||
|
this.updateOffsetsIfChanged,
|
||||||
|
DETECT_POSITION_CHANGE_INTERVAL,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if ("ResizeObserver" in window && this.excalidrawContainerRef?.current) {
|
if ("ResizeObserver" in window && this.excalidrawContainerRef?.current) {
|
||||||
this.resizeObserver = new ResizeObserver(() => {
|
this.resizeObserver = new ResizeObserver(() => {
|
||||||
// compute isMobile state
|
// compute isMobile state
|
||||||
@ -829,6 +839,9 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
this.removeEventListeners();
|
this.removeEventListeners();
|
||||||
this.scene.destroy();
|
this.scene.destroy();
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
if (this.detectPositionChangeIntervalId) {
|
||||||
|
clearInterval(this.detectPositionChangeIntervalId);
|
||||||
|
}
|
||||||
touchTimeout = 0;
|
touchTimeout = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1091,7 +1104,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onScroll = debounce(() => {
|
private updateOffsetsIfChanged = () => {
|
||||||
const { offsetTop, offsetLeft } = this.getCanvasOffsets();
|
const { offsetTop, offsetLeft } = this.getCanvasOffsets();
|
||||||
this.setState((state) => {
|
this.setState((state) => {
|
||||||
if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {
|
if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {
|
||||||
@ -1099,7 +1112,9 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
}
|
}
|
||||||
return { offsetTop, offsetLeft };
|
return { offsetTop, offsetLeft };
|
||||||
});
|
});
|
||||||
}, SCROLL_TIMEOUT);
|
};
|
||||||
|
|
||||||
|
private onScroll = debounce(this.updateOffsetsIfChanged, SCROLL_TIMEOUT);
|
||||||
|
|
||||||
// Copy/paste
|
// Copy/paste
|
||||||
|
|
||||||
|
@ -102,6 +102,7 @@ export const TITLE_TIMEOUT = 10000;
|
|||||||
export const TOAST_TIMEOUT = 5000;
|
export const TOAST_TIMEOUT = 5000;
|
||||||
export const VERSION_TIMEOUT = 30000;
|
export const VERSION_TIMEOUT = 30000;
|
||||||
export const SCROLL_TIMEOUT = 100;
|
export const SCROLL_TIMEOUT = 100;
|
||||||
|
export const DETECT_POSITION_CHANGE_INTERVAL = 100;
|
||||||
export const ZOOM_STEP = 0.1;
|
export const ZOOM_STEP = 0.1;
|
||||||
|
|
||||||
// Report a user inactive after IDLE_THRESHOLD milliseconds
|
// Report a user inactive after IDLE_THRESHOLD milliseconds
|
||||||
|
@ -325,6 +325,7 @@ const ExcalidrawWrapper = () => {
|
|||||||
langCode={langCode}
|
langCode={langCode}
|
||||||
renderCustomStats={renderCustomStats}
|
renderCustomStats={renderCustomStats}
|
||||||
detectScroll={false}
|
detectScroll={false}
|
||||||
|
detectPositionChange={false}
|
||||||
/>
|
/>
|
||||||
{excalidrawAPI && <CollabWrapper excalidrawAPI={excalidrawAPI} />}
|
{excalidrawAPI && <CollabWrapper excalidrawAPI={excalidrawAPI} />}
|
||||||
{errorMessage && (
|
{errorMessage && (
|
||||||
|
@ -31,6 +31,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
|
|||||||
renderCustomStats,
|
renderCustomStats,
|
||||||
onPaste,
|
onPaste,
|
||||||
detectScroll = true,
|
detectScroll = true,
|
||||||
|
detectPositionChange = true,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const canvasActions = props.UIOptions?.canvasActions;
|
const canvasActions = props.UIOptions?.canvasActions;
|
||||||
@ -82,6 +83,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
|
|||||||
UIOptions={UIOptions}
|
UIOptions={UIOptions}
|
||||||
onPaste={onPaste}
|
onPaste={onPaste}
|
||||||
detectScroll={detectScroll}
|
detectScroll={detectScroll}
|
||||||
|
detectPositionChange={detectPositionChange}
|
||||||
/>
|
/>
|
||||||
</InitializeApp>
|
</InitializeApp>
|
||||||
);
|
);
|
||||||
|
@ -196,6 +196,7 @@ export interface ExcalidrawProps {
|
|||||||
) => JSX.Element;
|
) => JSX.Element;
|
||||||
UIOptions?: UIOptions;
|
UIOptions?: UIOptions;
|
||||||
detectScroll?: boolean;
|
detectScroll?: boolean;
|
||||||
|
detectPositionChange?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SceneData = {
|
export type SceneData = {
|
||||||
@ -230,4 +231,5 @@ export type AppProps = ExcalidrawProps & {
|
|||||||
canvasActions: Required<CanvasActions>;
|
canvasActions: Required<CanvasActions>;
|
||||||
};
|
};
|
||||||
detectScroll: boolean;
|
detectScroll: boolean;
|
||||||
|
detectPositionChange: boolean;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user