Browse Source

Improved documentation

Arnaud Vergnet 1 year ago
parent
commit
4cdfc607e6

+ 7
- 1
components/CustomAgenda.js View File

@@ -2,8 +2,14 @@ import * as React from 'react';
2 2
 import {withTheme} from 'react-native-paper';
3 3
 import {Agenda} from "react-native-calendars";
4 4
 
5
+/**
6
+ * Abstraction layer for Agenda component, using custom configuration
7
+ *
8
+ * @param props Props to pass to the element. Must specify an onRef prop to get an Agenda ref.
9
+ * @return {*}
10
+ */
5 11
 function CustomAgenda(props) {
6
-    const { colors } = props.theme;
12
+    const {colors} = props.theme;
7 13
     return (
8 14
         <Agenda
9 15
             {...props}

+ 35
- 31
components/CustomIntroSlider.js View File

@@ -9,47 +9,24 @@ import i18n from 'i18n-js';
9 9
 import AppIntroSlider from "react-native-app-intro-slider";
10 10
 import Update from "../constants/Update";
11 11
 
12
-// Content to be used int the intro slides
13
-
14
-const styles = StyleSheet.create({
15
-    mainContent: {
16
-        flex: 1,
17
-        alignItems: 'center',
18
-        justifyContent: 'center',
19
-        paddingBottom: 100
20
-    },
21
-    image: {
22
-        width: 300,
23
-        height: 300,
24
-        marginBottom: -50,
25
-    },
26
-    text: {
27
-        color: 'rgba(255, 255, 255, 0.8)',
28
-        backgroundColor: 'transparent',
29
-        textAlign: 'center',
30
-        paddingHorizontal: 16,
31
-    },
32
-    title: {
33
-        fontSize: 22,
34
-        color: 'white',
35
-        backgroundColor: 'transparent',
36
-        textAlign: 'center',
37
-        marginBottom: 16,
38
-    },
39
-});
40
-
41 12
 type Props = {
42 13
     onDone: Function,
43 14
     isUpdate: boolean,
44 15
     isAprilFools: boolean,
45 16
 };
46 17
 
18
+/**
19
+ * Class used to create intro slides
20
+ */
47 21
 export default class CustomIntroSlider extends React.Component<Props> {
48 22
 
49 23
     introSlides: Array<Object>;
50 24
     updateSlides: Array<Object>;
51 25
     aprilFoolsSlides: Array<Object>;
52 26
 
27
+    /**
28
+     * Generates intro slides
29
+     */
53 30
     constructor() {
54 31
         super();
55 32
         this.introSlides = [
@@ -126,8 +103,9 @@ export default class CustomIntroSlider extends React.Component<Props> {
126 103
 
127 104
     /**
128 105
      * Render item to be used for the intro introSlides
129
-     * @param item
130
-     * @param dimensions
106
+     *
107
+     * @param item The item to be displayed
108
+     * @param dimensions Dimensions of the item
131 109
      */
132 110
     static getIntroRenderItem({item, dimensions}: Object) {
133 111
 
@@ -178,3 +156,29 @@ export default class CustomIntroSlider extends React.Component<Props> {
178 156
 }
179 157
 
180 158
 
159
+const styles = StyleSheet.create({
160
+    mainContent: {
161
+        flex: 1,
162
+        alignItems: 'center',
163
+        justifyContent: 'center',
164
+        paddingBottom: 100
165
+    },
166
+    image: {
167
+        width: 300,
168
+        height: 300,
169
+        marginBottom: -50,
170
+    },
171
+    text: {
172
+        color: 'rgba(255, 255, 255, 0.8)',
173
+        backgroundColor: 'transparent',
174
+        textAlign: 'center',
175
+        paddingHorizontal: 16,
176
+    },
177
+    title: {
178
+        fontSize: 22,
179
+        color: 'white',
180
+        backgroundColor: 'transparent',
181
+        textAlign: 'center',
182
+        marginBottom: 16,
183
+    },
184
+});

+ 7
- 1
components/CustomModal.js View File

@@ -4,8 +4,14 @@ import * as React from 'react';
4 4
 import {withTheme} from 'react-native-paper';
5 5
 import {Modalize} from "react-native-modalize";
6 6
 
7
+/**
8
+ * Abstraction layer for Modalize component, using custom configuration
9
+ *
10
+ * @param props Props to pass to the element. Must specify an onRef prop to get an Modalize ref.
11
+ * @return {*}
12
+ */
7 13
 function CustomModal(props) {
8
-    const { colors } = props.theme;
14
+    const {colors} = props.theme;
9 15
     return (
10 16
         <Modalize
11 17
             ref={props.onRef}

+ 26
- 13
components/EmptyWebSectionListItem.js View File

@@ -1,19 +1,19 @@
1 1
 import * as React from 'react';
2 2
 import {ActivityIndicator, Subheading, withTheme} from 'react-native-paper';
3
-import {View} from "react-native";
3
+import {StyleSheet, View} from "react-native";
4 4
 import {MaterialCommunityIcons} from "@expo/vector-icons";
5 5
 
6
-function EmptyWebSectionListItem(props) {
7
-    const { colors } = props.theme;
6
+/**
7
+ * Component used to display a message when a list is empty
8
+ *
9
+ * @param props Props to pass to the component
10
+ * @return {*}
11
+ */
12
+function EmptyWebSectionListItem(props: { text: string, icon: string, refreshing: boolean, theme: {} }) {
13
+    const {colors} = props.theme;
8 14
     return (
9 15
         <View>
10
-            <View style={{
11
-                justifyContent: 'center',
12
-                alignItems: 'center',
13
-                width: '100%',
14
-                height: 100,
15
-                marginBottom: 20
16
-            }}>
16
+            <View style={styles.iconContainer}>
17 17
                 {props.refreshing ?
18 18
                     <ActivityIndicator
19 19
                         animating={true}
@@ -27,9 +27,7 @@ function EmptyWebSectionListItem(props) {
27 27
             </View>
28 28
 
29 29
             <Subheading style={{
30
-                textAlign: 'center',
31
-                marginRight: 20,
32
-                marginLeft: 20,
30
+                ...styles.subheading,
33 31
                 color: colors.textDisabled
34 32
             }}>
35 33
                 {props.text}
@@ -38,4 +36,19 @@ function EmptyWebSectionListItem(props) {
38 36
     );
39 37
 }
40 38
 
39
+const styles = StyleSheet.create({
40
+    iconContainer: {
41
+        justifyContent: 'center',
42
+        alignItems: 'center',
43
+        width: '100%',
44
+        height: 100,
45
+        marginBottom: 20
46
+    },
47
+    subheading: {
48
+        textAlign: 'center',
49
+        marginRight: 20,
50
+        marginLeft: 20,
51
+    }
52
+});
53
+
41 54
 export default withTheme(EmptyWebSectionListItem);

+ 22
- 8
components/EventDashboardItem.js View File

@@ -2,7 +2,14 @@
2 2
 
3 3
 import * as React from 'react';
4 4
 import {Avatar, Card, withTheme} from 'react-native-paper';
5
+import {StyleSheet} from "react-native";
5 6
 
7
+/**
8
+ * Component used to display a dashboard item containing a preview event
9
+ *
10
+ * @param props Props to pass to the component
11
+ * @return {*}
12
+ */
6 13
 function EventDashBoardItem(props) {
7 14
     const {colors} = props.theme;
8 15
     const iconColor = props.isAvailable ?
@@ -13,13 +20,7 @@ function EventDashBoardItem(props) {
13 20
         colors.textDisabled;
14 21
     return (
15 22
         <Card
16
-            style={{
17
-                width: 'auto',
18
-                marginLeft: 10,
19
-                marginRight: 10,
20
-                marginTop: 10,
21
-                overflow: 'hidden',
22
-            }}
23
+            style={styles.card}
23 24
             onPress={props.clickAction}>
24 25
 
25 26
             <Card.Title
@@ -32,7 +33,7 @@ function EventDashBoardItem(props) {
32 33
                         icon={props.icon}
33 34
                         color={iconColor}
34 35
                         size={60}
35
-                        style={{backgroundColor: 'transparent'}}/>}
36
+                        style={styles.avatar}/>}
36 37
             />
37 38
             <Card.Content>
38 39
                 {props.children}
@@ -41,4 +42,17 @@ function EventDashBoardItem(props) {
41 42
     );
42 43
 }
43 44
 
45
+const styles = StyleSheet.create({
46
+    card: {
47
+        width: 'auto',
48
+        marginLeft: 10,
49
+        marginRight: 10,
50
+        marginTop: 10,
51
+        overflow: 'hidden',
52
+    },
53
+    avatar: {
54
+        backgroundColor: 'transparent'
55
+    }
56
+});
57
+
44 58
 export default withTheme(EventDashBoardItem);

+ 14
- 1
components/FeedItem.js View File

@@ -6,6 +6,11 @@ import i18n from "i18n-js";
6 6
 
7 7
 const ICON_AMICALE = require('../assets/amicale.png');
8 8
 
9
+/**
10
+ * Gets the amicale INSAT logo
11
+ *
12
+ * @return {*}
13
+ */
9 14
 function getAvatar() {
10 15
     return (
11 16
         <Avatar.Image size={48} source={ICON_AMICALE}
@@ -13,6 +18,12 @@ function getAvatar() {
13 18
     );
14 19
 }
15 20
 
21
+/**
22
+ * Component used to display a feed item
23
+ *
24
+ * @param props Props to pass to the component
25
+ * @return {*}
26
+ */
16 27
 function FeedItem(props) {
17 28
     const {colors} = props.theme;
18 29
     return (
@@ -39,7 +50,9 @@ function FeedItem(props) {
39 50
                 <Button
40 51
                     color={'#57aeff'}
41 52
                     onPress={props.onOutLinkPress}
42
-                    icon={'facebook'}>{i18n.t('homeScreen.dashboard.seeMore')}</Button>
53
+                    icon={'facebook'}>
54
+                    {i18n.t('homeScreen.dashboard.seeMore')}
55
+                </Button>
43 56
             </Card.Actions>
44 57
         </Card>
45 58
     );

+ 7
- 1
components/HeaderButton.js View File

@@ -1,8 +1,14 @@
1 1
 import * as React from 'react';
2 2
 import {IconButton, withTheme} from 'react-native-paper';
3 3
 
4
+/**
5
+ * Component used to display a header button
6
+ *
7
+ * @param props Props to pass to the component
8
+ * @return {*}
9
+ */
4 10
 function HeaderButton(props) {
5
-    const { colors } = props.theme;
11
+    const {colors} = props.theme;
6 12
     return (
7 13
         <IconButton
8 14
             icon={props.icon}

+ 33
- 14
components/PreviewEventDashboardItem.js View File

@@ -1,25 +1,33 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {View} from "react-native";
4
+import {StyleSheet, View} from "react-native";
5 5
 import HTML from "react-native-render-html";
6 6
 import i18n from "i18n-js";
7 7
 import {Avatar, Button, Card, withTheme} from 'react-native-paper';
8 8
 import PlanningEventManager from "../utils/PlanningEventManager";
9 9
 
10
-
10
+/**
11
+ * Component used to display an event preview if an event is available
12
+ *
13
+ * @param props Props to pass to the component
14
+ * @return {*}
15
+ */
11 16
 function PreviewEventDashboardItem(props) {
12 17
     const {colors} = props.theme;
13
-    const isEmpty = props.event === undefined ? true : PlanningEventManager.isDescriptionEmpty(props.event['description']);
18
+    const isEmpty = props.event === undefined
19
+        ? true
20
+        : PlanningEventManager.isDescriptionEmpty(props.event['description']);
21
+
14 22
     if (props.event !== undefined && props.event !== null) {
15 23
         const hasImage = props.event['logo'] !== '' && props.event['logo'] !== null;
16 24
         const getImage = () => <Avatar.Image
17 25
             source={{uri: props.event['logo']}}
18 26
             size={50}
19
-            style={{backgroundColor: 'transparent'}}/>;
27
+            style={styles.avatar}/>;
20 28
         return (
21 29
             <Card
22
-                style={{marginBottom: 10}}
30
+                style={styles.card}
23 31
                 onPress={props.clickAction}
24 32
                 elevation={3}
25 33
             >
@@ -34,10 +42,7 @@ function PreviewEventDashboardItem(props) {
34 42
                         subtitle={PlanningEventManager.getFormattedEventTime(props.event['date_begin'], props.event['date_end'])}
35 43
                     />}
36 44
                 {!isEmpty ?
37
-                    <Card.Content style={{
38
-                        maxHeight: 150,
39
-                        overflow: 'hidden',
40
-                    }}>
45
+                    <Card.Content style={styles.content}>
41 46
                         <HTML html={"<div>" + props.event['description'] + "</div>"}
42 47
                               tagsStyles={{
43 48
                                   p: {color: colors.text,},
@@ -46,11 +51,7 @@ function PreviewEventDashboardItem(props) {
46 51
 
47 52
                     </Card.Content> : null}
48 53
 
49
-                <Card.Actions style={{
50
-                    marginLeft: 'auto',
51
-                    marginTop: 'auto',
52
-                    flexDirection: 'row'
53
-                }}>
54
+                <Card.Actions style={styles.actions}>
54 55
                     <Button
55 56
                         icon={'chevron-right'}
56 57
                     >
@@ -63,4 +64,22 @@ function PreviewEventDashboardItem(props) {
63 64
         return <View/>
64 65
 }
65 66
 
67
+const styles = StyleSheet.create({
68
+    card: {
69
+        marginBottom: 10
70
+    },
71
+    content: {
72
+        maxHeight: 150,
73
+        overflow: 'hidden',
74
+    },
75
+    actions: {
76
+        marginLeft: 'auto',
77
+        marginTop: 'auto',
78
+        flexDirection: 'row'
79
+    },
80
+    avatar: {
81
+        backgroundColor: 'transparent'
82
+    }
83
+});
84
+
66 85
 export default withTheme(PreviewEventDashboardItem);

+ 38
- 21
components/ProxiwashListItem.js View File

@@ -1,8 +1,14 @@
1 1
 import * as React from 'react';
2 2
 import {Avatar, Card, Text, withTheme} from 'react-native-paper';
3
-import {View} from "react-native";
3
+import {StyleSheet, View} from "react-native";
4 4
 import ProxiwashConstants from "../constants/ProxiwashConstants";
5 5
 
6
+/**
7
+ * Component used to display a proxiwash item, showing machine progression and state
8
+ *
9
+ * @param props Props to pass to the component
10
+ * @return {*}
11
+ */
6 12
 function ProxiwashListItem(props) {
7 13
     const {colors} = props.theme;
8 14
     let stateColors = {};
@@ -17,13 +23,13 @@ function ProxiwashListItem(props) {
17 23
                 icon={'bell-ring'}
18 24
                 size={45}
19 25
                 color={colors.primary}
20
-                style={{backgroundColor: 'transparent'}}
26
+                style={styles.icon}
21 27
             /> :
22 28
             <Avatar.Icon
23 29
                 icon={props.isDryer ? 'tumble-dryer' : 'washing-machine'}
24 30
                 color={colors.text}
25 31
                 size={40}
26
-                style={{backgroundColor: 'transparent'}}
32
+                style={styles.icon}
27 33
             />
28 34
     );
29 35
     return (
@@ -35,37 +41,26 @@ function ProxiwashListItem(props) {
35 41
         >
36 42
             {ProxiwashConstants.machineStates[props.state] === ProxiwashConstants.machineStates["EN COURS"] ?
37 43
                 <Card style={{
38
-                    height: '100%',
39
-                    position: 'absolute',
40
-                    left: 0,
41
-                    width: '100%',
44
+                    ...styles.backgroundCard,
42 45
                     backgroundColor: colors.proxiwashRunningBgColor,
43
-                    elevation: 0
46
+
44 47
                 }}/> : null
45 48
             }
46 49
 
47 50
             <Card style={{
48
-                height: '100%',
49
-                position: 'absolute',
50
-                left: 0,
51
+                ...styles.progressionCard,
51 52
                 width: props.progress,
52 53
                 backgroundColor: stateColors[ProxiwashConstants.machineStates[props.state]],
53
-                elevation: 0
54 54
             }}/>
55 55
             <Card.Title
56 56
                 title={props.title}
57 57
                 titleStyle={{fontSize: 17}}
58 58
                 subtitle={props.description}
59
-                style={{
60
-                    backgroundColor: 'transparent',
61
-                    height: 64
62
-                }}
59
+                style={styles.title}
63 60
                 left={() => icon}
64 61
                 right={() => (
65 62
                     <View style={{flexDirection: 'row'}}>
66
-                        <View style={{
67
-                            justifyContent: 'center',
68
-                        }}>
63
+                        <View style={{justifyContent: 'center'}}>
69 64
                             <Text style={
70 65
                                 ProxiwashConstants.machineStates[props.state] === ProxiwashConstants.machineStates.TERMINE ?
71 66
                                     {fontWeight: 'bold',} : {}}
@@ -73,12 +68,11 @@ function ProxiwashListItem(props) {
73 68
                                 {props.statusText}
74 69
                             </Text>
75 70
                         </View>
76
-
77 71
                         <Avatar.Icon
78 72
                             icon={props.statusIcon}
79 73
                             color={colors.text}
80 74
                             size={30}
81
-                            style={{backgroundColor: 'transparent'}}
75
+                            style={styles.icon}
82 76
                         />
83 77
                     </View>)}
84 78
             />
@@ -86,4 +80,27 @@ function ProxiwashListItem(props) {
86 80
     );
87 81
 }
88 82
 
83
+const styles = StyleSheet.create({
84
+    icon: {
85
+        backgroundColor: 'transparent'
86
+    },
87
+    backgroundCard: {
88
+        height: '100%',
89
+        position: 'absolute',
90
+        left: 0,
91
+        width: '100%',
92
+        elevation: 0,
93
+    },
94
+    progressionCard: {
95
+        height: '100%',
96
+        position: 'absolute',
97
+        left: 0,
98
+        elevation: 0,
99
+    },
100
+    title: {
101
+        backgroundColor: 'transparent',
102
+        height: 64
103
+    }
104
+});
105
+
89 106
 export default withTheme(ProxiwashListItem);

+ 3
- 1
components/PureFlatList.js View File

@@ -9,10 +9,12 @@ type Props = {
9 9
 }
10 10
 
11 11
 /**
12
+ * FlatList implementing PureComponent for increased performance.
13
+ *
12 14
  * This is a pure component, meaning it will only update if a shallow comparison of state and props is different.
13 15
  * To force the component to update, change the value of updateData.
14 16
  */
15
-export default class PureFlatList extends React.PureComponent<Props>{
17
+export default class PureFlatList extends React.PureComponent<Props> {
16 18
 
17 19
     static defaultProps = {
18 20
         updateData: null,

+ 21
- 5
components/Sidebar.js View File

@@ -20,7 +20,7 @@ type State = {
20 20
 };
21 21
 
22 22
 /**
23
- * Class used to define a navigation drawer
23
+ * Component used to render the drawer menu content
24 24
  */
25 25
 export default class SideBar extends React.PureComponent<Props, State> {
26 26
 
@@ -33,7 +33,7 @@ export default class SideBar extends React.PureComponent<Props, State> {
33 33
     getRenderItem: Function;
34 34
 
35 35
     /**
36
-     * Generate the datasets
36
+     * Generate the dataset
37 37
      *
38 38
      * @param props
39 39
      */
@@ -123,6 +123,12 @@ export default class SideBar extends React.PureComponent<Props, State> {
123 123
         this.getRenderItem = this.getRenderItem.bind(this);
124 124
     }
125 125
 
126
+    /**
127
+     * Callback when a drawer item is pressed.
128
+     * It will either navigate to the associated screen, or open the browser to the associated link
129
+     *
130
+     * @param item The item pressed
131
+     */
126 132
     onListItemPress(item: Object) {
127 133
         if (item.link === undefined)
128 134
             this.props.navigation.navigate(item.route);
@@ -130,12 +136,22 @@ export default class SideBar extends React.PureComponent<Props, State> {
130 136
             WebBrowser.openBrowserAsync(item.link);
131 137
     }
132 138
 
133
-
134
-    listKeyExtractor(item: Object) {
139
+    /**
140
+     * Key extractor for list items
141
+     *
142
+     * @param item The item to extract the key from
143
+     * @return {string} The extracted key
144
+     */
145
+    listKeyExtractor(item: Object): string {
135 146
         return item.route;
136 147
     }
137 148
 
138
-
149
+    /**
150
+     * Gets the render item for the given list item
151
+     *
152
+     * @param item The item to render
153
+     * @return {*}
154
+     */
139 155
     getRenderItem({item}: Object) {
140 156
         const onListItemPress = this.onListItemPress.bind(this, item);
141 157
         if (item.icon !== undefined) {

+ 8
- 2
components/SidebarDivider.js View File

@@ -1,9 +1,15 @@
1 1
 import * as React from 'react';
2
-import { withTheme } from 'react-native-paper';
2
+import {withTheme} from 'react-native-paper';
3 3
 import {DrawerItem} from "@react-navigation/drawer";
4 4
 
5
+/**
6
+ * Component used to render a drawer menu item divider
7
+ *
8
+ * @param props Props to pass to the component
9
+ * @return {*}
10
+ */
5 11
 function SidebarDivider(props) {
6
-    const { colors } = props.theme;
12
+    const {colors} = props.theme;
7 13
     return (
8 14
         <DrawerItem
9 15
             label={props.title}

+ 6
- 0
components/SidebarItem.js View File

@@ -3,6 +3,12 @@ import {withTheme} from 'react-native-paper';
3 3
 import {DrawerItem} from "@react-navigation/drawer";
4 4
 import {MaterialCommunityIcons} from "@expo/vector-icons";
5 5
 
6
+/**
7
+ * Component used to render a drawer menu item
8
+ *
9
+ * @param props Props to pass to the component
10
+ * @return {*}
11
+ */
6 12
 function SidebarItem(props) {
7 13
     const {colors} = props.theme;
8 14
     return (

+ 12
- 5
components/SquareDashboardItem.js View File

@@ -2,6 +2,12 @@ import * as React from 'react';
2 2
 import {Badge, IconButton, withTheme} from 'react-native-paper';
3 3
 import {View} from "react-native";
4 4
 
5
+/**
6
+ * Component used to render a small dashboard item
7
+ *
8
+ * @param props Props to pass to the component
9
+ * @return {*}
10
+ */
5 11
 function SquareDashboardItem(props) {
6 12
     const {colors} = props.theme;
7 13
     return (
@@ -9,9 +15,9 @@ function SquareDashboardItem(props) {
9 15
             <IconButton
10 16
                 icon={props.icon}
11 17
                 color={
12
-                    props.isAvailable ?
13
-                        props.color :
14
-                        colors.textDisabled
18
+                    props.isAvailable
19
+                        ? props.color
20
+                        : colors.textDisabled
15 21
                 }
16 22
                 size={35}
17 23
                 onPress={props.clickAction}
@@ -23,9 +29,10 @@ function SquareDashboardItem(props) {
23 29
                             position: 'absolute',
24 30
                             top: 5,
25 31
                             right: 5
26
-                        }}>{props.badgeNumber}</Badge> : null
32
+                        }}>
33
+                        {props.badgeNumber}
34
+                    </Badge> : null
27 35
             }
28
-
29 36
         </View>
30 37
     );
31 38
 }

+ 47
- 8
components/WebSectionList.js View File

@@ -27,8 +27,10 @@ type State = {
27 27
 };
28 28
 
29 29
 
30
-const MIN_REFRESH_TIME = 5  * 1000;
30
+const MIN_REFRESH_TIME = 5 * 1000;
31 31
 /**
32
+ * Component used to render a SectionList with data fetched from the web
33
+ *
32 34
  * This is a pure component, meaning it will only update if a shallow comparison of state and props is different.
33 35
  * To force the component to update, change the value of updateData.
34 36
  */
@@ -73,7 +75,7 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
73 75
     }
74 76
 
75 77
     /**
76
-     * Register react navigation events on first screen load.
78
+     * Registers react navigation events on first screen load.
77 79
      * Allows to detect when the screen is focused
78 80
      */
79 81
     componentDidMount() {
@@ -86,7 +88,7 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
86 88
     }
87 89
 
88 90
     /**
89
-     * Refresh data when focusing the screen and setup a refresh interval if asked to
91
+     * Refreshes data when focusing the screen and setup a refresh interval if asked to
90 92
      */
91 93
     onScreenFocus() {
92 94
         if (this.props.refreshOnFocus && this.lastRefresh !== undefined)
@@ -96,13 +98,19 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
96 98
     }
97 99
 
98 100
     /**
99
-     * Remove any interval on un-focus
101
+     * Removes any interval on un-focus
100 102
      */
101 103
     onScreenBlur() {
102 104
         clearInterval(this.refreshInterval);
103 105
     }
104 106
 
105 107
 
108
+    /**
109
+     * Callback used when fetch is successful.
110
+     * It will update the displayed data and stop the refresh animation
111
+     *
112
+     * @param fetchedData The newly fetched data
113
+     */
106 114
     onFetchSuccess(fetchedData: Object) {
107 115
         this.setState({
108 116
             fetchedData: fetchedData,
@@ -112,6 +120,10 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
112 120
         this.lastRefresh = new Date();
113 121
     }
114 122
 
123
+    /**
124
+     * Callback used when fetch encountered an error.
125
+     * It will reset the displayed data and show an error.
126
+     */
115 127
     onFetchError() {
116 128
         this.setState({
117 129
             fetchedData: {},
@@ -119,12 +131,10 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
119 131
             firstLoading: false
120 132
         });
121 133
         this.showSnackBar();
122
-        // this.webDataManager.showUpdateToast(this.props.updateErrorText);
123 134
     }
124 135
 
125 136
     /**
126
-     * Refresh data and show a toast if any error occurred
127
-     * @private
137
+     * Refreshes data and shows an animations while doing it
128 138
      */
129 139
     onRefresh() {
130 140
         let canRefresh;
@@ -140,10 +150,22 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
140 150
         }
141 151
     }
142 152
 
153
+    /**
154
+     * Gets an empty section header
155
+     *
156
+     * @param section The current section
157
+     * @return {*}
158
+     */
143 159
     getEmptySectionHeader({section}: Object) {
144 160
         return <View/>;
145 161
     }
146 162
 
163
+    /**
164
+     * Gets an empty render item
165
+     *
166
+     * @param item The data to display
167
+     * @return {*}
168
+     */
147 169
     getEmptyRenderItem({item}: Object) {
148 170
         return (
149 171
             <EmptyWebSectionListItem
@@ -154,6 +176,11 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
154 176
         );
155 177
     }
156 178
 
179
+    /**
180
+     * Creates an empty dataset
181
+     *
182
+     * @return {*}
183
+     */
157 184
     createEmptyDataset() {
158 185
         return [
159 186
             {
@@ -174,14 +201,26 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
174 201
         ];
175 202
     }
176 203
 
177
-    datasetKeyExtractor(item: Object) {
204
+    /**
205
+     * Extracts a key from the given item
206
+     *
207
+     * @param item The item to extract the key from
208
+     * @return {string} The extracted key
209
+     */
210
+    datasetKeyExtractor(item: Object): string {
178 211
         return item.text
179 212
     }
180 213
 
214
+    /**
215
+     * Shows the error popup
216
+     */
181 217
     showSnackBar() {
182 218
         this.setState({snackbarVisible: true})
183 219
     }
184 220
 
221
+    /**
222
+     * Hides the error popup
223
+     */
185 224
     hideSnackBar() {
186 225
         this.setState({snackbarVisible: false})
187 226
     }

+ 22
- 29
components/WebViewScreen.js View File

@@ -34,8 +34,6 @@ class WebViewScreen extends React.PureComponent<Props> {
34 34
 
35 35
     onRefreshClicked: Function;
36 36
     onWebviewRef: Function;
37
-    onGoBackWebview: Function;
38
-    onGoForwardWebview: Function;
39 37
     getRenderLoading: Function;
40 38
 
41 39
     colors: Object;
@@ -44,12 +42,13 @@ class WebViewScreen extends React.PureComponent<Props> {
44 42
         super(props);
45 43
         this.onRefreshClicked = this.onRefreshClicked.bind(this);
46 44
         this.onWebviewRef = this.onWebviewRef.bind(this);
47
-        this.onGoBackWebview = this.onGoBackWebview.bind(this);
48
-        this.onGoForwardWebview = this.onGoForwardWebview.bind(this);
49 45
         this.getRenderLoading = this.getRenderLoading.bind(this);
50 46
         this.colors = props.theme.colors;
51 47
     }
52 48
 
49
+    /**
50
+     * Creates refresh button after mounting
51
+     */
53 52
     componentDidMount() {
54 53
         const rightButton = this.getRefreshButton.bind(this);
55 54
         this.props.navigation.setOptions({
@@ -57,42 +56,37 @@ class WebViewScreen extends React.PureComponent<Props> {
57 56
         });
58 57
     }
59 58
 
60
-    getHeaderButton(clickAction: Function, icon: string) {
61
-        return (
62
-            <HeaderButton icon={icon} onPress={clickAction}/>
63
-        );
64
-    }
65
-
59
+    /**
60
+     * Gets a header refresh button
61
+     *
62
+     * @return {*}
63
+     */
66 64
     getRefreshButton() {
67
-        return (
68
-            <View style={{
69
-                flexDirection: 'row',
70
-                marginRight: 10
71
-            }}>
72
-                {this.getHeaderButton(this.onRefreshClicked, 'refresh')}
73
-            </View>
74
-        );
65
+        return <HeaderButton icon={'refresh'} onPress={this.onRefreshClicked}/>
75 66
     };
76 67
 
68
+    /**
69
+     * Callback to use when refresh button is clicked. Reloads the webview.
70
+     */
77 71
     onRefreshClicked() {
78 72
         if (this.webviewRef !== null)
79 73
             this.webviewRef.reload();
80 74
     }
81 75
 
82
-    onGoBackWebview() {
83
-        if (this.webviewRef !== null)
84
-            this.webviewRef.goBack();
85
-    }
86
-
87
-    onGoForwardWebview() {
88
-        if (this.webviewRef !== null)
89
-            this.webviewRef.goForward();
90
-    }
91
-
76
+    /**
77
+     * Callback used when receiving the webview ref. Stores the ref for later use
78
+     *
79
+     * @param ref
80
+     */
92 81
     onWebviewRef(ref: Object) {
93 82
         this.webviewRef = ref
94 83
     }
95 84
 
85
+    /**
86
+     * Gets the loading indicator
87
+     *
88
+     * @return {*}
89
+     */
96 90
     getRenderLoading() {
97 91
         return (
98 92
             <View style={{
@@ -115,7 +109,6 @@ class WebViewScreen extends React.PureComponent<Props> {
115 109
     }
116 110
 
117 111
     render() {
118
-        // console.log("rendering WebViewScreen");
119 112
         return (
120 113
             <WebView
121 114
                 ref={this.onWebviewRef}

+ 20
- 0
constants/Update.js View File

@@ -1,12 +1,31 @@
1 1
 import i18n from "i18n-js";
2 2
 
3
+/**
4
+ * Singleton used to manage update slides.
5
+ * Must be a singleton because it uses translations.
6
+ *
7
+ * Change values in this class to change the update slide.
8
+ * You will also need to update those translations:
9
+ * <ul>
10
+ *     <li>intro.updateSlide.title</li>
11
+ *     <li>intro.updateSlide.text</li>
12
+ * </ul>
13
+ */
3 14
 export default class Update {
4 15
 
16
+    // Increment the number to show the update slide
5 17
     static number = 5;
18
+    // Change the icon to be displayed on the update slide
6 19
     static icon = 'surround-sound-2-0';
7 20
 
8 21
     static instance: Update | null = null;
9 22
 
23
+    title: string;
24
+    description: string;
25
+
26
+    /**
27
+     * Init translations
28
+     */
10 29
     constructor() {
11 30
         this.title = i18n.t('intro.updateSlide.title');
12 31
         this.description = i18n.t('intro.updateSlide.text');
@@ -14,6 +33,7 @@ export default class Update {
14 33
 
15 34
     /**
16 35
      * Get this class instance or create one if none is found
36
+     *
17 37
      * @returns {Update}
18 38
      */
19 39
     static getInstance(): Update {

+ 3
- 3
utils/AsyncStorageManager.js View File

@@ -3,7 +3,7 @@
3 3
 import {AsyncStorage} from "react-native";
4 4
 
5 5
 /**
6
- * Static class used to manage preferences.
6
+ * Singleton used to manage preferences.
7 7
  * Preferences are fetched at the start of the app and saved in an instance object.
8 8
  * This allows for a synchronous access to saved data.
9 9
  */
@@ -14,7 +14,7 @@ export default class AsyncStorageManager {
14 14
 
15 15
     /**
16 16
      * Get this class instance or create one if none is found
17
-     * @returns {ThemeManager}
17
+     * @returns {AsyncStorageManager}
18 18
      */
19 19
     static getInstance(): AsyncStorageManager {
20 20
         return AsyncStorageManager.instance === null ?
@@ -113,7 +113,7 @@ export default class AsyncStorageManager {
113 113
 
114 114
     /**
115 115
      * Save the value associated to the given key to preferences.
116
-     * This updates the preferences object and saves it to AsynStorage.
116
+     * This updates the preferences object and saves it to AsyncStorage.
117 117
      *
118 118
      * @param key
119 119
      * @param val

+ 10
- 1
utils/DateManager.js View File

@@ -2,10 +2,13 @@
2 2
 
3 3
 import i18n from 'i18n-js';
4 4
 
5
+/**
6
+ * Singleton used to manage date translations.
7
+ * Translations are hardcoded as toLocaleDateString does not work on current android JS engine
8
+ */
5 9
 export default class DateManager {
6 10
     static instance: DateManager | null = null;
7 11
 
8
-    // Hard code strings as toLocaleDateString does not work on current android JS engine
9 12
     daysOfWeek = [];
10 13
     monthsOfYear = [];
11 14
 
@@ -42,6 +45,12 @@ export default class DateManager {
42 45
             DateManager.instance;
43 46
     }
44 47
 
48
+    /**
49
+     * Gets a translated string representing the given date.
50
+     *
51
+     * @param dateString The date with the format YYYY-MM-DD
52
+     * @return {string} The translated string
53
+     */
45 54
     getTranslatedDate(dateString: string) {
46 55
         let dateArray = dateString.split('-');
47 56
         let date = new Date();

+ 11
- 5
utils/NotificationsManager.js View File

@@ -49,6 +49,11 @@ export default class NotificationsManager {
49 49
         }
50 50
     }
51 51
 
52
+    /**
53
+     * Gets the machines watched from the server
54
+     *
55
+     * @param callback Function to execute with the fetched data
56
+     */
52 57
     static getMachineNotificationWatchlist(callback: Function) {
53 58
         let token = AsyncStorageManager.getInstance().preferences.expoToken.current;
54 59
         if (token !== '') {
@@ -72,10 +77,10 @@ export default class NotificationsManager {
72 77
     }
73 78
 
74 79
     /**
75
-     * Ask the server to enable/disable notifications for the specified machine
80
+     * Asks the server to enable/disable notifications for the specified machine
76 81
      *
77
-     * @param machineID
78
-     * @param isEnabled
82
+     * @param machineID The machine ID
83
+     * @param isEnabled True to enable notifications, false to disable
79 84
      */
80 85
     static setupMachineNotification(machineID: string, isEnabled: boolean) {
81 86
         let token = AsyncStorageManager.getInstance().preferences.expoToken.current;
@@ -100,8 +105,9 @@ export default class NotificationsManager {
100 105
     }
101 106
 
102 107
     /**
103
-     * Send the selected reminder time for notifications to the server
104
-     * @param time
108
+     * Sends the selected reminder time for notifications to the server
109
+     *
110
+     * @param time The reminder time to use
105 111
      */
106 112
     static setMachineReminderNotificationTime(time: number) {
107 113
         let token = AsyncStorageManager.getInstance().preferences.expoToken.current;

+ 28
- 6
utils/ThemeManager.js View File

@@ -19,7 +19,12 @@ export default class ThemeManager {
19 19
         this.updateThemeCallback = null;
20 20
     }
21 21
 
22
-    static getWhiteTheme() {
22
+    /**
23
+     * Gets the light theme
24
+     *
25
+     * @return {Object} Object containing theme variables
26
+     * */
27
+    static getWhiteTheme(): Object {
23 28
         return {
24 29
             ...DefaultTheme,
25 30
             colors: {
@@ -70,7 +75,12 @@ export default class ThemeManager {
70 75
         };
71 76
     }
72 77
 
73
-    static getDarkTheme() {
78
+    /**
79
+     * Gets the dark theme
80
+     *
81
+     * @return {Object} Object containing theme variables
82
+     * */
83
+    static getDarkTheme(): Object {
74 84
         return {
75 85
             ...DarkTheme,
76 86
             colors: {
@@ -124,6 +134,7 @@ export default class ThemeManager {
124 134
 
125 135
     /**
126 136
      * Get this class instance or create one if none is found
137
+     *
127 138
      * @returns {ThemeManager}
128 139
      */
129 140
     static getInstance(): ThemeManager {
@@ -133,6 +144,10 @@ export default class ThemeManager {
133 144
     }
134 145
 
135 146
     /**
147
+     * Gets night mode status.
148
+     * If Follow System Preferences is enabled, will first use system theme.
149
+     * If disabled or not available, will use value stored din preferences
150
+     *
136 151
      * @returns {boolean} Night mode state
137 152
      */
138 153
     static getNightMode(): boolean {
@@ -143,8 +158,9 @@ export default class ThemeManager {
143 158
     }
144 159
 
145 160
     /**
146
-     * Get the current theme based on night mode
147
-     * @returns {Object}
161
+     * Get the current theme based on night mode and events
162
+     *
163
+     * @returns {Object} The current theme
148 164
      */
149 165
     static getCurrentTheme(): Object {
150 166
         if (AprilFoolsManager.getInstance().isAprilFoolsEnabled())
@@ -153,6 +169,11 @@ export default class ThemeManager {
153 169
             return ThemeManager.getBaseTheme()
154 170
     }
155 171
 
172
+    /**
173
+     * Get the theme based on night mode
174
+     *
175
+     * @return {Object} The theme
176
+     */
156 177
     static getBaseTheme() {
157 178
         if (ThemeManager.getNightMode())
158 179
             return ThemeManager.getDarkTheme();
@@ -161,7 +182,8 @@ export default class ThemeManager {
161 182
     }
162 183
 
163 184
     /**
164
-     * Set the function to be called when the theme is changed (allows for general reload of the app)
185
+     * Sets the function to be called when the theme is changed (allows for general reload of the app)
186
+     *
165 187
      * @param callback Function to call after theme change
166 188
      */
167 189
     setUpdateThemeCallback(callback: ?Function) {
@@ -171,7 +193,7 @@ export default class ThemeManager {
171 193
     /**
172 194
      * Set night mode and save it to preferences
173 195
      *
174
-     * @param isNightMode Whether to enable night mode
196
+     * @param isNightMode True to enable night mode, false to disable
175 197
      */
176 198
     setNightMode(isNightMode: boolean) {
177 199
         let nightModeKey = AsyncStorageManager.getInstance().preferences.nightMode.key;

Loading…
Cancel
Save