Application Android et IOS pour l'amicale des élèves https://play.google.com/store/apps/details?id=fr.amicaleinsat.application
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

WebViewScreen.js 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // @flow
  2. import * as React from 'react';
  3. import WebView from "react-native-webview";
  4. import BasicLoadingScreen from "../Custom/BasicLoadingScreen";
  5. import ErrorView from "../Custom/ErrorView";
  6. import {ERROR_TYPE} from "../../utils/WebData";
  7. import MaterialHeaderButtons, {Item} from '../Custom/HeaderButton';
  8. import {HiddenItem} from "react-navigation-header-buttons";
  9. import {Linking} from "expo";
  10. import i18n from 'i18n-js';
  11. import {Animated, BackHandler} from "react-native";
  12. import {withCollapsible} from "../../utils/withCollapsible";
  13. type Props = {
  14. navigation: Object,
  15. url: string,
  16. customJS: string,
  17. collapsibleStack: Object,
  18. onMessage: Function,
  19. onScroll: Function,
  20. }
  21. const AnimatedWebView = Animated.createAnimatedComponent(WebView);
  22. /**
  23. * Class defining a webview screen.
  24. */
  25. class WebViewScreen extends React.PureComponent<Props> {
  26. static defaultProps = {
  27. customJS: '',
  28. };
  29. webviewRef: Object;
  30. canGoBack: boolean;
  31. constructor() {
  32. super();
  33. this.webviewRef = React.createRef();
  34. this.canGoBack = false;
  35. }
  36. /**
  37. * Creates refresh button after mounting
  38. */
  39. componentDidMount() {
  40. const rightButton = this.getRefreshButton.bind(this);
  41. this.props.navigation.setOptions({
  42. headerRight: rightButton,
  43. });
  44. this.props.navigation.addListener(
  45. 'focus',
  46. () =>
  47. BackHandler.addEventListener(
  48. 'hardwareBackPress',
  49. this.onBackButtonPressAndroid
  50. )
  51. );
  52. this.props.navigation.addListener(
  53. 'blur',
  54. () =>
  55. BackHandler.removeEventListener(
  56. 'hardwareBackPress',
  57. this.onBackButtonPressAndroid
  58. )
  59. );
  60. }
  61. onBackButtonPressAndroid = () => {
  62. if (this.canGoBack) {
  63. this.onGoBackClicked();
  64. return true;
  65. }
  66. return false;
  67. };
  68. /**
  69. * Gets a header refresh button
  70. *
  71. * @return {*}
  72. */
  73. getRefreshButton() {
  74. return (
  75. <MaterialHeaderButtons>
  76. <Item
  77. title="refresh"
  78. iconName="refresh"
  79. onPress={this.onRefreshClicked}/>
  80. <HiddenItem
  81. title={i18n.t("general.goBack")}
  82. iconName="arrow-left"
  83. onPress={this.onGoBackClicked}/>
  84. <HiddenItem
  85. title={i18n.t("general.goForward")}
  86. iconName="arrow-right"
  87. onPress={this.onGoForwardClicked}/>
  88. <HiddenItem
  89. title={i18n.t("general.openInBrowser")}
  90. iconName="web"
  91. onPress={this.onOpenClicked}/>
  92. </MaterialHeaderButtons>
  93. );
  94. };
  95. /**
  96. * Callback to use when refresh button is clicked. Reloads the webview.
  97. */
  98. onRefreshClicked = () => this.webviewRef.current.getNode().reload(); // Need to call getNode() as we are working with animated components
  99. onGoBackClicked = () => this.webviewRef.current.getNode().goBack();
  100. onGoForwardClicked = () => this.webviewRef.current.getNode().goForward();
  101. onOpenClicked = () => Linking.openURL(this.props.url);
  102. injectJavaScript = (script: string) => {
  103. this.webviewRef.current.getNode().injectJavaScript(script);
  104. }
  105. /**
  106. * Gets the loading indicator
  107. *
  108. * @return {*}
  109. */
  110. getRenderLoading = () => <BasicLoadingScreen isAbsolute={true}/>;
  111. getJavascriptPadding(padding: number) {
  112. return (
  113. "document.getElementsByTagName('body')[0].style.paddingTop = '" + padding + "px';" +
  114. "true;"
  115. );
  116. }
  117. render() {
  118. const {containerPaddingTop, onScrollWithListener} = this.props.collapsibleStack;
  119. return (
  120. <AnimatedWebView
  121. ref={this.webviewRef}
  122. source={{uri: this.props.url}}
  123. startInLoadingState={true}
  124. injectedJavaScript={this.props.customJS}
  125. javaScriptEnabled={true}
  126. renderLoading={this.getRenderLoading}
  127. renderError={() => <ErrorView
  128. errorCode={ERROR_TYPE.CONNECTION_ERROR}
  129. onRefresh={this.onRefreshClicked}
  130. />}
  131. onNavigationStateChange={navState => {
  132. this.canGoBack = navState.canGoBack;
  133. }}
  134. onMessage={this.props.onMessage}
  135. onLoad={() => this.injectJavaScript(this.getJavascriptPadding(containerPaddingTop))}
  136. // Animations
  137. onScroll={onScrollWithListener(this.props.onScroll)}
  138. />
  139. );
  140. }
  141. }
  142. export default withCollapsible(WebViewScreen);