Skip to content

Commit

Permalink
[refactored] isAnyOf to use named args
Browse files Browse the repository at this point in the history
Summary: Continuation of #193

Reviewers: O2 Material Motion, O3 Material JavaScript platform reviewers, #material_motion, vietanh

Reviewed By: #material_motion, vietanh

Tags: #material_motion

Differential Revision: http://codereview.cc/D3413
  • Loading branch information
appsforartists committed Oct 11, 2017
1 parent 2ac5748 commit 635eb98
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 22 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/interactions/Point2DSpring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ export class Point2DSpring implements Spring<Point2D> {
}

readonly state$: ObservableWithMotionOperators<State> = anyOf([
this.xSpring.state$.isAnyOf([ State.ACTIVE ]),
this.ySpring.state$.isAnyOf([ State.ACTIVE ]),
this.xSpring.state$.isAnyOf({ candidates: [ State.ACTIVE ] }),
this.ySpring.state$.isAnyOf({ candidates: [ State.ACTIVE ] }),
]).dedupe().rewrite<State, State>({
true: State.ACTIVE,
false: State.AT_REST,
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/interactions/Swipeable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export class Swipeable {

this.iconSpring.initialValue = ICON_SPRING_INITIAL_VALUE;

const tossableIsAtRest$ = tossable.state$.isAnyOf([ State.AT_REST ]);
const tossableIsAtRest$ = tossable.state$.isAnyOf({ candidates: [ State.AT_REST ] });
subscribe({
sink: tossable.resistanceFactor$,
source: when(tossableIsAtRest$).rewriteTo(
Expand All @@ -164,7 +164,7 @@ export class Swipeable {
)
});

this.direction$ = draggedX$.threshold(0).isAnyOf([ ThresholdRegion.ABOVE ]).rewrite({
this.direction$ = draggedX$.threshold(0).isAnyOf({ candidates: [ ThresholdRegion.ABOVE ] }).rewrite({
true: Direction.RIGHT,
false: Direction.LEFT
});
Expand All @@ -178,14 +178,14 @@ export class Swipeable {

this.isThresholdMet$ = draggedX$.distanceFrom({
origin$: 0,
}).threshold(Swipeable.VISUAL_THRESHOLD).isAnyOf([ThresholdRegion.ABOVE, ThresholdRegion.WITHIN]);
}).threshold(Swipeable.VISUAL_THRESHOLD).isAnyOf({ candidates: [ThresholdRegion.ABOVE, ThresholdRegion.WITHIN] });
this.whenThresholdCrossed$ = when(this.isThresholdMet$.dedupe());
this.whenThresholdFirstCrossed$ = when(tossable.resistanceFactor$.dedupe().isAnyOf([ DISABLED_RESISTANCE_FACTOR ]));
this.whenThresholdFirstCrossed$ = when(tossable.resistanceFactor$.dedupe().isAnyOf({ candidates: [ DISABLED_RESISTANCE_FACTOR ] }));

subscribe({
sink: spring.enabled$,
source: this.whenThresholdFirstCrossed$.merge(
when(spring.state$.isAnyOf([ State.AT_REST ])).rewriteTo(false)
when(spring.state$.isAnyOf({ candidates: [ State.AT_REST ] })).rewriteTo(false)
),
});

Expand Down Expand Up @@ -224,7 +224,7 @@ export class Swipeable {
// cares about final position.
subscribe({
sink: this.swipeState$,
source: when(draggable.state$.isAnyOf([ State.AT_REST ])).rewriteTo(
source: when(draggable.state$.isAnyOf({ candidates: [ State.AT_REST ] })).rewriteTo(
this.isThresholdMet$.rewrite({
true: this.direction$,
false: SwipeState.NONE,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/interactions/Tossable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ export class Tossable {
subscribe({
sink: this.state$,
source: anyOf([
spring.state$.isAnyOf([ State.ACTIVE ]),
draggable.state$.isAnyOf([ State.ACTIVE ])
spring.state$.isAnyOf({ candidates: [ State.ACTIVE ] }),
draggable.state$.isAnyOf({ candidates: [ State.ACTIVE ] }),
]).rewrite({
true: State.ACTIVE,
false: State.AT_REST,
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/operators/__tests__/isAnyOf.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe('motionObservable.isAnyOf',

it('should dispatch true when the upstream values matches a possibility',
() => {
subject.isAnyOf([1, 2, 3]).subscribe(listener);
subject.isAnyOf({ candidates: [1, 2, 3] }).subscribe(listener);

subject.next(2);

Expand All @@ -59,7 +59,7 @@ describe('motionObservable.isAnyOf',

it('should dispatch false when the upstream values matches a possibility',
() => {
subject.isAnyOf([1, 2, 3]).subscribe(listener);
subject.isAnyOf({ candidates: [1, 2, 3] }).subscribe(listener);

subject.next(4);

Expand All @@ -69,7 +69,7 @@ describe('motionObservable.isAnyOf',

it('should accept reactive matches',
() => {
subject.isAnyOf([1, argSubject, 3]).subscribe(listener);
subject.isAnyOf({ candidates: [1, argSubject, 3] }).subscribe(listener);

argSubject.next(2);
subject.next(4);
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/operators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export interface ObservableWithMotionOperators<T> extends
MotionDeduplicable<T>,
MotionDivisible<T>,
MotionInvertible<T>,
MotionIsAnyOfable,
MotionIsAnyOfable<T>,
MotionLoggable<T>,
MotionMeasurable<T>,
MotionMergeable<T>,
Expand Down
23 changes: 15 additions & 8 deletions packages/core/src/operators/isAnyOf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,29 @@ import {
Constructor,
MotionReactiveMappable,
NextChannel,
Observable,
ObservableWithMotionOperators,
} from '../types';

export interface MotionIsAnyOfable {
isAnyOf(matches: Array<any>): ObservableWithMotionOperators<boolean>;
export type IsAnyOfArgs<T> = {
// To be consistent with our naming strategy, this should probably be called
// candidate$s, but it looks weird to combine the two sufficies.
candidates: Array<T | Observable<T>>,
};

export interface MotionIsAnyOfable<T> {
isAnyOf(kwargs: IsAnyOfArgs<T>): ObservableWithMotionOperators<boolean>;
}

export function withIsAnyOf<T, S extends Constructor<MotionReactiveMappable<T>>>(superclass: S): S & Constructor<MotionIsAnyOfable> {
return class extends superclass implements MotionIsAnyOfable {
export function withIsAnyOf<T, S extends Constructor<MotionReactiveMappable<T>>>(superclass: S): S & Constructor<MotionIsAnyOfable<T>> {
return class extends superclass implements MotionIsAnyOfable<T> {
/**
* Dispatches `true` when it receives a value that matches any of the
* provided values and `false` otherwise.
* provided candidates and `false` otherwise.
*/
isAnyOf(matches: Array<any>): ObservableWithMotionOperators<boolean> {
return combineLatest([ this, ...matches ])._map({
transform: ([ upstream, ...currentMatches ]: Array<T>) => currentMatches.includes(upstream)
isAnyOf({ candidates }: IsAnyOfArgs<T>): ObservableWithMotionOperators<boolean> {
return combineLatest([ this, ...candidates ])._map({
transform: ([ upstream, ...currentCandidates ]: Array<T>) => currentCandidates.includes(upstream)
});
}
};
Expand Down

0 comments on commit 635eb98

Please sign in to comment.