Skip to content

Commit

Permalink
killing it
Browse files Browse the repository at this point in the history
  • Loading branch information
alexreardon committed May 9, 2018
1 parent af9c215 commit 2dfb621
Show file tree
Hide file tree
Showing 14 changed files with 230 additions and 77 deletions.
7 changes: 4 additions & 3 deletions src/state/action-creators.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,12 @@ export const drop = (args: DropArgs) => ({

export type DropPendingAction = {|
type: 'DROP_PENDING',
payload: null,
payload: DropReason,
|}

export const dropPending = (): DropPendingAction => ({
export const dropPending = (reason: DropReason): DropPendingAction => ({
type: 'DROP_PENDING',
payload: null,
payload: reason,
});

export type DropAnimationFinishedAction = {|
Expand All @@ -253,6 +253,7 @@ export type Action =
MoveForwardAction |
CrossAxisMoveForwardAction |
CrossAxisMoveBackwardAction |
DropPendingAction |
DropAction |
DropAnimateAction |
DropAnimationFinishedAction |
Expand Down
8 changes: 6 additions & 2 deletions src/state/auto-scroller/auto-scroller-types.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// @flow
import type { State } from '../../types';
import type { DraggingState, BulkCollectionState } from '../../types';

type UserDragState = DraggingState | BulkCollectionState;

export type AutoScroller = {|
onStateChange: (previous: State, current: State) => void,
cancel: () => void,
jumpScroll: (state: UserDragState) => void,
fluidScroll: (state: UserDragState) => void,
|}
30 changes: 3 additions & 27 deletions src/state/auto-scroller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,34 +37,10 @@ export default ({
scrollDroppable,
});

const onStateChange = (previous: State, current: State): void => {
// now dragging

if (current.phase === 'DRAGGING' || current.phase === 'BULK_COLLECTING') {
if (current.autoScrollMode === 'FLUID') {
fluidScroll(current);
return;
}

// autoScrollMode == 'JUMP'

if (!current.scrollJumpRequest) {
return;
}

jumpScroll(current);
return;
}

// Not currently dragging
// Was previously dragging
if (previous.phase === 'DRAGGING' || previous.phase === 'BULK_COLLECTING') {
fluidScroll.cancel();
}
};

const marshal: AutoScroller = {
onStateChange,
cancel: fluidScroll.cancel,
fluidScroll,
jumpScroll,
};

return marshal;
Expand Down
20 changes: 12 additions & 8 deletions src/state/create-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import style from './middleware/style';
import drop from './middleware/drop';
import dropAnimationFinish from './middleware/drop-animation-finish';
import dimensionMarshalStopper from './middleware/dimension-marshal-stopper';
import autoScroll from './middleware/auto-scroll';
import pendingDrop from './middleware/pending-drop';
import type { DimensionMarshal } from './dimension-marshal/dimension-marshal-types';
import type { StyleMarshal } from '../view/style-marshal/style-marshal-types';
import type { Store, Hooks } from '../types';
Expand All @@ -33,6 +35,14 @@ export default ({
reducer,
composeEnhancers(
applyMiddleware(
// ## Debug middleware
// > uncomment to use
// debugging logger
require('./debug-middleware/log-middleware').default,
// debugging timer
// require('./debug-middleware/timing-middleware').default,
// average action timer
// require('./debug-middleware/timing-average-middleware').default(20),
// ## Application middleware
// Style updates do not cause more actions. It is important to update styles
// before hooks are called: specifically the onDragEnd hook. We need to clear
Expand All @@ -53,18 +63,12 @@ export default ({
drop,
// When a drop animation finishes - fire a drop complete
dropAnimationFinish,
pendingDrop,
autoScroll,

// TODO: where should this go?
// hooks(getHooks),

// ## Debug middleware
// > uncomment to use
// debugging logger
// require('./debug-middleware/log-middleware'),
// debugging timer
// require('./debug-middleware/timing-middleware').default,
// average action timer
// require('./debug-middleware/timing-average-middleware').default(20),
),
),
);
21 changes: 13 additions & 8 deletions src/state/dimension-marshal/collector.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export default ({
getEntries,
}: Args): Collector => {
let frameId: ?AnimationFrameID = null;
// tmep
let timerId: ?TimeoutID = null;

const collectFromDOM = (windowScroll: Position, options: CollectOptions): DimensionMap => {
const { collection, includeCritical } = options;
Expand Down Expand Up @@ -133,6 +135,7 @@ export default ({

const collect = (options: CollectOptions) => {
abortFrame();
clearTimeout(timerId);

// Perform DOM collection in next frame
frameId = requestAnimationFrame(() => {
Expand All @@ -143,14 +146,16 @@ export default ({

// Perform publish in next frame
frameId = requestAnimationFrame(() => {
timings.start('Bulk dimension publish');
bulkReplace({
dimensions,
viewport,
shouldReplaceCritical: options.includeCritical,
});
timings.finish('Bulk dimension publish');

console.log('waiting a really long time for publish');
timerId = setTimeout(() => {
timings.start('Bulk dimension publish');
bulkReplace({
dimensions,
viewport,
shouldReplaceCritical: options.includeCritical,
});
timings.finish('Bulk dimension publish');
}, 2000);
frameId = null;
});
});
Expand Down
61 changes: 61 additions & 0 deletions src/state/middleware/auto-scroll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@

// @flow
import { bindActionCreators } from 'redux';
import createAutoScroller from '../auto-scroller';
import type { AutoScroller } from '../auto-scroller/auto-scroller-types';
import {
move,
updateDroppableScroll,
} from '../action-creators';
import scrollWindow from '../../view/window/scroll-window';
import isDragEnding from './util/is-drag-ending';
import type {
Store,
State,
Action,
} from '../../types';

export default (store: Store) => {
const scroller: AutoScroller = createAutoScroller({
...bindActionCreators({
scrollDroppable: updateDroppableScroll,
move,
}, store.dispatch),
scrollWindow,
});
return (next: (Action) => mixed) => (action: Action): mixed => {
// Need to cancel any pending auto scrolling when drag is ending
if (isDragEnding(action)) {
scroller.cancel();
next(action);
return;
}

// auto scroll happens in response to state changes
// releasing all actions to the reducer first
next(action);

const state: State = store.getState();

// Only want to auto scroll in the dragging phase
// Not allowing auto scrolling while bulk collecting
// This is to avoid a mismatch in scroll between the captured
// viewport in one frame and published in the next
// Also, jump scrolling would not occur during a BULK_COLLECTION
// as no changes to the impact are permitted in that time
if (state.phase !== 'DRAGGING') {
return;
}

if (state.autoScrollMode === 'FLUID') {
scroller.fluidScroll(state);
return;
}

if (!state.scrollJumpRequest) {
return;
}

scroller.jumpScroll(state);
};
};
6 changes: 3 additions & 3 deletions src/state/middleware/dimension-marshal-stopper.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// @flow
import type { Store, State, Action } from '../../types';
import isDragEnding from './util/is-drag-ending';
import type { Action } from '../../types';
import type { DimensionMarshal } from '../dimension-marshal/dimension-marshal-types';

export default (getMarshal: () => DimensionMarshal) =>
() => (next: (Action) => mixed) => (action: Action): mixed => {
if (action.type === 'CLEAN' || action.type === 'DROP_ANIMATE' || action.type === 'DROP_COMPLETE') {
console.log('telling the marshal to stop');
if (isDragEnding(action)) {
const marshal: DimensionMarshal = getMarshal();
marshal.stopPublishing();
}
Expand Down
23 changes: 18 additions & 5 deletions src/state/middleware/drop.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const getScrollDisplacement = (

export default ({ getState, dispatch }: Store) =>
(next: (Action) => mixed) => (action: Action): mixed => {
// TODO: pending drop flushing
// TODO: pending drop flushing

const state: State = getState();

Expand All @@ -58,16 +58,29 @@ export default ({ getState, dispatch }: Store) =>
return;
}

invariant(state.phase === 'DRAGGING' || state.phase === 'BULK_COLLECTING',
`Cannot drop in phase: ${state.phase}`);
invariant(
state.phase === 'DRAGGING' ||
state.phase === 'BULK_COLLECTING' ||
state.phase === 'DROP_PENDING',
`Cannot drop in phase: ${state.phase}`
);

const reason: DropReason = action.payload.reason;

// Still waiting for a bulk collection to publish
// We are now shifting the application into the 'DROP_PENDING' phase
if (state.phase === 'BULK_COLLECTING') {
dispatch(dropPending());
dispatch(dropPending(reason));
return;
}

const reason: DropReason = action.payload.reason;
// Still waiting for our drop pending to end
if (state.phase === 'DROP_PENDING' && state.isWaiting) {
return;
}

// We are now in the DRAGGING or DROP_PENDING phase

const critical: Critical = state.critical;
const dimensions: DimensionMap = state.dimensions;
const impact: DragImpact = reason === 'DROP' ? state.impact : noImpact;
Expand Down
33 changes: 33 additions & 0 deletions src/state/middleware/pending-drop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

// @flow
import { drop } from '../action-creators';
import type {
Store,
State,
Action,
} from '../../types';

export default (store: Store) => (next: (Action) => mixed) => (action: Action): mixed => {
next(action);

if (action.type !== 'BULK_REPLACE') {
return;
}

// A bulk replace occurred - check if
// 1. there was a pending drop
// 2. that the pending drop is no longer waiting

const postActionState: State = store.getState();

if (postActionState.phase !== 'DROP_PENDING') {
return;
}

if (!postActionState.isWaiting) {
console.log('ending a pending drop');
store.dispatch(drop({
reason: postActionState.reason,
}));
}
};
8 changes: 8 additions & 0 deletions src/state/middleware/util/is-drag-ending.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// @flow
import type { Action } from '../../../types';

export default (action: Action): boolean =>
action.type === 'CLEAN' ||
action.type === 'DROP_ANIMATE' ||
action.type === 'DROP_COMPLETE' ||
action.type === 'DROP_PENDING';
Loading

0 comments on commit 2dfb621

Please sign in to comment.