|
@@ -13,12 +13,11 @@ import ProxiwashConstants from "../../constants/ProxiwashConstants";
|
13
|
13
|
import CustomModal from "../../components/Custom/CustomModal";
|
14
|
14
|
import AprilFoolsManager from "../../managers/AprilFoolsManager";
|
15
|
15
|
import MaterialHeaderButtons, {Item} from "../../components/Custom/HeaderButton";
|
|
16
|
+import ProxiwashSectionHeader from "../../components/Lists/ProxiwashSectionHeader";
|
16
|
17
|
|
17
|
18
|
const DATA_URL = "https://etud.insa-toulouse.fr/~amicale_app/washinsa/washinsa.json";
|
18
|
19
|
|
19
|
|
-let stateStrings = {};
|
20
|
20
|
let modalStateStrings = {};
|
21
|
|
-let stateIcons = {};
|
22
|
21
|
|
23
|
22
|
const REFRESH_TIME = 1000 * 10; // Refresh every 10 seconds
|
24
|
23
|
const LIST_ITEM_HEIGHT = 64;
|
|
@@ -30,7 +29,6 @@ type Props = {
|
30
|
29
|
|
31
|
30
|
type State = {
|
32
|
31
|
refreshing: boolean,
|
33
|
|
- firstLoading: boolean,
|
34
|
32
|
modalCurrentDisplayItem: React.Node,
|
35
|
33
|
machinesWatched: Array<string>,
|
36
|
34
|
bannerVisible: boolean,
|
|
@@ -45,22 +43,12 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
45
|
43
|
|
46
|
44
|
modalRef: Object;
|
47
|
45
|
|
48
|
|
- onAboutPress: Function;
|
49
|
|
- getRenderItem: Function;
|
50
|
|
- getRenderSectionHeader: Function;
|
51
|
|
- createDataset: Function;
|
52
|
|
- onHideBanner: Function;
|
53
|
|
- onModalRef: Function;
|
54
|
|
-
|
55
|
46
|
fetchedData: Object;
|
56
|
|
- colors: Object;
|
57
|
47
|
|
58
|
48
|
state = {
|
59
|
49
|
refreshing: false,
|
60
|
|
- firstLoading: true,
|
61
|
|
- fetchedData: {},
|
62
|
|
- machinesWatched: [],
|
63
|
50
|
modalCurrentDisplayItem: null,
|
|
51
|
+ machinesWatched: [],
|
64
|
52
|
bannerVisible: AsyncStorageManager.getInstance().preferences.proxiwashShowBanner.current === '1',
|
65
|
53
|
};
|
66
|
54
|
|
|
@@ -69,53 +57,31 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
69
|
57
|
*/
|
70
|
58
|
constructor(props) {
|
71
|
59
|
super(props);
|
72
|
|
- stateStrings[ProxiwashConstants.machineStates.TERMINE] = i18n.t('proxiwashScreen.states.finished');
|
73
|
|
- stateStrings[ProxiwashConstants.machineStates.DISPONIBLE] = i18n.t('proxiwashScreen.states.ready');
|
74
|
|
- stateStrings[ProxiwashConstants.machineStates["EN COURS"]] = i18n.t('proxiwashScreen.states.running');
|
75
|
|
- stateStrings[ProxiwashConstants.machineStates.HS] = i18n.t('proxiwashScreen.states.broken');
|
76
|
|
- stateStrings[ProxiwashConstants.machineStates.ERREUR] = i18n.t('proxiwashScreen.states.error');
|
77
|
|
-
|
78
|
60
|
modalStateStrings[ProxiwashConstants.machineStates.TERMINE] = i18n.t('proxiwashScreen.modal.finished');
|
79
|
61
|
modalStateStrings[ProxiwashConstants.machineStates.DISPONIBLE] = i18n.t('proxiwashScreen.modal.ready');
|
80
|
62
|
modalStateStrings[ProxiwashConstants.machineStates["EN COURS"]] = i18n.t('proxiwashScreen.modal.running');
|
81
|
63
|
modalStateStrings[ProxiwashConstants.machineStates.HS] = i18n.t('proxiwashScreen.modal.broken');
|
82
|
64
|
modalStateStrings[ProxiwashConstants.machineStates.ERREUR] = i18n.t('proxiwashScreen.modal.error');
|
83
|
|
-
|
84
|
|
- stateIcons[ProxiwashConstants.machineStates.TERMINE] = 'check-circle';
|
85
|
|
- stateIcons[ProxiwashConstants.machineStates.DISPONIBLE] = 'radiobox-blank';
|
86
|
|
- stateIcons[ProxiwashConstants.machineStates["EN COURS"]] = 'progress-check';
|
87
|
|
- stateIcons[ProxiwashConstants.machineStates.HS] = 'alert-octagram-outline';
|
88
|
|
- stateIcons[ProxiwashConstants.machineStates.ERREUR] = 'alert';
|
89
|
|
-
|
90
|
|
- // let dataString = AsyncStorageManager.getInstance().preferences.proxiwashWatchedMachines.current;
|
91
|
|
- this.onAboutPress = this.onAboutPress.bind(this);
|
92
|
|
- this.getRenderItem = this.getRenderItem.bind(this);
|
93
|
|
- this.getRenderSectionHeader = this.getRenderSectionHeader.bind(this);
|
94
|
|
- this.createDataset = this.createDataset.bind(this);
|
95
|
|
- this.onHideBanner = this.onHideBanner.bind(this);
|
96
|
|
- this.onModalRef = this.onModalRef.bind(this);
|
97
|
|
- this.colors = props.theme.colors;
|
98
|
65
|
}
|
99
|
66
|
|
100
|
67
|
/**
|
101
|
68
|
* Callback used when closing the banner.
|
102
|
69
|
* This hides the banner and saves to preferences to prevent it from reopening
|
103
|
70
|
*/
|
104
|
|
- onHideBanner() {
|
|
71
|
+ onHideBanner = () => {
|
105
|
72
|
this.setState({bannerVisible: false});
|
106
|
73
|
AsyncStorageManager.getInstance().savePref(
|
107
|
74
|
AsyncStorageManager.getInstance().preferences.proxiwashShowBanner.key,
|
108
|
75
|
'0'
|
109
|
76
|
);
|
110
|
|
- }
|
|
77
|
+ };
|
111
|
78
|
|
112
|
79
|
/**
|
113
|
80
|
* Setup notification channel for android and add listeners to detect notifications fired
|
114
|
81
|
*/
|
115
|
82
|
componentDidMount() {
|
116
|
|
- const rightButton = this.getAboutButton.bind(this);
|
117
|
83
|
this.props.navigation.setOptions({
|
118
|
|
- headerRight: rightButton,
|
|
84
|
+ headerRight: this.getAboutButton,
|
119
|
85
|
});
|
120
|
86
|
if (AsyncStorageManager.getInstance().preferences.expoToken.current !== '') {
|
121
|
87
|
// Get latest watchlist from server
|
|
@@ -142,20 +108,17 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
142
|
108
|
* Callback used when pressing the about button.
|
143
|
109
|
* This will open the ProxiwashAboutScreen.
|
144
|
110
|
*/
|
145
|
|
- onAboutPress() {
|
146
|
|
- this.props.navigation.navigate('proxiwash-about');
|
147
|
|
- }
|
|
111
|
+ onAboutPress = () => this.props.navigation.navigate('proxiwash-about');
|
148
|
112
|
|
149
|
113
|
/**
|
150
|
114
|
* Gets the about header button
|
151
|
115
|
*
|
152
|
116
|
* @return {*}
|
153
|
117
|
*/
|
154
|
|
- getAboutButton() {
|
155
|
|
- return <MaterialHeaderButtons>
|
|
118
|
+ getAboutButton = () =>
|
|
119
|
+ <MaterialHeaderButtons>
|
156
|
120
|
<Item title="information" iconName="information" onPress={this.onAboutPress}/>
|
157
|
121
|
</MaterialHeaderButtons>;
|
158
|
|
- }
|
159
|
122
|
|
160
|
123
|
/**
|
161
|
124
|
* Extracts the key for the given item
|
|
@@ -261,7 +224,7 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
261
|
224
|
* @param fetchedData
|
262
|
225
|
* @return {*}
|
263
|
226
|
*/
|
264
|
|
- createDataset(fetchedData: Object) {
|
|
227
|
+ createDataset = (fetchedData: Object) => {
|
265
|
228
|
let data = fetchedData;
|
266
|
229
|
if (AprilFoolsManager.getInstance().isAprilFoolsEnabled()) {
|
267
|
230
|
data = JSON.parse(JSON.stringify(fetchedData)); // Deep copy
|
|
@@ -284,7 +247,7 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
284
|
247
|
keyExtractor: this.getKeyExtractor
|
285
|
248
|
},
|
286
|
249
|
];
|
287
|
|
- }
|
|
250
|
+ };
|
288
|
251
|
|
289
|
252
|
/**
|
290
|
253
|
* Shows a modal for the given item
|
|
@@ -293,14 +256,14 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
293
|
256
|
* @param item The item to display information for in the modal
|
294
|
257
|
* @param isDryer True if the given item is a dryer
|
295
|
258
|
*/
|
296
|
|
- showModal(title: string, item: Object, isDryer: boolean) {
|
|
259
|
+ showModal = (title: string, item: Object, isDryer: boolean) => {
|
297
|
260
|
this.setState({
|
298
|
261
|
modalCurrentDisplayItem: this.getModalContent(title, item, isDryer)
|
299
|
262
|
});
|
300
|
263
|
if (this.modalRef) {
|
301
|
264
|
this.modalRef.open();
|
302
|
265
|
}
|
303
|
|
- }
|
|
266
|
+ };
|
304
|
267
|
|
305
|
268
|
/**
|
306
|
269
|
* Callback used when the user clicks on enable notifications for a machine
|
|
@@ -362,7 +325,7 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
362
|
325
|
title={title}
|
363
|
326
|
left={() => <Avatar.Icon
|
364
|
327
|
icon={isDryer ? 'tumble-dryer' : 'washing-machine'}
|
365
|
|
- color={this.colors.text}
|
|
328
|
+ color={this.props.theme.colors.text}
|
366
|
329
|
style={{backgroundColor: 'transparent'}}/>}
|
367
|
330
|
|
368
|
331
|
/>
|
|
@@ -390,9 +353,9 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
390
|
353
|
*
|
391
|
354
|
* @param ref
|
392
|
355
|
*/
|
393
|
|
- onModalRef(ref: Object) {
|
|
356
|
+ onModalRef = (ref: Object) => {
|
394
|
357
|
this.modalRef = ref;
|
395
|
|
- }
|
|
358
|
+ };
|
396
|
359
|
|
397
|
360
|
/**
|
398
|
361
|
* Gets the number of machines available
|
|
@@ -420,43 +383,16 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
420
|
383
|
* @param section The section to render
|
421
|
384
|
* @return {*}
|
422
|
385
|
*/
|
423
|
|
- getRenderSectionHeader({section}: Object) {
|
|
386
|
+ getRenderSectionHeader = ({section}: Object) => {
|
424
|
387
|
const isDryer = section.title === i18n.t('proxiwashScreen.dryers');
|
425
|
388
|
const nbAvailable = this.getMachineAvailableNumber(isDryer);
|
426
|
|
- const subtitle = nbAvailable + ' ' + ((nbAvailable <= 1) ? i18n.t('proxiwashScreen.numAvailable')
|
427
|
|
- : i18n.t('proxiwashScreen.numAvailablePlural'));
|
428
|
389
|
return (
|
429
|
|
- <View style={{
|
430
|
|
- flexDirection: 'row',
|
431
|
|
- marginLeft: 5,
|
432
|
|
- marginRight: 5,
|
433
|
|
- marginBottom: 10,
|
434
|
|
- marginTop: 20,
|
435
|
|
- }}>
|
436
|
|
- <Avatar.Icon
|
437
|
|
- icon={isDryer ? 'tumble-dryer' : 'washing-machine'}
|
438
|
|
- color={this.colors.primary}
|
439
|
|
- style={{backgroundColor: 'transparent'}}
|
440
|
|
- />
|
441
|
|
- <View style={{
|
442
|
|
- justifyContent: 'center',
|
443
|
|
- }}>
|
444
|
|
- <Text style={{
|
445
|
|
- fontSize: 20,
|
446
|
|
- fontWeight: 'bold',
|
447
|
|
- }}>
|
448
|
|
- {section.title}
|
449
|
|
- </Text>
|
450
|
|
-
|
451
|
|
- <Text style={{
|
452
|
|
- color: this.colors.subtitle,
|
453
|
|
- }}>
|
454
|
|
- {subtitle}
|
455
|
|
- </Text>
|
456
|
|
- </View>
|
457
|
|
- </View>
|
|
390
|
+ <ProxiwashSectionHeader
|
|
391
|
+ title={section.title}
|
|
392
|
+ nbAvailable={nbAvailable}
|
|
393
|
+ isDryer={isDryer}/>
|
458
|
394
|
);
|
459
|
|
- }
|
|
395
|
+ };
|
460
|
396
|
|
461
|
397
|
/**
|
462
|
398
|
* Gets the list item to be rendered
|
|
@@ -465,34 +401,18 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
465
|
401
|
* @param section The object describing the current SectionList section
|
466
|
402
|
* @returns {React.Node}
|
467
|
403
|
*/
|
468
|
|
- getRenderItem({item, section}: Object) {
|
469
|
|
- const isMachineRunning = ProxiwashConstants.machineStates[item.state] === ProxiwashConstants.machineStates["EN COURS"];
|
470
|
|
- let displayNumber = item.number;
|
471
|
|
- if (AprilFoolsManager.getInstance().isAprilFoolsEnabled())
|
472
|
|
- displayNumber = AprilFoolsManager.getProxiwashMachineDisplayNumber(parseInt(item.number));
|
473
|
|
- const machineName = (section.title === i18n.t('proxiwashScreen.dryers') ?
|
474
|
|
- i18n.t('proxiwashScreen.dryer') :
|
475
|
|
- i18n.t('proxiwashScreen.washer')) + ' n°' + displayNumber;
|
|
404
|
+ getRenderItem = ({item, section}: Object) => {
|
476
|
405
|
const isDryer = section.title === i18n.t('proxiwashScreen.dryers');
|
477
|
|
- const onPress = this.showModal.bind(this, machineName, item, isDryer);
|
478
|
|
- let width = item.donePercent !== '' ? (parseInt(item.donePercent)).toString() + '%' : 0;
|
479
|
|
- if (ProxiwashConstants.machineStates[item.state] === '0')
|
480
|
|
- width = '100%';
|
481
|
406
|
return (
|
482
|
407
|
<ProxiwashListItem
|
483
|
|
- title={machineName}
|
484
|
|
- description={isMachineRunning ? item.startTime + '/' + item.endTime : ''}
|
485
|
|
- onPress={onPress}
|
486
|
|
- progress={width}
|
487
|
|
- state={item.state}
|
|
408
|
+ item={item}
|
|
409
|
+ onPress={this.showModal}
|
488
|
410
|
isWatched={this.isMachineWatched(item.number)}
|
489
|
411
|
isDryer={isDryer}
|
490
|
|
- statusText={stateStrings[ProxiwashConstants.machineStates[item.state]]}
|
491
|
|
- statusIcon={stateIcons[ProxiwashConstants.machineStates[item.state]]}
|
492
|
412
|
height={LIST_ITEM_HEIGHT}
|
493
|
413
|
/>
|
494
|
414
|
);
|
495
|
|
- }
|
|
415
|
+ };
|
496
|
416
|
|
497
|
417
|
render() {
|
498
|
418
|
const nav = this.props.navigation;
|