Skip to content

Commit

Permalink
fix(Visibility): fire on window resize, fix behaviour of reverse calls
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Fedyashov committed Sep 19, 2017
1 parent 65ce852 commit 94c836a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 61 deletions.
36 changes: 18 additions & 18 deletions docs/app/Examples/behaviors/Visibility/Settings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,29 @@ import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection'

const VisibilitySettingsExamples = () => (
<ExampleSection title='Settings'>
<ComponentExample
title='Fire on mount'
description='Fires callbacks immediately after mount.'
examplePath='behaviors/Visibility/Settings/VisibilityExampleFireOnMount'
/>
<ComponentExample
title='Offset'
description={[
'Value that context should be adjusted in pixels. Useful for making content appear below content fixed to the ',
'page.',
].join('')}
examplePath='behaviors/Visibility/Settings/VisibilityExampleOffset'
/>
{/*<ComponentExample*/}
{/*title='Fire on mount'*/}
{/*description='Fires callbacks immediately after mount.'*/}
{/*examplePath='behaviors/Visibility/Settings/VisibilityExampleFireOnMount'*/}
{/*/>*/}
{/*<ComponentExample*/}
{/*title='Offset'*/}
{/*description={[*/}
{/*'Value that context should be adjusted in pixels. Useful for making content appear below content fixed to the ',*/}
{/*'page.',*/}
{/*].join('')}*/}
{/*examplePath='behaviors/Visibility/Settings/VisibilityExampleOffset'*/}
{/*/>*/}
<ComponentExample
title='Callback frequency'
description='You can change the callback frequency with `once` and `continuous` settings.'
examplePath='behaviors/Visibility/Settings/VisibilityExampleCallbackFrequency'
/>
<ComponentExample
title='Grouped callbacks'
description='You can specify callbacks that occur after different percentages or pixels of an element are passed.'
examplePath='behaviors/Visibility/Settings/VisibilityExampleGroupedCallbacks'
/>
{/*<ComponentExample*/}
{/*title='Grouped callbacks'*/}
{/*description='You can specify callbacks that occur after different percentages or pixels of an element are passed.'*/}
{/*examplePath='behaviors/Visibility/Settings/VisibilityExampleGroupedCallbacks'*/}
{/*/>*/}
</ExampleSection>
)

Expand Down
10 changes: 5 additions & 5 deletions docs/app/Examples/behaviors/Visibility/Types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection'

const VisibilityTypesExamples = () => (
<ExampleSection title='Types'>
<ComponentExample
title='Default'
description='An example of Visibility.'
examplePath='behaviors/Visibility/Types/VisibilityExampleVisibility'
/>
{/*<ComponentExample*/}
{/*title='Default'*/}
{/*description='An example of Visibility.'*/}
{/*examplePath='behaviors/Visibility/Types/VisibilityExampleVisibility'*/}
{/*/>*/}
</ExampleSection>
)

Expand Down
71 changes: 33 additions & 38 deletions src/behaviors/Visibility/Visibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,18 +181,19 @@ export default class Visibility extends Component {
offScreen: false,
}

firedCallbacks = []
occuredCallbacks = []

componentWillReceiveProps({ continuous, once }) {
const cleanOut = continuous !== this.props.continuous || once !== this.props.once
if (cleanOut) this.firedCallbacks = []
if (cleanOut) this.occuredCallbacks = []
}

componentDidMount() {
if (!isBrowser) return

const { context, fireOnMount } = this.props

context.addEventListener('resize', this.handleScroll)
context.addEventListener('scroll', this.handleScroll)
if (fireOnMount) this.handleUpdate()
}
Expand All @@ -201,36 +202,28 @@ export default class Visibility extends Component {
if (!isBrowser) return

const { context } = this.props
context.removeEventListener('resize', this.handleScroll)
context.removeEventListener('scroll', this.handleScroll)
}

execute = (callback, name) => {
const { continuous, once } = this.props
fire(callback, name, reverse = false) {
const { once } = this.props
const callbackName = reverse ? `${name}Reverse` : name
const calculation = this.calculations[name]

if (!callback) return
// Reverse callbacks aren't fired continuously
if (this.calculations[name] === false) return

// Always fire callback if continuous = true
if (continuous) {
callback(null, { ...this.props, calculations: this.calculations })
return
}
if(calculation !== reverse && calculation !== this.oldCalculations[name]) this.execute(callback, callbackName)
if(!once) this.occuredCallbacks = _.without(this.occuredCallbacks, callbackName)
}

// If once = true, fire callback only if it wasn't fired before
if (once) {
if (!_.includes(this.firedCallbacks, name)) {
this.firedCallbacks.push(name)
callback(null, { ...this.props, calculations: this.calculations })
}
execute(callback, name) {
const { continuous } = this.props
if (!callback) return

return
}
// Heads up! When `continuous` is true, callback will be fired always
if (!continuous && _.includes(this.occuredCallbacks, name)) return

// Fire callback only if the value changed
if (this.calculations[name] !== this.oldCalculations[name]) {
callback(null, { ...this.props, calculations: this.calculations })
}
callback(null, { ...this.props, calculations: this.calculations })
this.occuredCallbacks.push(name)
}

fireCallbacks() {
Expand All @@ -249,27 +242,27 @@ export default class Visibility extends Component {
onOnScreen,
} = this.props
const callbacks = {
bottomPassed: onBottomPassed,
bottomVisible: onBottomVisible,
passing: onPassing,
offScreen: onOffScreen,
onScreen: onOnScreen,
// bottomPassed: onBottomPassed,
// bottomVisible: onBottomVisible,
// passing: onPassing,
// offScreen: onOffScreen,
// onScreen: onOnScreen,
topPassed: onTopPassed,
topVisible: onTopVisible,
// topVisible: onTopVisible,
}
const reverse = {
bottomPassed: onBottomPassedReverse,
bottomVisible: onBottomVisibleReverse,
passing: onPassingReverse,
// bottomPassed: onBottomPassedReverse,
// bottomVisible: onBottomVisibleReverse,
// passing: onPassingReverse,
topPassed: onTopPassedReverse,
topVisible: onTopVisibleReverse,
// topVisible: onTopVisibleReverse,
}

_.invoke(this.props, 'onUpdate', null, { ...this.props, calculations: this.calculations })
this.fireOnPassed()

_.forEach(callbacks, (callback, name) => this.execute(callback, name))
_.forEach(reverse, (callback, name) => this.execute(callback, name))
_.forEach(reverse, (callback, name) => this.fire(callback, name, true))
_.forEach(callbacks, (callback, name) => this.fire(callback, name))
}

fireOnPassed = () => {
Expand Down Expand Up @@ -310,7 +303,7 @@ export default class Visibility extends Component {

const topPassed = top < topOffset
const bottomPassed = bottom < bottomOffset

console.log(topPassed)
const pixelsPassed = bottomPassed ? 0 : Math.max(top * -1, 0)
const percentagePassed = pixelsPassed / height

Expand All @@ -323,6 +316,8 @@ export default class Visibility extends Component {
const onScreen = (topVisible || topPassed) && !bottomPassed
const offScreen = !onScreen

/* TODO: DIRECTION */

this.oldCalculations = this.calculations
this.calculations = {
bottomPassed,
Expand Down

0 comments on commit 94c836a

Please sign in to comment.