Skip to content

Instantly share code, notes, and snippets.

@jennmueng
Created February 13, 2019 05:12
Show Gist options
  • Save jennmueng/2408320e63e30ddadd143e9d83d64ed3 to your computer and use it in GitHub Desktop.
Save jennmueng/2408320e63e30ddadd143e9d83d64ed3 to your computer and use it in GitHub Desktop.
Webview scroll issue
// @flow
import React, { Component } from 'react';
import { WebView } from 'react-native-webview';
import styled from 'styled-components';
import { connect } from 'react-redux';
import * as Animatable from 'react-native-animatable';
import Reactotron from 'reactotron-react-native';
import type { NavigationScreenProp } from 'react-navigation';
import type { DeviceProps } from '../../../flow/general';
import WebViewHeader from './components/webviewHeader';
import addBookingBookedAction from '../hotels/actions/chain.addBookingBooked';
import ErrorAlert from '../../tools/errorAlert';
import ButtonArea from '../../components/screens/buttonArea';
import LoadingOverlay from '../../components/screens/loadingOverlay';
class WebViewContainer extends Component<
{
addBookingBooked: Function,
navigation: NavigationScreenProp,
deviceProps: DeviceProps
},
{
loading: boolean,
height: number
}
> {
state = {
loading: false,
height: 0
};
goBack = () => {
this.props.navigation.goBack(null);
};
onLoadStart = e => {
Reactotron.log(e);
if (
e.nativeEvent.title.toLowerCase().includes('confirmation')
|| e.nativeEvent.url.toLowerCase().includes('confirmation')
) {
this.props.addBookingBooked(e.nativeEvent.url, this.showButtonArea, this.onFail);
this.setState({
loading: true
});
}
};
goToHotels = () => {
this.props.navigation.navigate('Hotels');
};
onFail = () => {
ErrorAlert('Could not add booking to trip', 'webview:hotelSearch/onFail');
};
webViewBack = () => {
this.webView.goBack();
};
webViewForward = () => {
this.webView.goForward();
};
setHeight = (height: number) => {
this.setState({
height
});
};
showButtonArea = () => {
const buttonAreaHeight = this.props.deviceProps.profile === 1 ? 140 : 110;
this.setState(
{
loading: false
},
() => {
this.webViewContainer.transition(
{ height: this.state.height },
{ height: this.state.height - (buttonAreaHeight - 50) },
240,
'ease-out-cubic'
);
this.buttonArea.transition({ translateY: 0 }, { translateY: -buttonAreaHeight }, 240, 'ease-out-cubic');
}
);
};
webView: any;
webViewContainer: any;
buttonArea: any;
render() {
const { navigation, deviceProps } = this.props;
const { loading, height } = this.state;
const { source } = navigation.state.params;
return (
<Container>
<WebViewHeader
goBack={this.goBack}
webViewBack={this.webViewBack}
webViewForward={this.webViewForward}
deviceProps={deviceProps}
/>
<ViewContainer
ref={c => (this.webViewContainer = c)}
onLayout={({
nativeEvent: {
layout: { height: layoutHeight }
}
}) => this.setHeight(layoutHeight)}
>
<WebView
style={{ width: '100%', height }}
source={{ uri: source }}
ref={c => (this.webView = c)}
onLoadStart={this.onLoadStart}
scrollsToTop={false}
/>
</ViewContainer>
<ButtonAreaContainer ref={c => (this.buttonArea = c)} deviceProps={deviceProps}>
<ButtonArea action={this.goToHotels} buttonText="Done" deviceProps={deviceProps} />
</ButtonAreaContainer>
{loading && (
<LoadingContainer>
<LoadingOverlay text="Adding to your trip..." />
</LoadingContainer>
)}
</Container>
);
}
}
const mapStateToProps = state => ({
deviceProps: state.deviceProps
});
const actionCreators = {
addBookingBooked: addBookingBookedAction
};
export default connect(
mapStateToProps,
actionCreators
)(WebViewContainer);
const Container = styled.View`
flex: 1;
`;
const ViewContainer = Animatable.createAnimatableComponent(styled.View`
flex: 1;
`);
const ButtonAreaContainer = Animatable.createAnimatableComponent(styled.View`
position: absolute;
bottom: -${({ deviceProps: { profile } }) => (profile === 1 ? 140 : 110)};
`);
const LoadingContainer = styled.View`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment