Application Android et IOS pour l'amicale des élèves
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.

PlanexScreen.js 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // @flow
  2. import * as React from 'react';
  3. import ThemeManager from "../../managers/ThemeManager";
  4. import WebViewScreen from "../../components/Screens/WebViewScreen";
  5. import {Avatar, Banner} from "react-native-paper";
  6. import i18n from "i18n-js";
  7. import {View} from "react-native";
  8. import AsyncStorageManager from "../../managers/AsyncStorageManager";
  9. type Props = {
  10. navigation: Object,
  11. }
  12. type State = {
  13. bannerVisible: boolean,
  14. }
  15. const PLANEX_URL = 'http://planex.insa-toulouse.fr/';
  16. const CUSTOM_CSS_GENERAL = 'https://etud.insa-toulouse.fr/~amicale_app/custom_css/planex/customMobile3.css';
  17. const CUSTOM_CSS_NIGHTMODE = 'https://etud.insa-toulouse.fr/~amicale_app/custom_css/planex/customDark2.css';
  18. // // JS + JQuery functions used to remove alpha from events. Copy paste in browser console for quick testing
  19. // // Remove alpha from given Jquery node
  20. // function removeAlpha(node) {
  21. // let bg = node.css("background-color");
  22. // if (bg.match("^rgba")) {
  23. // let a = bg.slice(5).split(',');
  24. // // Fix for tooltips with broken background
  25. // if (parseInt(a[0]) === parseInt(a[1]) && parseInt(a[1]) === parseInt(a[2]) && parseInt(a[2]) === 0) {
  26. // a[0] = a[1] = a[2] = '255';
  27. // }
  28. // let newBg ='rgb(' + a[0] + ',' + a[1] + ',' + a[2] + ')';
  29. // node.css("background-color", newBg);
  30. // }
  31. // }
  32. // // Observe for planning DOM changes
  33. // let observer = new MutationObserver(function(mutations) {
  34. // for (let i = 0; i < mutations.length; i++) {
  35. // if (mutations[i]['addedNodes'].length > 0 &&
  36. // ($(mutations[i]['addedNodes'][0]).hasClass("fc-event") || $(mutations[i]['addedNodes'][0]).hasClass("tooltiptopicevent")))
  37. // removeAlpha($(mutations[i]['addedNodes'][0]))
  38. // }
  39. // });
  40. // // observer.observe(document.querySelector(".fc-body"), {attributes: false, childList: true, characterData: false, subtree:true});
  41. // observer.observe(document.querySelector("body"), {attributes: false, childList: true, characterData: false, subtree:true});
  42. // // Run remove alpha a first time on whole planning. Useful when code injected after planning fully loaded.
  43. // $(".fc-event-container .fc-event").each(function(index) {
  44. // removeAlpha($(this));
  45. // });
  46. // Watch for changes in the calendar and call the remove alpha function
  47. const OBSERVE_MUTATIONS_INJECTED =
  48. 'function removeAlpha(node) {\n' +
  49. ' let bg = node.css("background-color");\n' +
  50. ' if (bg.match("^rgba")) {\n' +
  51. ' let a = bg.slice(5).split(\',\');\n' +
  52. ' // Fix for tooltips with broken background\n' +
  53. ' if (parseInt(a[0]) === parseInt(a[1]) && parseInt(a[1]) === parseInt(a[2]) && parseInt(a[2]) === 0) {\n' +
  54. ' a[0] = a[1] = a[2] = \'255\';\n' +
  55. ' }\n' +
  56. ' let newBg =\'rgb(\' + a[0] + \',\' + a[1] + \',\' + a[2] + \')\';\n' +
  57. ' node.css("background-color", newBg);\n' +
  58. ' }\n' +
  59. '}\n' +
  60. '// Observe for planning DOM changes\n' +
  61. 'let observer = new MutationObserver(function(mutations) {\n' +
  62. ' for (let i = 0; i < mutations.length; i++) {\n' +
  63. ' if (mutations[i][\'addedNodes\'].length > 0 &&\n' +
  64. ' ($(mutations[i][\'addedNodes\'][0]).hasClass("fc-event") || $(mutations[i][\'addedNodes\'][0]).hasClass("tooltiptopicevent")))\n' +
  65. ' removeAlpha($(mutations[i][\'addedNodes\'][0]))\n' +
  66. ' }\n' +
  67. '});\n' +
  68. '// observer.observe(document.querySelector(".fc-body"), {attributes: false, childList: true, characterData: false, subtree:true});\n' +
  69. 'observer.observe(document.querySelector("body"), {attributes: false, childList: true, characterData: false, subtree:true});\n' +
  70. '// Run remove alpha a first time on whole planning. Useful when code injected after planning fully loaded.\n' +
  71. '$(".fc-event-container .fc-event").each(function(index) {\n' +
  72. ' removeAlpha($(this));\n' +
  73. '});';
  74. /**
  75. * Class defining the app's Planex screen.
  76. * This screen uses a webview to render the page
  77. */
  78. export default class PlanexScreen extends React.Component<Props, State> {
  79. customInjectedJS: string;
  80. onHideBanner: Function;
  81. onGoToSettings: Function;
  82. state = {
  83. bannerVisible:
  84. AsyncStorageManager.getInstance().preferences.planexShowBanner.current === '1' &&
  85. AsyncStorageManager.getInstance().preferences.defaultStartScreen.current !== 'Planex',
  86. };
  87. /**
  88. * Defines custom injected JavaScript to improve the page display on mobile
  89. */
  90. constructor() {
  91. super();
  92. this.customInjectedJS =
  93. '$(document).ready(function() {' +
  94. OBSERVE_MUTATIONS_INJECTED +
  95. '$("head").append(\'<meta name="viewport" content="width=device-width, initial-scale=0.9">\');' +
  96. '$("head").append(\'<link rel="stylesheet" href="' + CUSTOM_CSS_GENERAL + '" type="text/css"/>\');';
  97. if (ThemeManager.getNightMode())
  98. this.customInjectedJS += '$("head").append(\'<link rel="stylesheet" href="' + CUSTOM_CSS_NIGHTMODE + '" type="text/css"/>\');';
  99. this.customInjectedJS +=
  100. 'removeAlpha();' +
  101. '});true;'; // Prevents crash on ios
  102. this.onHideBanner = this.onHideBanner.bind(this);
  103. this.onGoToSettings = this.onGoToSettings.bind(this);
  104. }
  105. /**
  106. * Callback used when closing the banner.
  107. * This hides the banner and saves to preferences to prevent it from reopening
  108. */
  109. onHideBanner() {
  110. this.setState({bannerVisible: false});
  111. AsyncStorageManager.getInstance().savePref(
  112. AsyncStorageManager.getInstance().preferences.planexShowBanner.key,
  113. '0'
  114. );
  115. }
  116. /**
  117. * Callback used when the used click on the navigate to settings button.
  118. * This will hide the banner and open the SettingsScreen
  119. *
  120. */
  121. onGoToSettings() {
  122. this.onHideBanner();
  123. this.props.navigation.navigate('SettingsScreen');
  124. }
  125. render() {
  126. const nav = this.props.navigation;
  127. return (
  128. <View style={{
  129. height: '100%'
  130. }}>
  131. <Banner
  132. visible={this.state.bannerVisible}
  133. actions={[
  134. {
  135. label: i18n.t('planexScreen.enableStartOK'),
  136. onPress: this.onGoToSettings,
  137. },
  138. {
  139. label: i18n.t('planexScreen.enableStartCancel'),
  140. onPress: this.onHideBanner,
  141. },
  142. ]}
  143. icon={() => <Avatar.Icon
  144. icon={'information'}
  145. size={40}
  146. />}
  147. >
  148. {i18n.t('planexScreen.enableStartScreen')}
  149. </Banner>
  150. <WebViewScreen
  151. navigation={nav}
  152. data={[
  153. {
  154. url: PLANEX_URL,
  155. icon: '',
  156. name: '',
  157. customJS: this.customInjectedJS
  158. },
  159. ]}
  160. customInjectedJS={this.customInjectedJS}
  161. headerTitle={'Planex'}
  162. hasHeaderBackButton={false}
  163. hasFooter={false}/>
  164. </View>
  165. );
  166. }
  167. }