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.

ProxiwashScreen.js 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import React from 'react';
  2. import {SectionList, RefreshControl, StyleSheet, View, ScrollView} from 'react-native';
  3. import {Badge, Body, Container, Content, Icon, Left, ListItem, Right, Text, Toast, H2, Button} from 'native-base';
  4. import CustomHeader from "../components/CustomHeader";
  5. import NotificationsManager from '../utils/NotificationsManager';
  6. import i18n from "i18n-js";
  7. import {AsyncStorage} from 'react-native'
  8. const DATA_URL = "https://etud.insa-toulouse.fr/~vergnet/appli-amicale/dataProxiwash.json";
  9. const WATCHED_MACHINES_PREFKEY = "proxiwash.watchedMachines";
  10. const remainderNotifTime = 5;
  11. const MACHINE_STATES = {
  12. TERMINE: "0",
  13. DISPONIBLE: "1",
  14. FONCTIONNE: "2",
  15. HS: "3",
  16. ERREUR: "4"
  17. };
  18. let stateStrings = {};
  19. let stateColors = {};
  20. export default class ProxiwashScreen extends React.Component {
  21. constructor(props) {
  22. super(props);
  23. stateColors[MACHINE_STATES.TERMINE] = 'rgba(54,165,22,0.4)';
  24. stateColors[MACHINE_STATES.DISPONIBLE] = '#ffffff';
  25. stateColors[MACHINE_STATES.FONCTIONNE] = 'rgba(241,237,41,0.4)';
  26. stateColors[MACHINE_STATES.HS] = '#a2a2a2';
  27. stateColors[MACHINE_STATES.ERREUR] = 'rgba(204,7,0,0.4)';
  28. stateStrings[MACHINE_STATES.TERMINE] = i18n.t('proxiwashScreen.states.finished');
  29. stateStrings[MACHINE_STATES.DISPONIBLE] = i18n.t('proxiwashScreen.states.ready');
  30. stateStrings[MACHINE_STATES.FONCTIONNE] = i18n.t('proxiwashScreen.states.running');
  31. stateStrings[MACHINE_STATES.HS] = i18n.t('proxiwashScreen.states.broken');
  32. stateStrings[MACHINE_STATES.ERREUR] = i18n.t('proxiwashScreen.states.error');
  33. this.state = {
  34. refreshing: false,
  35. data: {},
  36. machinesWatched: [],
  37. };
  38. }
  39. async readData() {
  40. try {
  41. let response = await fetch(DATA_URL);
  42. let responseJson = await response.json();
  43. // This prevents end notifications from showing
  44. // let watchList = this.state.machinesWatched;
  45. // for (let i = 0; i < watchList.length; i++) {
  46. // if (responseJson[MACHINE_STATES[watchList[i].machineNumber.state]] !== MACHINE_STATES.FONCTIONNE)
  47. // this.disableNotification(watchList[i].machineNumber);
  48. // }
  49. this.setState({
  50. data: responseJson
  51. });
  52. } catch (error) {
  53. console.error(error);
  54. }
  55. }
  56. async componentWillMount() {
  57. let dataString = await AsyncStorage.getItem(WATCHED_MACHINES_PREFKEY);
  58. if (dataString === null)
  59. dataString = '[]';
  60. this.setState({machinesWatched: JSON.parse(dataString)});
  61. }
  62. componentDidMount() {
  63. this._onRefresh();
  64. }
  65. _onRefresh = () => {
  66. this.setState({refreshing: true});
  67. this.readData().then(() => {
  68. this.setState({refreshing: false});
  69. Toast.show({
  70. text: i18n.t('proxiwashScreen.listUpdated'),
  71. buttonText: 'OK',
  72. type: "success",
  73. duration: 2000
  74. })
  75. });
  76. };
  77. static getRemainingTime(startString, endString, percentDone) {
  78. let startArray = startString.split(':');
  79. let endArray = endString.split(':');
  80. let startDate = new Date();
  81. startDate.setHours(parseInt(startArray[0]), parseInt(startArray[1]), 0, 0);
  82. let endDate = new Date();
  83. endDate.setHours(parseInt(endArray[0]), parseInt(endArray[1]), 0, 0);
  84. return (((100 - percentDone) / 100) * (endDate - startDate) / (60 * 1000)).toFixed(0); // Convert milliseconds into minutes
  85. }
  86. async setupNotifications(number, remainingTime) {
  87. if (!this.isMachineWatched(number)) {
  88. let endNotifID = await NotificationsManager.scheduleNotification(
  89. i18n.t('proxiwashScreen.notifications.machineFinishedTitle'),
  90. i18n.t('proxiwashScreen.notifications.machineFinishedBody', {number: number}),
  91. new Date().getTime() + remainingTime * (60 * 1000) // Convert back to milliseconds
  92. );
  93. let remainderNotifID = undefined;
  94. if (remainingTime > remainderNotifTime) {
  95. remainderNotifID = await NotificationsManager.scheduleNotification(
  96. i18n.t('proxiwashScreen.notifications.machineRunningTitle', {time: remainderNotifTime}),
  97. i18n.t('proxiwashScreen.notifications.machineRunningBody', {number: number}),
  98. new Date().getTime() + (remainingTime - remainderNotifTime) * (60 * 1000) // Convert back to milliseconds
  99. );
  100. }
  101. let data = this.state.machinesWatched;
  102. data.push({machineNumber: number, endNotifID: endNotifID, remainderNotifID: remainderNotifID});
  103. this.setState({machinesWatched: data});
  104. AsyncStorage.setItem(WATCHED_MACHINES_PREFKEY, JSON.stringify(data));
  105. } else
  106. this.disableNotification(number);
  107. }
  108. disableNotification(number) {
  109. let data = this.state.machinesWatched;
  110. if (data.length > 0) {
  111. let elem = this.state.machinesWatched.find(function (elem) {
  112. return elem.machineNumber === number
  113. });
  114. let arrayIndex = data.indexOf(elem);
  115. NotificationsManager.cancelScheduledNoification(data[arrayIndex].endNotifID);
  116. if (data[arrayIndex].remainderNotifID !== undefined)
  117. NotificationsManager.cancelScheduledNoification(data[arrayIndex].remainderNotifID);
  118. data.splice(arrayIndex, 1);
  119. this.setState({machinesWatched: data});
  120. AsyncStorage.setItem(WATCHED_MACHINES_PREFKEY, JSON.stringify(data));
  121. }
  122. }
  123. isMachineWatched(number) {
  124. return this.state.machinesWatched.find(function (elem) {
  125. return elem.machineNumber === number
  126. }) !== undefined;
  127. }
  128. renderItem(item, section, data) {
  129. return (
  130. <ListItem
  131. thumbnail
  132. style={{
  133. marginLeft: 0,
  134. backgroundColor: stateColors[MACHINE_STATES[item.state]]
  135. }}
  136. >
  137. <View style={{
  138. height: '100%',
  139. position: 'absolute',
  140. alignSelf: 'flex-end',
  141. right: 0,
  142. width: item.donePercent !== '' ? (100 - parseInt(item.donePercent)).toString() + '%' : 0,
  143. backgroundColor: '#fff'
  144. }}>
  145. </View>
  146. <Left>
  147. <Icon name={section.title === data[0].title ? 'tumble-dryer' : 'washing-machine'}
  148. type={'MaterialCommunityIcons'}
  149. style={{fontSize: 30, width: 30}}
  150. />
  151. </Left>
  152. <Body>
  153. <Text>
  154. {section.title === data[0].title ? i18n.t('proxiwashScreen.dryer') : i18n.t('proxiwashScreen.washer')} n°{item.number}
  155. </Text>
  156. <Text note>
  157. {item.startTime !== '' ? item.startTime + '/' + item.endTime : ''}
  158. </Text>
  159. </Body>
  160. <Right>
  161. {item.startTime !== '' ?
  162. <Button
  163. style={this.isMachineWatched(item.number) ?
  164. {backgroundColor: '#ba7c1f'} : {}}
  165. onPress={() => {
  166. this.setupNotifications(item.number, ProxiwashScreen.getRemainingTime(item.startTime, item.endTime, item.donePercent))
  167. }}>
  168. <Text>
  169. {ProxiwashScreen.getRemainingTime(item.startTime, item.endTime, item.donePercent) + ' ' + i18n.t('proxiwashScreen.min')}
  170. </Text>
  171. <Icon name={this.isMachineWatched(item.number) ? 'bell-ring' : 'bell'}
  172. type={'MaterialCommunityIcons'}
  173. style={{fontSize: 30, width: 30}}
  174. />
  175. </Button>
  176. : <Text style={MACHINE_STATES[item.state] === MACHINE_STATES.TERMINE ?
  177. {fontWeight: 'bold'} : {}}
  178. >{stateStrings[MACHINE_STATES[item.state]]}</Text>
  179. }
  180. </Right>
  181. </ListItem>);
  182. }
  183. render() {
  184. const nav = this.props.navigation;
  185. const data = [
  186. {
  187. title: i18n.t('proxiwashScreen.dryers'),
  188. data: this.state.data.dryers === undefined ? [] : this.state.data.dryers,
  189. extraData: this.state
  190. },
  191. {
  192. title: i18n.t('proxiwashScreen.washers'),
  193. data: this.state.data.washers === undefined ? [] : this.state.data.washers,
  194. extraData: this.state
  195. },
  196. ];
  197. console.log(this.state.machinesWatched);
  198. return (
  199. <Container>
  200. <CustomHeader navigation={nav} title={'Proxiwash'}/>
  201. <SectionList
  202. sections={data}
  203. keyExtractor={(item) => item.number}
  204. refreshControl={
  205. <RefreshControl
  206. refreshing={this.state.refreshing}
  207. onRefresh={this._onRefresh}
  208. />
  209. }
  210. renderSectionHeader={({section: {title}}) => (
  211. <H2 style={{textAlign: 'center', paddingVertical: 10}}>{title}</H2>
  212. )}
  213. renderItem={({item, section}) =>
  214. this.renderItem(item, section, data)
  215. }
  216. />
  217. </Container>
  218. );
  219. }
  220. }