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.

ProxiwashListItem.tsx 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. * Copyright (c) 2019 - 2020 Arnaud Vergnet.
  3. *
  4. * This file is part of Campus INSAT.
  5. *
  6. * Campus INSAT is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Campus INSAT is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import * as React from 'react';
  20. import {
  21. Avatar,
  22. Caption,
  23. List,
  24. ProgressBar,
  25. Surface,
  26. Text,
  27. withTheme,
  28. } from 'react-native-paper';
  29. import {StyleSheet, View} from 'react-native';
  30. import i18n from 'i18n-js';
  31. import * as Animatable from 'react-native-animatable';
  32. import ProxiwashConstants, {
  33. MachineStates,
  34. } from '../../../constants/ProxiwashConstants';
  35. import AprilFoolsManager from '../../../managers/AprilFoolsManager';
  36. import type {ProxiwashMachineType} from '../../../screens/Proxiwash/ProxiwashScreen';
  37. type PropsType = {
  38. item: ProxiwashMachineType;
  39. theme: ReactNativePaper.Theme;
  40. onPress: (
  41. title: string,
  42. item: ProxiwashMachineType,
  43. isDryer: boolean,
  44. ) => void;
  45. isWatched: boolean;
  46. isDryer: boolean;
  47. height: number;
  48. };
  49. const AnimatedIcon = Animatable.createAnimatableComponent(Avatar.Icon);
  50. const styles = StyleSheet.create({
  51. container: {
  52. margin: 5,
  53. justifyContent: 'center',
  54. elevation: 1,
  55. },
  56. icon: {
  57. backgroundColor: 'transparent',
  58. },
  59. progressBar: {
  60. position: 'absolute',
  61. left: 0,
  62. borderRadius: 4,
  63. },
  64. });
  65. /**
  66. * Component used to display a proxiwash item, showing machine progression and state
  67. */
  68. class ProxiwashListItem extends React.Component<PropsType> {
  69. static stateStrings: {[key in MachineStates]: string} = {
  70. [MachineStates.AVAILABLE]: i18n.t('screens.proxiwash.states.ready'),
  71. [MachineStates.RUNNING]: i18n.t('screens.proxiwash.states.running'),
  72. [MachineStates.RUNNING_NOT_STARTED]: i18n.t(
  73. 'screens.proxiwash.states.runningNotStarted',
  74. ),
  75. [MachineStates.FINISHED]: i18n.t('screens.proxiwash.states.finished'),
  76. [MachineStates.UNAVAILABLE]: i18n.t('screens.proxiwash.states.broken'),
  77. [MachineStates.ERROR]: i18n.t('screens.proxiwash.states.error'),
  78. [MachineStates.UNKNOWN]: i18n.t('screens.proxiwash.states.unknown'),
  79. };
  80. stateColors: {[key: string]: string};
  81. title: string;
  82. titlePopUp: string;
  83. constructor(props: PropsType) {
  84. super(props);
  85. this.stateColors = {};
  86. let displayNumber = props.item.number;
  87. const displayMaxWeight = props.item.maxWeight;
  88. if (AprilFoolsManager.getInstance().isAprilFoolsEnabled()) {
  89. displayNumber = AprilFoolsManager.getProxiwashMachineDisplayNumber(
  90. parseInt(props.item.number, 10),
  91. );
  92. }
  93. this.title = props.isDryer
  94. ? i18n.t('screens.proxiwash.dryer')
  95. : i18n.t('screens.proxiwash.washer');
  96. this.title += ` n°${displayNumber}`;
  97. this.titlePopUp = `${this.title} - ${displayMaxWeight} kg`;
  98. }
  99. shouldComponentUpdate(nextProps: PropsType): boolean {
  100. const {props} = this;
  101. return (
  102. nextProps.theme.dark !== props.theme.dark ||
  103. nextProps.item.state !== props.item.state ||
  104. nextProps.item.donePercent !== props.item.donePercent ||
  105. nextProps.isWatched !== props.isWatched
  106. );
  107. }
  108. onListItemPress = () => {
  109. const {props} = this;
  110. props.onPress(this.titlePopUp, props.item, props.isDryer);
  111. };
  112. updateStateColors() {
  113. const {props} = this;
  114. const {colors} = props.theme;
  115. this.stateColors[MachineStates.AVAILABLE] = colors.proxiwashReadyColor;
  116. this.stateColors[MachineStates.RUNNING] = colors.proxiwashRunningColor;
  117. this.stateColors[MachineStates.RUNNING_NOT_STARTED] =
  118. colors.proxiwashRunningNotStartedColor;
  119. this.stateColors[MachineStates.FINISHED] = colors.proxiwashFinishedColor;
  120. this.stateColors[MachineStates.UNAVAILABLE] = colors.proxiwashBrokenColor;
  121. this.stateColors[MachineStates.ERROR] = colors.proxiwashErrorColor;
  122. this.stateColors[MachineStates.UNKNOWN] = colors.proxiwashUnknownColor;
  123. }
  124. render() {
  125. const {props} = this;
  126. const {colors} = props.theme;
  127. const machineState = props.item.state;
  128. const isRunning = machineState === MachineStates.RUNNING;
  129. const isReady = machineState === MachineStates.AVAILABLE;
  130. const description = isRunning
  131. ? `${props.item.startTime}/${props.item.endTime}`
  132. : '';
  133. const stateIcon = ProxiwashConstants.stateIcons[machineState];
  134. const stateString = ProxiwashListItem.stateStrings[machineState];
  135. let progress;
  136. if (isRunning && props.item.donePercent !== '') {
  137. progress = parseFloat(props.item.donePercent) / 100;
  138. } else if (isRunning) {
  139. progress = 0;
  140. } else {
  141. progress = 1;
  142. }
  143. const icon = props.isWatched ? (
  144. <AnimatedIcon
  145. icon="bell-ring"
  146. animation="rubberBand"
  147. useNativeDriver
  148. size={50}
  149. color={colors.primary}
  150. style={styles.icon}
  151. />
  152. ) : (
  153. <AnimatedIcon
  154. icon={props.isDryer ? 'tumble-dryer' : 'washing-machine'}
  155. animation={isRunning ? 'pulse' : undefined}
  156. iterationCount="infinite"
  157. easing="linear"
  158. duration={1000}
  159. useNativeDriver
  160. size={40}
  161. color={colors.text}
  162. style={styles.icon}
  163. />
  164. );
  165. this.updateStateColors();
  166. return (
  167. <Surface
  168. style={{
  169. ...styles.container,
  170. height: props.height,
  171. borderRadius: 4,
  172. }}>
  173. {!isReady ? (
  174. <ProgressBar
  175. style={{
  176. ...styles.progressBar,
  177. height: props.height,
  178. }}
  179. progress={progress}
  180. color={this.stateColors[machineState]}
  181. />
  182. ) : null}
  183. <List.Item
  184. title={this.title}
  185. description={description}
  186. style={{
  187. height: props.height,
  188. justifyContent: 'center',
  189. }}
  190. onPress={this.onListItemPress}
  191. left={() => icon}
  192. right={() => (
  193. <View style={{flexDirection: 'row'}}>
  194. <View style={{justifyContent: 'center'}}>
  195. <Text
  196. style={
  197. machineState === MachineStates.FINISHED
  198. ? {fontWeight: 'bold'}
  199. : {}
  200. }>
  201. {stateString}
  202. </Text>
  203. {machineState === MachineStates.RUNNING ? (
  204. <Caption>{props.item.remainingTime} min</Caption>
  205. ) : null}
  206. </View>
  207. <View style={{justifyContent: 'center'}}>
  208. <Avatar.Icon
  209. icon={stateIcon}
  210. color={colors.text}
  211. size={30}
  212. style={styles.icon}
  213. />
  214. </View>
  215. </View>
  216. )}
  217. />
  218. </Surface>
  219. );
  220. }
  221. }
  222. export default withTheme(ProxiwashListItem);