'use strict'

import React from 'react'
import { UIManager, findNodeHandle } from 'react-native'
import PropTypes from 'prop-types'
import * as Utils from '../utils'

export default WrappedComponent => {
  return class extends React.Component {
    constructor(props, context) {
      super(props, context)
      this.state = {
        inViewport: false,
      }
    }

    componentDidMount() {
      this.context.addViewportListener &&
        this.context.addViewportListener(this._onViewportChange)
    }

    componentWillUnmount() {
      this.context.removeViewportListener &&
        this.context.removeViewportListener(this._onViewportChange)
    }

    _onViewportChange = info => {
      if (this.wrapperRef != null) {
        UIManager.measureLayout(
          this.nodeHandle,
          info.parentHandle,
          () => {},
          (wrapperX, wrapperY, wrapperWidth, wrapperHeight) => {
            const inViewport = Utils.isInViewport(
              info.viewportOffset,
              info.viewportHeight,
              wrapperY,
              wrapperHeight,
              this.props.preTriggerRatio
            )
            this.setState({
              inViewport,
            })
          }
        )
      }
    }

    render() {
      return (
        <WrappedComponent
          ref={ref => {
            this.wrapperRef = ref
            this.nodeHandle = findNodeHandle(ref)
          }}
          {...this.props}
          inViewport={this.state.inViewport}
        />
      )
    }

    static propTypes = {
      preTriggerRatio: PropTypes.number,
    }

    static contextTypes = {
      addViewportListener: PropTypes.func,
      removeViewportListener: PropTypes.func,
    }

    static displayName = `ViewportAware(${WrappedComponent.displayName ||
      WrappedComponent.name ||
      'Component'})`
  }
}

@@ -317,24 +317,86 @@
 s.state = %7B%0A
+        componentOffset: null,%0A        componentHeight: null,%0A
         inVi
@@ -550,32 +550,61 @@
 ViewportChange)%0A
+      this._isMounted = true%0A
     %7D%0A%0A    compo
@@ -732,24 +732,54 @@
 portChange)%0A
+      this._isMounted = false%0A
     %7D%0A%0A    _
@@ -821,31 +821,159 @@
 if (
+!
 this.
-wrapperRef
+nodeHandle) %7B%0A        return%0A      %7D%0A      if (%0A        this.state.componentOffset !== null &&%0A        this.state.componentHeight
  !=
+=
  null
+%0A      
 ) %7B%0A
@@ -984,191 +984,607 @@
     
-UIManager.measureLayout(%0A          this.nodeHandle,%0A          info.parentHandle,%0A          () =%3E %7B%7D,%0A          (wrapperX, wrapperY, wrapperWidth, wrapperHeight) =%3E %7B%0A            const
+this.setState(%7B%0A          inViewport: Utils.isInViewport(%0A            info.viewportOffset,%0A            info.viewportHeight,%0A            this.state.componentOffset,%0A            this.state.componentHeight,%0A            this.props.preTriggerRatio%0A          ),%0A        %7D)%0A      %7D else %7B%0A        UIManager.measureLayout(%0A          this.nodeHandle,%0A          info.parentHandle,%0A          () =%3E %7B%7D,%0A          (offsetX, offsetY, width, height) =%3E %7B%0A            this._isMounted &&%0A              this.setState(%7B%0A                componentOffset: offsetY,%0A                componentHeight: height,%0A               
  inV
@@ -1590,18 +1590,17 @@
 Viewport
- =
+:
  Utils.i
@@ -1604,32 +1604,36 @@
 s.isInViewport(%0A
+    
               in
@@ -1657,32 +1657,36 @@
 ,%0A              
+ 
+   
 info.viewportHei
@@ -1704,23 +1704,26 @@
         
+   
-wrapper
+ offset
 Y,%0A     
@@ -1735,23 +1735,24 @@
     
-wrapperH
+    h
 eight,%0A
+    
     
@@ -1804,64 +1804,17 @@
     
-)%0A
     
-        this.setState(%7B%0A              inViewport,%0A
+),%0A  
     
@@ -1943,56 +1943,9 @@
  =%3E 
-%7B%0A            this.wrapperRef = ref%0A            
+(
 this
@@ -1977,28 +1977,17 @@
 dle(ref)
-%0A          %7D
+)
 %7D%0A      

Improve viewport awareness higher-order component (#62)