Browse Source

Improve Dashboard edit components to match linter

Arnaud Vergnet 3 years ago
parent
commit
70365136ac

+ 77
- 60
src/components/Lists/DashboardEdit/DashboardEditAccordion.js View File

@@ -2,71 +2,88 @@
2 2
 
3 3
 import * as React from 'react';
4 4
 import {withTheme} from 'react-native-paper';
5
-import {FlatList, Image, View} from "react-native";
6
-import DashboardEditItem from "./DashboardEditItem";
7
-import AnimatedAccordion from "../../Animations/AnimatedAccordion";
8
-import type {ServiceCategory, ServiceItem} from "../../../managers/ServicesManager";
9
-import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
10
-import type {CustomTheme} from "../../../managers/ThemeManager";
5
+import {FlatList, Image, View} from 'react-native';
6
+import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
7
+import DashboardEditItem from './DashboardEditItem';
8
+import AnimatedAccordion from '../../Animations/AnimatedAccordion';
9
+import type {
10
+  ServiceCategoryType,
11
+  ServiceItemType,
12
+} from '../../../managers/ServicesManager';
13
+import type {CustomTheme} from '../../../managers/ThemeManager';
11 14
 
12
-type Props = {
13
-    item: ServiceCategory,
14
-    activeDashboard: Array<string>,
15
-    onPress: (service: ServiceItem) => void,
16
-    theme: CustomTheme,
17
-}
15
+type PropsType = {
16
+  item: ServiceCategoryType,
17
+  activeDashboard: Array<string>,
18
+  onPress: (service: ServiceItemType) => void,
19
+  theme: CustomTheme,
20
+};
18 21
 
19 22
 const LIST_ITEM_HEIGHT = 64;
20 23
 
21
-class DashboardEditAccordion extends React.Component<Props> {
22
-
23
-    renderItem = ({item}: { item: ServiceItem }) => {
24
-        return (
25
-            <DashboardEditItem
26
-                height={LIST_ITEM_HEIGHT}
27
-                item={item}
28
-                isActive={this.props.activeDashboard.includes(item.key)}
29
-                onPress={() => this.props.onPress(item)}/>
30
-        );
31
-    }
24
+class DashboardEditAccordion extends React.Component<PropsType> {
25
+  getRenderItem = ({item}: {item: ServiceItemType}): React.Node => {
26
+    const {props} = this;
27
+    return (
28
+      <DashboardEditItem
29
+        height={LIST_ITEM_HEIGHT}
30
+        item={item}
31
+        isActive={props.activeDashboard.includes(item.key)}
32
+        onPress={() => {
33
+          props.onPress(item);
34
+        }}
35
+      />
36
+    );
37
+  };
32 38
 
33
-    itemLayout = (data, index) => ({length: LIST_ITEM_HEIGHT, offset: LIST_ITEM_HEIGHT * index, index});
39
+  getItemLayout = (
40
+    data: ?Array<ServiceItemType>,
41
+    index: number,
42
+  ): {length: number, offset: number, index: number} => ({
43
+    length: LIST_ITEM_HEIGHT,
44
+    offset: LIST_ITEM_HEIGHT * index,
45
+    index,
46
+  });
34 47
 
35
-    render() {
36
-        const item = this.props.item;
37
-        return (
38
-            <View>
39
-                <AnimatedAccordion
40
-                    title={item.title}
41
-                    left={props => typeof item.image === "number"
42
-                        ? <Image
43
-                            {...props}
44
-                            source={item.image}
45
-                            style={{
46
-                                width: 40,
47
-                                height: 40
48
-                            }}
49
-                        />
50
-                        : <MaterialCommunityIcons
51
-                            //$FlowFixMe
52
-                            name={item.image}
53
-                            color={this.props.theme.colors.primary}
54
-                            size={40}/>}
55
-                >
56
-                    {/*$FlowFixMe*/}
57
-                    <FlatList
58
-                        data={item.content}
59
-                        extraData={this.props.activeDashboard.toString()}
60
-                        renderItem={this.renderItem}
61
-                        listKey={item.key}
62
-                        // Performance props, see https://reactnative.dev/docs/optimizing-flatlist-configuration
63
-                        getItemLayout={this.itemLayout}
64
-                        removeClippedSubviews={true}
65
-                    />
66
-                </AnimatedAccordion>
67
-            </View>
68
-        );
69
-    }
48
+  render(): React.Node {
49
+    const {props} = this;
50
+    const {item} = props;
51
+    return (
52
+      <View>
53
+        <AnimatedAccordion
54
+          title={item.title}
55
+          left={(): React.Node =>
56
+            typeof item.image === 'number' ? (
57
+              <Image
58
+                source={item.image}
59
+                style={{
60
+                  width: 40,
61
+                  height: 40,
62
+                }}
63
+              />
64
+            ) : (
65
+              <MaterialCommunityIcons
66
+                // $FlowFixMe
67
+                name={item.image}
68
+                color={props.theme.colors.primary}
69
+                size={40}
70
+              />
71
+            )
72
+          }>
73
+          {/* $FlowFixMe */}
74
+          <FlatList
75
+            data={item.content}
76
+            extraData={props.activeDashboard.toString()}
77
+            renderItem={this.getRenderItem}
78
+            listKey={item.key}
79
+            // Performance props, see https://reactnative.dev/docs/optimizing-flatlist-configuration
80
+            getItemLayout={this.getItemLayout}
81
+            removeClippedSubviews
82
+          />
83
+        </AnimatedAccordion>
84
+      </View>
85
+    );
86
+  }
70 87
 }
71 88
 
72
-export default withTheme(DashboardEditAccordion)
89
+export default withTheme(DashboardEditAccordion);

+ 50
- 44
src/components/Lists/DashboardEdit/DashboardEditItem.js View File

@@ -1,55 +1,61 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {Image} from "react-native";
4
+import {Image} from 'react-native';
5 5
 import {List, withTheme} from 'react-native-paper';
6
-import type {CustomTheme} from "../../../managers/ThemeManager";
7
-import type {ServiceItem} from "../../../managers/ServicesManager";
6
+import type {CustomTheme} from '../../../managers/ThemeManager';
7
+import type {ServiceItemType} from '../../../managers/ServicesManager';
8 8
 
9
-type Props = {
10
-    item: ServiceItem,
11
-    isActive: boolean,
12
-    height: number,
13
-    onPress: () => void,
14
-    theme: CustomTheme,
15
-}
16
-
17
-class DashboardEditItem extends React.Component<Props> {
9
+type PropsType = {
10
+  item: ServiceItemType,
11
+  isActive: boolean,
12
+  height: number,
13
+  onPress: () => void,
14
+  theme: CustomTheme,
15
+};
18 16
 
19
-    shouldComponentUpdate(nextProps: Props) {
20
-        return (nextProps.isActive !== this.props.isActive);
21
-    }
17
+class DashboardEditItem extends React.Component<PropsType> {
18
+  shouldComponentUpdate(nextProps: PropsType): boolean {
19
+    const {isActive} = this.props;
20
+    return nextProps.isActive !== isActive;
21
+  }
22 22
 
23
-    render() {
24
-        return (
25
-            <List.Item
26
-                title={this.props.item.title}
27
-                description={this.props.item.subtitle}
28
-                onPress={this.props.isActive ? null : this.props.onPress}
29
-                left={props =>
30
-                    <Image
31
-                        {...props}
32
-                        source={{uri: this.props.item.image}}
33
-                        style={{
34
-                            width: 40,
35
-                            height: 40
36
-                        }}
37
-                    />}
38
-                right={props => this.props.isActive
39
-                    ? <List.Icon
40
-                        {...props}
41
-                        icon={"check"}
42
-                        color={this.props.theme.colors.success}
43
-                    /> : null}
44
-                style={{
45
-                    height: this.props.height,
46
-                    justifyContent: 'center',
47
-                    paddingLeft: 30,
48
-                    backgroundColor: this.props.isActive ? this.props.theme.colors.proxiwashFinishedColor : "transparent"
49
-                }}
23
+  render(): React.Node {
24
+    const {props} = this;
25
+    return (
26
+      <List.Item
27
+        title={props.item.title}
28
+        description={props.item.subtitle}
29
+        onPress={props.isActive ? null : props.onPress}
30
+        left={(): React.Node => (
31
+          <Image
32
+            source={{uri: props.item.image}}
33
+            style={{
34
+              width: 40,
35
+              height: 40,
36
+            }}
37
+          />
38
+        )}
39
+        right={({size}: {size: number}): React.Node =>
40
+          props.isActive ? (
41
+            <List.Icon
42
+              size={size}
43
+              icon="check"
44
+              color={props.theme.colors.success}
50 45
             />
51
-        );
52
-    }
46
+          ) : null
47
+        }
48
+        style={{
49
+          height: props.height,
50
+          justifyContent: 'center',
51
+          paddingLeft: 30,
52
+          backgroundColor: props.isActive
53
+            ? props.theme.colors.proxiwashFinishedColor
54
+            : 'transparent',
55
+        }}
56
+      />
57
+    );
58
+  }
53 59
 }
54 60
 
55 61
 export default withTheme(DashboardEditItem);

+ 47
- 47
src/components/Lists/DashboardEdit/DashboardEditPreviewItem.js View File

@@ -2,57 +2,57 @@
2 2
 
3 3
 import * as React from 'react';
4 4
 import {TouchableRipple, withTheme} from 'react-native-paper';
5
-import {Dimensions, Image, View} from "react-native";
6
-import type {CustomTheme} from "../../../managers/ThemeManager";
7
-
8
-type Props = {
9
-    image: string,
10
-    isActive: boolean,
11
-    onPress: () => void,
12
-    theme: CustomTheme,
5
+import {Dimensions, Image, View} from 'react-native';
6
+import type {CustomTheme} from '../../../managers/ThemeManager';
7
+
8
+type PropsType = {
9
+  image: string,
10
+  isActive: boolean,
11
+  onPress: () => void,
12
+  theme: CustomTheme,
13 13
 };
14 14
 
15 15
 /**
16 16
  * Component used to render a small dashboard item
17 17
  */
18
-class DashboardEditPreviewItem extends React.Component<Props> {
19
-
20
-    itemSize: number;
21
-
22
-    constructor(props: Props) {
23
-        super(props);
24
-        this.itemSize = Dimensions.get('window').width / 8;
25
-    }
26
-
27
-    render() {
28
-        const props = this.props;
29
-        return (
30
-            <TouchableRipple
31
-                onPress={this.props.onPress}
32
-                borderless={true}
33
-                style={{
34
-                    marginLeft: 5,
35
-                    marginRight: 5,
36
-                    backgroundColor: this.props.isActive ? this.props.theme.colors.textDisabled : "transparent",
37
-                    borderRadius: 5
38
-                }}
39
-            >
40
-                <View style={{
41
-                    width: this.itemSize,
42
-                    height: this.itemSize,
43
-                }}>
44
-                    <Image
45
-                        source={{uri: props.image}}
46
-                        style={{
47
-                            width: "100%",
48
-                            height: "100%",
49
-                        }}
50
-                    />
51
-                </View>
52
-            </TouchableRipple>
53
-        );
54
-    }
55
-
18
+class DashboardEditPreviewItem extends React.Component<PropsType> {
19
+  itemSize: number;
20
+
21
+  constructor(props: PropsType) {
22
+    super(props);
23
+    this.itemSize = Dimensions.get('window').width / 8;
24
+  }
25
+
26
+  render(): React.Node {
27
+    const {props} = this;
28
+    return (
29
+      <TouchableRipple
30
+        onPress={props.onPress}
31
+        borderless
32
+        style={{
33
+          marginLeft: 5,
34
+          marginRight: 5,
35
+          backgroundColor: props.isActive
36
+            ? props.theme.colors.textDisabled
37
+            : 'transparent',
38
+          borderRadius: 5,
39
+        }}>
40
+        <View
41
+          style={{
42
+            width: this.itemSize,
43
+            height: this.itemSize,
44
+          }}>
45
+          <Image
46
+            source={{uri: props.image}}
47
+            style={{
48
+              width: '100%',
49
+              height: '100%',
50
+            }}
51
+          />
52
+        </View>
53
+      </TouchableRipple>
54
+    );
55
+  }
56 56
 }
57 57
 
58
-export default withTheme(DashboardEditPreviewItem)
58
+export default withTheme(DashboardEditPreviewItem);

+ 152
- 134
src/screens/Other/Settings/DashboardEditScreen.js View File

@@ -1,148 +1,166 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {StackNavigationProp} from "@react-navigation/stack";
5
-import type {CustomTheme} from "../../../managers/ThemeManager";
6
-import {Button, Card, Paragraph, withTheme} from "react-native-paper";
7
-import type {ServiceCategory, ServiceItem} from "../../../managers/ServicesManager";
8
-import DashboardManager from "../../../managers/DashboardManager";
9
-import DashboardItem from "../../../components/Home/EventDashboardItem";
10
-import {FlatList} from "react-native";
11
-import {View} from "react-native-animatable";
12
-import DashboardEditAccordion from "../../../components/Lists/DashboardEdit/DashboardEditAccordion";
13
-import DashboardEditPreviewItem from "../../../components/Lists/DashboardEdit/DashboardEditPreviewItem";
14
-import AsyncStorageManager from "../../../managers/AsyncStorageManager";
15
-import i18n from "i18n-js";
16
-import CollapsibleFlatList from "../../../components/Collapsible/CollapsibleFlatList";
17
-
18
-type Props = {
19
-    navigation: StackNavigationProp,
20
-    theme: CustomTheme,
4
+import {StackNavigationProp} from '@react-navigation/stack';
5
+import {Button, Card, Paragraph, withTheme} from 'react-native-paper';
6
+import {FlatList} from 'react-native';
7
+import {View} from 'react-native-animatable';
8
+import i18n from 'i18n-js';
9
+import type {
10
+  ServiceCategoryType,
11
+  ServiceItemType,
12
+} from '../../../managers/ServicesManager';
13
+import DashboardManager from '../../../managers/DashboardManager';
14
+import DashboardItem from '../../../components/Home/EventDashboardItem';
15
+import DashboardEditAccordion from '../../../components/Lists/DashboardEdit/DashboardEditAccordion';
16
+import DashboardEditPreviewItem from '../../../components/Lists/DashboardEdit/DashboardEditPreviewItem';
17
+import AsyncStorageManager from '../../../managers/AsyncStorageManager';
18
+import CollapsibleFlatList from '../../../components/Collapsible/CollapsibleFlatList';
19
+
20
+type PropsType = {
21
+  navigation: StackNavigationProp,
21 22
 };
22 23
 
23
-type State = {
24
-    currentDashboard: Array<ServiceItem>,
25
-    currentDashboardIdList: Array<string>,
26
-    activeItem: number,
24
+type StateType = {
25
+  currentDashboard: Array<ServiceItemType | null>,
26
+  currentDashboardIdList: Array<string>,
27
+  activeItem: number,
27 28
 };
28 29
 
29 30
 /**
30 31
  * Class defining the Settings screen. This screen shows controls to modify app preferences.
31 32
  */
32
-class DashboardEditScreen extends React.Component<Props, State> {
33
-
34
-    content: Array<ServiceCategory>;
35
-    initialDashboard: Array<ServiceItem>;
36
-    initialDashboardIdList: Array<string>;
37
-
38
-    constructor(props: Props) {
39
-        super(props);
40
-        let dashboardManager = new DashboardManager(this.props.navigation);
41
-        this.initialDashboardIdList = AsyncStorageManager.getObject(AsyncStorageManager.PREFERENCES.dashboardItems.key);
42
-        this.initialDashboard = dashboardManager.getCurrentDashboard();
43
-        this.state = {
44
-            currentDashboard: [...this.initialDashboard],
45
-            currentDashboardIdList: [...this.initialDashboardIdList],
46
-            activeItem: 0,
47
-        }
48
-        this.content = dashboardManager.getCategories();
49
-    }
50
-
51
-    dashboardRowRenderItem = ({item, index}: { item: DashboardItem, index: number }) => {
52
-        return (
53
-            <DashboardEditPreviewItem
54
-                image={item.image}
55
-                onPress={() => this.setState({activeItem: index})}
56
-                isActive={this.state.activeItem === index}
57
-            />
58
-        );
59
-    };
60
-
61
-    getDashboard(content: Array<DashboardItem>) {
62
-        return (
63
-            <FlatList
64
-                data={content}
65
-                extraData={this.state}
66
-                renderItem={this.dashboardRowRenderItem}
67
-                horizontal={true}
68
-                contentContainerStyle={{
69
-                    marginLeft: 'auto',
70
-                    marginRight: 'auto',
71
-                    marginTop: 5,
72
-                }}
73
-            />);
74
-    }
75
-
76
-    renderItem = ({item}: { item: ServiceCategory }) => {
77
-        return (
78
-            <DashboardEditAccordion
79
-                item={item}
80
-                onPress={this.updateDashboard}
81
-                activeDashboard={this.state.currentDashboardIdList}
82
-            />
83
-        );
33
+class DashboardEditScreen extends React.Component<PropsType, StateType> {
34
+  content: Array<ServiceCategoryType>;
35
+
36
+  initialDashboard: Array<ServiceItemType | null>;
37
+
38
+  initialDashboardIdList: Array<string>;
39
+
40
+  constructor(props: PropsType) {
41
+    super(props);
42
+    const dashboardManager = new DashboardManager(props.navigation);
43
+    this.initialDashboardIdList = AsyncStorageManager.getObject(
44
+      AsyncStorageManager.PREFERENCES.dashboardItems.key,
45
+    );
46
+    this.initialDashboard = dashboardManager.getCurrentDashboard();
47
+    this.state = {
48
+      currentDashboard: [...this.initialDashboard],
49
+      currentDashboardIdList: [...this.initialDashboardIdList],
50
+      activeItem: 0,
84 51
     };
85
-
86
-    updateDashboard = (service: ServiceItem) => {
87
-        let currentDashboard = this.state.currentDashboard;
88
-        let currentDashboardIdList = this.state.currentDashboardIdList;
89
-        currentDashboard[this.state.activeItem] = service;
90
-        currentDashboardIdList[this.state.activeItem] = service.key;
91
-        this.setState({
92
-            currentDashboard: currentDashboard,
93
-            currentDashboardIdList: currentDashboardIdList,
94
-        });
95
-        AsyncStorageManager.set(AsyncStorageManager.PREFERENCES.dashboardItems.key, currentDashboardIdList);
96
-    }
97
-
98
-    undoDashboard = () => {
99
-        this.setState({
100
-            currentDashboard: [...this.initialDashboard],
101
-            currentDashboardIdList: [...this.initialDashboardIdList]
102
-        });
103
-        AsyncStorageManager.set(AsyncStorageManager.PREFERENCES.dashboardItems.key, this.initialDashboardIdList);
104
-    }
105
-
106
-    getListHeader() {
107
-        return (
108
-            <Card style={{margin: 5}}>
109
-                <Card.Content>
110
-                    <View style={{padding: 5}}>
111
-                        <Button
112
-                            mode={"contained"}
113
-                            onPress={this.undoDashboard}
114
-                            style={{
115
-                                marginLeft: "auto",
116
-                                marginRight: "auto",
117
-                                marginBottom: 10,
118
-                            }}
119
-                        >
120
-                            {i18n.t("screens.settings.dashboardEdit.undo")}
121
-                        </Button>
122
-                        <View style={{height: 50}}>
123
-                            {this.getDashboard(this.state.currentDashboard)}
124
-                        </View>
125
-                    </View>
126
-                    <Paragraph style={{textAlign: "center"}}>
127
-                        {i18n.t("screens.settings.dashboardEdit.message")}
128
-                    </Paragraph>
129
-                </Card.Content>
130
-            </Card>
131
-        );
132
-    }
133
-
134
-
135
-    render() {
136
-        return (
137
-            <CollapsibleFlatList
138
-                data={this.content}
139
-                renderItem={this.renderItem}
140
-                ListHeaderComponent={this.getListHeader()}
141
-                style={{}}
142
-            />
143
-        );
144
-    }
145
-
52
+    this.content = dashboardManager.getCategories();
53
+  }
54
+
55
+  getDashboardRowRenderItem = ({
56
+    item,
57
+    index,
58
+  }: {
59
+    item: DashboardItem,
60
+    index: number,
61
+  }): React.Node => {
62
+    const {activeItem} = this.state;
63
+    return (
64
+      <DashboardEditPreviewItem
65
+        image={item.image}
66
+        onPress={() => {
67
+          this.setState({activeItem: index});
68
+        }}
69
+        isActive={activeItem === index}
70
+      />
71
+    );
72
+  };
73
+
74
+  getDashboard(content: Array<DashboardItem>): React.Node {
75
+    return (
76
+      <FlatList
77
+        data={content}
78
+        extraData={this.state}
79
+        renderItem={this.getDashboardRowRenderItem}
80
+        horizontal
81
+        contentContainerStyle={{
82
+          marginLeft: 'auto',
83
+          marginRight: 'auto',
84
+          marginTop: 5,
85
+        }}
86
+      />
87
+    );
88
+  }
89
+
90
+  getRenderItem = ({item}: {item: ServiceCategoryType}): React.Node => {
91
+    const {currentDashboardIdList} = this.state;
92
+    return (
93
+      <DashboardEditAccordion
94
+        item={item}
95
+        onPress={this.updateDashboard}
96
+        activeDashboard={currentDashboardIdList}
97
+      />
98
+    );
99
+  };
100
+
101
+  getListHeader(): React.Node {
102
+    const {currentDashboard} = this.state;
103
+    return (
104
+      <Card style={{margin: 5}}>
105
+        <Card.Content>
106
+          <View style={{padding: 5}}>
107
+            <Button
108
+              mode="contained"
109
+              onPress={this.undoDashboard}
110
+              style={{
111
+                marginLeft: 'auto',
112
+                marginRight: 'auto',
113
+                marginBottom: 10,
114
+              }}>
115
+              {i18n.t('screens.settings.dashboardEdit.undo')}
116
+            </Button>
117
+            <View style={{height: 50}}>
118
+              {this.getDashboard(currentDashboard)}
119
+            </View>
120
+          </View>
121
+          <Paragraph style={{textAlign: 'center'}}>
122
+            {i18n.t('screens.settings.dashboardEdit.message')}
123
+          </Paragraph>
124
+        </Card.Content>
125
+      </Card>
126
+    );
127
+  }
128
+
129
+  updateDashboard = (service: ServiceItemType) => {
130
+    const {currentDashboard, currentDashboardIdList, activeItem} = this.state;
131
+    currentDashboard[activeItem] = service;
132
+    currentDashboardIdList[activeItem] = service.key;
133
+    this.setState({
134
+      currentDashboard,
135
+      currentDashboardIdList,
136
+    });
137
+    AsyncStorageManager.set(
138
+      AsyncStorageManager.PREFERENCES.dashboardItems.key,
139
+      currentDashboardIdList,
140
+    );
141
+  };
142
+
143
+  undoDashboard = () => {
144
+    this.setState({
145
+      currentDashboard: [...this.initialDashboard],
146
+      currentDashboardIdList: [...this.initialDashboardIdList],
147
+    });
148
+    AsyncStorageManager.set(
149
+      AsyncStorageManager.PREFERENCES.dashboardItems.key,
150
+      this.initialDashboardIdList,
151
+    );
152
+  };
153
+
154
+  render(): React.Node {
155
+    return (
156
+      <CollapsibleFlatList
157
+        data={this.content}
158
+        renderItem={this.getRenderItem}
159
+        ListHeaderComponent={this.getListHeader()}
160
+        style={{}}
161
+      />
162
+    );
163
+  }
146 164
 }
147 165
 
148 166
 export default withTheme(DashboardEditScreen);

Loading…
Cancel
Save