Skip to content

Commit

Permalink
bulk replace getting some love
Browse files Browse the repository at this point in the history
  • Loading branch information
alexreardon committed Jun 7, 2018
1 parent 36a5fde commit e6b1a64
Show file tree
Hide file tree
Showing 10 changed files with 447 additions and 306 deletions.
7 changes: 7 additions & 0 deletions src/state/bulk-replace/bulk-replace-types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// @flow
import type {
DraggingState,
DropPendingState,
} from '../../types';

export type Result = DraggingState | DropPendingState;
35 changes: 35 additions & 0 deletions src/state/bulk-replace/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// @flow
import withCriticalReplacement from './with-critical-replacement';
import withoutCriticalReplacement from './without-critical-replacement';
import type {
BulkCollectionState,
DropPendingState,
Critical,
DimensionMap,
Viewport,
} from '../../types';
import type { Result } from './bulk-replace-types';

type Args = {|
state: BulkCollectionState | DropPendingState,
viewport: Viewport,
critical: ?Critical,
dimensions: DimensionMap,
|}

export default ({
state,
viewport,
critical,
dimensions,
}: Args): Result => {
if (critical) {
return withCriticalReplacement({
state, viewport, critical, dimensions,
});
}

return withoutCriticalReplacement({
state, viewport, dimensions,
});
};
114 changes: 114 additions & 0 deletions src/state/bulk-replace/with-critical-replacement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// @flow
import type { Position } from 'css-box-model';
import { add, subtract } from '../position';
import getDragImpact from '../get-drag-impact';
import type {
BulkCollectionState,
DropPendingState,
DraggingState,
DraggableDimension,
Critical,
DimensionMap,
Viewport,
DragImpact,
DragPositions,
ItemPositions,
} from '../../types';
import type { Result } from './bulk-replace-types';

type Args = {|
state: BulkCollectionState | DropPendingState,
viewport: Viewport,
critical: Critical,
dimensions: DimensionMap,
|}

const origin: Position = { x: 0, y: 0 };

export default ({
state,
viewport,
critical,
dimensions,
}: Args): Result => {
const oldClientBorderBoxCenter: Position = state.initial.client.borderBoxCenter;
const draggable: DraggableDimension = dimensions.draggables[critical.draggable.id];
const newClientBorderBoxCenter: Position = draggable.client.borderBox.center;
const centerDiff: Position = subtract(newClientBorderBoxCenter, oldClientBorderBoxCenter);

const oldInitialClientSelection: Position = state.initial.client.selection;
const newInitialClientSelection: Position = add(oldInitialClientSelection, centerDiff);

// Need to figure out what the initial and current positions should be
const initial: DragPositions = {
client: {
selection: newInitialClientSelection,
borderBoxCenter: newClientBorderBoxCenter,
offset: origin,
},
page: {
selection: add(newInitialClientSelection, viewport.scroll.initial),
borderBoxCenter: add(newClientBorderBoxCenter, viewport.scroll.initial),
offset: add(origin, viewport.scroll.initial),
},
};

const newCurrentOffset: Position = subtract(state.current.client.offset, centerDiff);

const current: DragPositions = (() => {
const client: ItemPositions = {
selection: add(initial.client.selection, newCurrentOffset),
borderBoxCenter: add(initial.client.borderBoxCenter, newCurrentOffset),
offset: newCurrentOffset,
};
const page: ItemPositions = {
selection: add(client.selection, viewport.scroll.current),
borderBoxCenter: add(client.borderBoxCenter, viewport.scroll.current),
offset: add(client.offset, viewport.scroll.current),
};
return { client, page };
})();

const impact: DragImpact = getDragImpact({
pageBorderBoxCenter: current.page.borderBoxCenter,
draggable: dimensions.draggables[critical.draggable.id],
draggables: dimensions.draggables,
droppables: dimensions.droppables,
previousImpact: state.impact,
viewport,
});

const draggingState: DraggingState = {
// appeasing flow
phase: 'DRAGGING',
...state,
// eslint-disable-next-line
phase: 'DRAGGING',
impact,
viewport,
initial,
current,
dimensions,
};

if (state.phase === 'BULK_COLLECTING') {
return draggingState;
}

// There was a DROP_PENDING
// Staying in the DROP_PENDING phase
// setting isWaiting for false

const dropPending: DropPendingState = {
// appeasing flow
phase: 'DROP_PENDING',
...draggingState,
// eslint-disable-next-line
phase: 'DROP_PENDING',
// No longer waiting
reason: state.reason,
isWaiting: false,
};

return dropPending;
};
83 changes: 83 additions & 0 deletions src/state/bulk-replace/without-critical-replacement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// @flow
import getDragImpact from '../get-drag-impact';
import type {
BulkCollectionState,
DropPendingState,
DraggingState,
DraggableDimension,
DroppableDimension,
DimensionMap,
Viewport,
DragImpact,
} from '../../types';
import type { Result } from './bulk-replace-types';

type Args = {|
state: BulkCollectionState | DropPendingState,
viewport: Viewport,
dimensions: DimensionMap,
|}

export default ({
state,
viewport,
dimensions: suppliedDimensions,
}: Args): Result => {
// need to maintain critical dimensions as they where not collected
const draggable: DraggableDimension =
state.dimensions.draggables[state.critical.draggable.id];
const droppable: DroppableDimension =
state.dimensions.droppables[state.critical.droppable.id];

const dimensions: DimensionMap = {
draggables: {
...suppliedDimensions.draggables,
[draggable.descriptor.id]: draggable,
},
droppables: {
...suppliedDimensions.droppables,
[droppable.descriptor.id]: droppable,
},
};

const impact: DragImpact = getDragImpact({
pageBorderBoxCenter: state.current.page.borderBoxCenter,
draggable: dimensions.draggables[state.critical.draggable.id],
draggables: dimensions.draggables,
droppables: dimensions.droppables,
previousImpact: state.impact,
viewport,
});

const draggingState: DraggingState = {
// appeasing flow
phase: 'DRAGGING',
...state,
// eslint-disable-next-line
phase: 'DRAGGING',
impact,
viewport,
dimensions,
};

if (state.phase === 'BULK_COLLECTING') {
return draggingState;
}

// There was a DROP_PENDING
// Staying in the DROP_PENDING phase
// setting isWaiting for false

const dropPending: DropPendingState = {
// appeasing flow
phase: 'DROP_PENDING',
...draggingState,
// eslint-disable-next-line
phase: 'DROP_PENDING',
// No longer waiting
reason: state.reason,
isWaiting: false,
};

return dropPending;
};
20 changes: 14 additions & 6 deletions src/state/get-home-impact.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
// @flow
import { patch } from './position';
import type {
Critical,
DimensionMap,
DraggableDimension,
DroppableDimension,
DroppableDimensionMap,
Axis,
} from '../types';
import { noMovement } from './no-impact';

export default (critical: Critical, droppables: DroppableDimensionMap) => {
const home: DroppableDimension = droppables[critical.droppable.id];
export default (critical: Critical, dimensions: DimensionMap) => {
const home: DroppableDimension = dimensions.droppables[critical.droppable.id];
const axis: Axis = home.axis;
const draggable: DraggableDimension = dimensions.draggables[critical.draggable.id];

return {
movement: noMovement,
direction: home.axis.direction,
movement: {
displaced: [],
isBeyondStartPosition: false,
amount: patch(axis.line, draggable.client.marginBox[axis.size]),
},
direction: axis.direction,
destination: {
index: critical.draggable.index,
droppableId: critical.droppable.id,
Expand Down
Loading

0 comments on commit e6b1a64

Please sign in to comment.