Disable block pointer events during layout drag (#183)

This will ensure that the webview cannot capture the pointer events and
disrupt the drag functionality.

This also fixes an issue where greedy and imprecise bounds calculations
could result in thrashing of the layoutState.pendingAction field, which
could cause the placeholder to flicker.

This also fixes issues where some React Effects that were supposed to be
debounced or throttled were being invoked too much. This is because
useEffect regenerates the callback when it is run, resulting in the
debounce or throttle never taking effect. Moving the throttled or
debounced logic to a separate callback solves this.
This commit is contained in:
Evan Simkowitz
2024-07-31 12:49:38 -07:00
committed by GitHub
parent 3ff03f7b34
commit 2157df85de
4 changed files with 152 additions and 108 deletions
+15 -9
View File
@@ -22,6 +22,7 @@ import * as React from "react";
import "./block.less";
export interface LayoutComponentModel {
disablePointerEvents: boolean;
onClose?: () => void;
onMagnifyToggle?: () => void;
dragHandleRef?: React.RefObject<HTMLDivElement>;
@@ -268,7 +269,7 @@ const BlockFrame_Default_Component = ({
if (preview) {
isFocused = true;
}
let style: React.CSSProperties = {};
const style: React.CSSProperties = {};
if (!isFocused && blockData?.meta?.["frame:bordercolor"]) {
style.borderColor = blockData.meta["frame:bordercolor"];
}
@@ -286,12 +287,13 @@ const BlockFrame_Default_Component = ({
if (preIconButton) {
preIconButtonElem = <IconButton decl={preIconButton} className="block-frame-preicon-button" />;
}
let endIconsElem: JSX.Element[] = [];
const endIconsElem: JSX.Element[] = [];
if (endIconButtons && endIconButtons.length > 0) {
for (let idx = 0; idx < endIconButtons.length; idx++) {
const button = endIconButtons[idx];
endIconsElem.push(<IconButton key={idx} decl={button} className="block-frame-endicon-button" />);
}
endIconsElem.push(
...endIconButtons.map((button, idx) => (
<IconButton key={idx} decl={button} className="block-frame-endicon-button" />
))
);
}
const settingsDecl: HeaderIconButton = {
elemtype: "iconbutton",
@@ -549,7 +551,7 @@ function makeDefaultViewModel(blockId: string): ViewModel {
}
const BlockPreview = React.memo(({ blockId, layoutModel }: BlockProps) => {
const [blockData, blockDataLoading] = WOS.useWaveObjectValue<Block>(WOS.makeORef("block", blockId));
const [blockData] = WOS.useWaveObjectValue<Block>(WOS.makeORef("block", blockId));
if (!blockData) {
return null;
}
@@ -578,7 +580,7 @@ const BlockFull = React.memo(({ blockId, layoutModel }: BlockProps) => {
return winData.activeblockid === blockId;
});
});
let isFocused = jotai.useAtomValue(isFocusedAtom);
const isFocused = jotai.useAtomValue(isFocusedAtom);
React.useLayoutEffect(() => {
setBlockClicked(isFocused);
@@ -651,7 +653,11 @@ const BlockFull = React.memo(({ blockId, layoutModel }: BlockProps) => {
<div key="focuselem" className="block-focuselem">
<input type="text" value="" ref={focusElemRef} id={`${blockId}-dummy-focus`} onChange={() => {}} />
</div>
<div key="content" className="block-content">
<div
key="content"
className="block-content"
style={{ pointerEvents: layoutModel?.disablePointerEvents ? "none" : undefined }}
>
<ErrorBoundary>
<React.Suspense fallback={<CenteredDiv>Loading...</CenteredDiv>}>{viewElem}</React.Suspense>
</ErrorBoundary>