-
Notifications
You must be signed in to change notification settings - Fork 106
refactor: convert to functional component #124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,4 @@ | ||||||||||
| import React, { Component } from 'react'; | ||||||||||
| import React, { useState, useRef } from 'react'; | ||||||||||
| import PropTypes from 'prop-types'; | ||||||||||
| import { | ||||||||||
| StyleSheet, View, Alert, Modal, Dimensions, TouchableOpacity, Image, | ||||||||||
|
|
@@ -22,50 +22,46 @@ const patchPostMessageJsCode = `(${String(function () { | |||||||||
| window.postMessage = patchedPostMessage; | ||||||||||
| })})();`; | ||||||||||
|
|
||||||||||
| export default class Instagram extends Component { | ||||||||||
| constructor(props) { | ||||||||||
| super(props); | ||||||||||
| this.state = { | ||||||||||
| modalVisible: false, | ||||||||||
| key: 1, | ||||||||||
| }; | ||||||||||
| } | ||||||||||
| export default function Instagram(props) { | ||||||||||
| const { wrapperStyle, containerStyle, closeStyle, onLoginSuccess, onLoginFailure, redirectUrl, appId, appSecret, responseType, scopes, language = 'en', incognito = false } = props; | ||||||||||
| const [modalVisible, setModalVisible] = useState(false); | ||||||||||
| const [key, setKey] = useState(1); | ||||||||||
| const webViewRef = useRef(null); | ||||||||||
|
|
||||||||||
| show() { | ||||||||||
| this.setState({ modalVisible: true }); | ||||||||||
| function show() { | ||||||||||
| setModalVisible(true); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| hide() { | ||||||||||
| this.setState({ modalVisible: false }); | ||||||||||
| function hide() { | ||||||||||
| setModalVisible(false); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| async onNavigationStateChange(webViewState) { | ||||||||||
| async function onNavigationStateChange(webViewState) { | ||||||||||
| const { url } = webViewState; | ||||||||||
| const { key } = this.state; | ||||||||||
|
|
||||||||||
| if ( | ||||||||||
| webViewState.title === 'Instagram' && | ||||||||||
| webViewState.url === 'https://www.instagram.com/' | ||||||||||
| ) { | ||||||||||
| this.setState({ key: key + 1 }); | ||||||||||
| setKey((k) => k + 1); | ||||||||||
| } | ||||||||||
| if (url && url.startsWith(this.props.redirectUrl)) { | ||||||||||
| this.webView.stopLoading(); | ||||||||||
| if (url && url.startsWith(redirectUrl)) { | ||||||||||
| webViewRef.current.stopLoading(); | ||||||||||
| const match = url.match(/(#|\?)(.*)/); | ||||||||||
| const results = qs.parse(match[2]); | ||||||||||
| this.hide(); | ||||||||||
| hide(); | ||||||||||
| if (results.access_token) { | ||||||||||
| // Keeping this to keep it backwards compatible, but also returning raw results to account for future changes. | ||||||||||
| this.props.onLoginSuccess(results.access_token, results); | ||||||||||
| onLoginSuccess(results.access_token, results); | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we assume that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a conditional to validate that
Suggested change
|
||||||||||
| } else if (results.code) { | ||||||||||
| //Fetching to get token with appId, appSecret and code | ||||||||||
| let { code } = results; | ||||||||||
| code = code.split('#_').join(''); | ||||||||||
| const { appId, appSecret, redirectUrl, responseType } = this.props; | ||||||||||
| if (responseType === 'code' && !appSecret) { | ||||||||||
| if (code) { | ||||||||||
| this.props.onLoginSuccess(code, results); | ||||||||||
| onLoginSuccess(code, results); | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||||||||||
| } else { | ||||||||||
| this.props.onLoginFailure(results); | ||||||||||
| onLoginFailure(results); | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||||||||||
| } | ||||||||||
| } else { | ||||||||||
| let headers = { 'Content-Type': 'application/x-www-form-urlencoded' }; | ||||||||||
|
|
@@ -86,107 +82,97 @@ export default class Instagram extends Component { | |||||||||
| }); | ||||||||||
|
|
||||||||||
| if (res) { | ||||||||||
| this.props.onLoginSuccess(res.data, results); | ||||||||||
| onLoginSuccess(res.data, results); | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||||||||||
| } else { | ||||||||||
| this.props.onLoginFailure(results); | ||||||||||
| onLoginFailure(results); | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||||||||||
| } | ||||||||||
| } | ||||||||||
| } else { | ||||||||||
| this.props.onLoginFailure(results); | ||||||||||
| onLoginFailure(results); | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| onMessage(reactMessage) { | ||||||||||
| function onMessage(reactMessage) { | ||||||||||
| try { | ||||||||||
| const json = JSON.parse(reactMessage.nativeEvent.data); | ||||||||||
| if (json && json.error_type) { | ||||||||||
| this.hide(); | ||||||||||
| this.props.onLoginFailure(json); | ||||||||||
| hide(); | ||||||||||
| onLoginFailure(json); | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||||||||||
| } | ||||||||||
| } catch (err) { } | ||||||||||
| } catch (err) {} | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // _onLoadEnd () { | ||||||||||
| // const scriptToPostBody = "window.postMessage(document.body.innerText, '*')" | ||||||||||
| // this.webView.injectJavaScript(scriptToPostBody) | ||||||||||
| // } | ||||||||||
|
|
||||||||||
| renderClose() { | ||||||||||
| const { renderClose } = this.props; | ||||||||||
| if (renderClose) { | ||||||||||
| return renderClose(); | ||||||||||
| function renderClose() { | ||||||||||
| if (props.renderClose) { | ||||||||||
| return props.renderClose(); | ||||||||||
| } | ||||||||||
| return ( | ||||||||||
| <Image | ||||||||||
| source={require('./assets/close-button.png')} | ||||||||||
| style={styles.imgClose} | ||||||||||
| resizeMode="contain" | ||||||||||
| resizeMode='contain' | ||||||||||
| /> | ||||||||||
| ); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| onClose() { | ||||||||||
| const { onClose } = this.props; | ||||||||||
| if (onClose) { | ||||||||||
| onClose(); | ||||||||||
| function onClose() { | ||||||||||
| if (props.onClose) { | ||||||||||
| props.onClose(); | ||||||||||
| } | ||||||||||
| // Reuse hide state update logic | ||||||||||
| this.hide(); | ||||||||||
| hide(); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| renderWebview() { | ||||||||||
| const { appId, appSecret, redirectUrl, scopes, responseType,language='en', incognito=false } = this.props; | ||||||||||
| const { key } = this.state; | ||||||||||
|
|
||||||||||
| function renderWebview() { | ||||||||||
| let ig_uri = `https://api.instagram.com/oauth/authorize/?client_id=${appId}&redirect_uri=${redirectUrl}&response_type=${responseType}&scope=${scopes.join(',')}`; | ||||||||||
|
|
||||||||||
| return ( | ||||||||||
| <WebView | ||||||||||
| {...this.props} | ||||||||||
| {...props} | ||||||||||
| key={key} | ||||||||||
| incognito={incognito} | ||||||||||
| style={[styles.webView, this.props.styles.webView]} | ||||||||||
| source={{ uri: ig_uri,headers: { | ||||||||||
| "Accept-Language": `${language}`, | ||||||||||
| } }} | ||||||||||
| style={[styles.webView, props.styles.webView]} | ||||||||||
| source={{ | ||||||||||
| uri: ig_uri, | ||||||||||
| headers: { | ||||||||||
| 'Accept-Language': `${language}`, | ||||||||||
| }, | ||||||||||
| }} | ||||||||||
| startInLoadingState | ||||||||||
| onNavigationStateChange={this.onNavigationStateChange.bind(this)} | ||||||||||
| onError={this.onNavigationStateChange.bind(this)} | ||||||||||
| onMessage={this.onMessage.bind(this)} | ||||||||||
| ref={(webView) => { this.webView = webView; }} | ||||||||||
| onNavigationStateChange={onNavigationStateChange} | ||||||||||
| onError={onNavigationStateChange} | ||||||||||
| onMessage={onMessage} | ||||||||||
| ref={(webView) => { | ||||||||||
| webViewRef.current = webView; | ||||||||||
| }} | ||||||||||
| injectedJavaScript={patchPostMessageJsCode} | ||||||||||
| /> | ||||||||||
| ); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| render() { | ||||||||||
| const { wrapperStyle, containerStyle, closeStyle } = this.props; | ||||||||||
|
|
||||||||||
| // Bind onClose to onRequestClose callback rather than hide to ensure that the (optional) | ||||||||||
| // onClose callback provided by client is called when dialog is dismissed | ||||||||||
| return ( | ||||||||||
| <Modal | ||||||||||
| animationType={'slide'} | ||||||||||
| visible={this.state.modalVisible} | ||||||||||
| onRequestClose={this.onClose.bind(this)} | ||||||||||
| transparent> | ||||||||||
| <View style={[styles.container, containerStyle]}> | ||||||||||
| <View style={[styles.wrapper, wrapperStyle]}> | ||||||||||
| {this.renderWebview()} | ||||||||||
| </View> | ||||||||||
| <TouchableOpacity | ||||||||||
| onPress={() => this.onClose()} | ||||||||||
| style={[styles.close, closeStyle]} | ||||||||||
| accessibilityComponentType={'button'} | ||||||||||
| accessibilityTraits={['button']}> | ||||||||||
| {this.renderClose()} | ||||||||||
| </TouchableOpacity> | ||||||||||
| </View> | ||||||||||
| </Modal> | ||||||||||
| ); | ||||||||||
| } | ||||||||||
| return ( | ||||||||||
| <Modal | ||||||||||
| animationType={'slide'} | ||||||||||
| visible={modalVisible} | ||||||||||
| onRequestClose={onClose} | ||||||||||
| transparent | ||||||||||
| > | ||||||||||
| <View style={[styles.container, containerStyle]}> | ||||||||||
| <View style={[styles.wrapper, wrapperStyle]}>{renderWebview()}</View> | ||||||||||
| <TouchableOpacity | ||||||||||
| onPress={() => onClose()} | ||||||||||
| style={[styles.close, closeStyle]} | ||||||||||
| accessibilityComponentType={'button'} | ||||||||||
| accessibilityTraits={['button']} | ||||||||||
| > | ||||||||||
| {renderClose()} | ||||||||||
| </TouchableOpacity> | ||||||||||
| </View> | ||||||||||
| </Modal> | ||||||||||
| ); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| const propTypes = { | ||||||||||
| appId: PropTypes.string.isRequired, | ||||||||||
| appSecret: PropTypes.string, | ||||||||||
|
|
||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why exactly do you need to increase the key counter on that? just to force a rerender?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't understand too
Should we do this change in this PR, since its only goal is to move from class to FC?