PromucFlow_constructor/app/client/src/utils/reflowHookUtils.ts

91 lines
2.5 KiB
TypeScript
Raw Normal View History

feat: Reflow and Resize while Dragging and Resizing widgets. (#9054) * resize n reflow rough cut * removing warnings * relatively stable changes * minor bug fix * reflow relative collision * working dp cut * fix for reflow of widgets closer next to each other * disabling scroll * Drag with reflow * reflow fix * overlap and retracing fix * On Drop updates. * bug when no displacement but resize update. * temp fix for new widget addition. * reflow bug fixes * new widget addition bug. * stop reflow on leave. * fix corner case overlap * update bottom row when reflowed widgets go beyond bottom boundary. * capture mouse positions on enter * enable container jumps with faster mouse movements. * reflow only for snap changes. * restructured reflow Algorithm * collision check and bug fixes * undo redo fix for new widget drop * resizable fix snapRows fix * directional stability * self collision fix * first round of perf fixes * update bottom row while resizing and resize-reflowing * performance fix and overlapping fix * Remove eslint warning * remove eslint warning * eslint warning * can reflowed Drop Indication Stability * container jumps and force direction on entering canvas * fixing scroll on resize jitters. * reflow when jumping into container. * reflow ux fixes while leaving container * resizing fixes. * fixes for edge move. * restrict container jumps into reflowed containers. * container jump direction reflow * checkbox dimensions fix. * Excess bottom rows not lost post dragging or resizing widgets. * fixing the after drop css glitch. * double first move trigger bug fix. * stop reflow only if reflowing * stabilize container exit directions * using acceleration and speed instead of movement covered to restrict reflow. * fixing modal drops. * remove warnings. * reflow resize styles * moving acceleration and movement logic to a monitoring effect. * adding beta flag for reflow. * fixing jest tests * Adding analytics to beta flag toggle. * Adding placeholder for reflow beta screens. * fixing initial load's screen * few more crashes. * force close onboarding for the session. * fixing bugs in reset canvas. * Beta flag bug fixes. * fixing bugs. * restrict reflow screens during onboarding. * disabling reflow screens in tests. * code review comments. * fixing store based specs. * fixing cypress failures. * fixing specs. * code cleanup * reverting yarn lock changes * removing onboarding screens. * more cleanup and function descriptors * keeping reflow under the hood. Co-authored-by: rahulramesha <rahul@appsmith.com> Co-authored-by: Arpit Mohan <arpit@appsmith.com>
2022-01-13 13:21:57 +00:00
import { OccupiedSpace } from "constants/CanvasEditorConstants";
import { GridDefaults } from "constants/WidgetConstants";
import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
import { GridProps, ReflowedSpace, ReflowedSpaceMap } from "reflow/reflowTypes";
export function collisionCheckPostReflow(
widgets: {
[widgetId: string]: FlattenedWidgetProps;
},
reflowWidgetKeys: string[],
parentId?: string,
) {
const widgetKeys = Object.keys(widgets).filter((widgetId) => {
if (!widgets[widgetId].parentId) return false;
if (widgets[widgetId].parentId !== parentId) return false;
if (widgets[widgetId].type === "MODAL_WIDGET") return false;
return true;
});
//boundary Check
for (const reflowedKey of reflowWidgetKeys) {
if (isOutOfCanvas(widgets[reflowedKey])) {
return false;
}
}
//overlapping check
for (const reflowedKey of reflowWidgetKeys) {
for (const widgetId of widgetKeys) {
if (areIntersecting(widgets[reflowedKey], widgets[widgetId])) {
return false;
}
}
}
return true;
}
function areIntersecting(r1: FlattenedWidgetProps, r2: FlattenedWidgetProps) {
if (r1.widgetId === r2.widgetId) return false;
return !(
r2.leftColumn >= r1.rightColumn ||
r2.rightColumn <= r1.leftColumn ||
r2.topRow >= r1.bottomRow ||
r2.bottomRow <= r1.topRow
);
}
function isOutOfCanvas(widget: FlattenedWidgetProps) {
return (
widget.leftColumn < 0 ||
widget.topRow < 0 ||
widget.rightColumn > GridDefaults.DEFAULT_GRID_COLUMNS
);
}
export function getBottomRowAfterReflow(
movementMap: ReflowedSpaceMap | undefined,
widgetBottom: number,
occupiedSpaces: OccupiedSpace[],
gridProps: GridProps,
) {
const reflowedWidgets: [string, ReflowedSpace][] = Object.entries(
movementMap || {},
);
const bottomReflowedWidgets = reflowedWidgets.filter((each) => !!each[1].Y);
const reflowedWidgetsBottomMostRow = bottomReflowedWidgets.reduce(
(bottomMostRow, each) => {
const [id, reflowedParams] = each;
const widget = occupiedSpaces.find((eachSpace) => eachSpace.id === id);
if (widget) {
const bottomMovement =
(reflowedParams.Y || 0) / gridProps.parentRowSpace;
const bottomRow = widget.bottom + bottomMovement;
if (bottomRow > bottomMostRow) {
return bottomRow;
}
}
return bottomMostRow;
},
0,
);
return Math.max(reflowedWidgetsBottomMostRow, widgetBottom);
}