Browse Source

Added support for favorite groups

Arnaud Vergnet 4 years ago
parent
commit
9baaed9f6a

+ 33
- 8
src/components/Lists/GroupListAccordion.js View File

@@ -1,15 +1,18 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {List} from 'react-native-paper';
4
+import {IconButton, List, withTheme} from 'react-native-paper';
5 5
 import {FlatList} from "react-native";
6 6
 import {stringMatchQuery} from "../../utils/Search";
7 7
 
8 8
 type Props = {
9 9
     item: Object,
10 10
     onGroupPress: Function,
11
+    onFavoritePress: Function,
11 12
     currentSearchString: string,
13
+    favoriteNumber: number,
12 14
     height: number,
15
+    theme: Object,
13 16
 }
14 17
 
15 18
 type State = {
@@ -18,10 +21,13 @@ type State = {
18 21
 
19 22
 const LIST_ITEM_HEIGHT = 64;
20 23
 
21
-export default class GroupListAccordion extends React.Component<Props, State> {
24
+class GroupListAccordion extends React.Component<Props, State> {
22 25
 
23
-    state = {
24
-        expanded: false,
26
+    constructor(props) {
27
+        super(props);
28
+        this.state = {
29
+            expanded: props.item.id === "0",
30
+        }
25 31
     }
26 32
 
27 33
     shouldComponentUpdate(nextProps: Props, nextSate: State) {
@@ -29,16 +35,22 @@ export default class GroupListAccordion extends React.Component<Props, State> {
29 35
             this.state.expanded = nextProps.currentSearchString.length > 0;
30 36
 
31 37
         return (nextProps.currentSearchString !== this.props.currentSearchString)
32
-            || (nextSate.expanded !== this.state.expanded);
38
+            || (nextSate.expanded !== this.state.expanded)
39
+            || (nextProps.favoriteNumber !== this.props.favoriteNumber);
33 40
     }
34 41
 
35 42
     onPress = () => this.setState({expanded: !this.state.expanded});
36 43
 
37 44
     keyExtractor = (item: Object) => item.id.toString();
38 45
 
46
+    isItemFavorite(item: Object) {
47
+        return item.isFav !== undefined && item.isFav;
48
+    }
49
+
39 50
     renderItem = ({item}: Object) => {
40 51
         if (stringMatchQuery(item.name, this.props.currentSearchString)) {
41 52
             const onPress = () => this.props.onGroupPress(item);
53
+            const onStartPress = () => this.props.onFavoritePress(item);
42 54
             return (
43 55
                 <List.Item
44 56
                     title={item.name}
@@ -48,9 +60,12 @@ export default class GroupListAccordion extends React.Component<Props, State> {
48 60
                             {...props}
49 61
                             icon={"chevron-right"}/>}
50 62
                     right={props =>
51
-                        <List.Icon
63
+                        <IconButton
52 64
                             {...props}
53
-                            icon={"star"}/>}
65
+                            icon={"star"}
66
+                            onPress={onStartPress}
67
+                            color={this.isItemFavorite(item) ? this.props.theme.colors.tetrisScore : props.color}
68
+                        />}
54 69
                     style={{
55 70
                         height: LIST_ITEM_HEIGHT,
56 71
                         justifyContent: 'center',
@@ -74,6 +89,14 @@ export default class GroupListAccordion extends React.Component<Props, State> {
74 89
                     height: this.props.height,
75 90
                     justifyContent: 'center',
76 91
                 }}
92
+                left={props =>
93
+                    item.id === "0"
94
+                    ? <List.Icon
95
+                        {...props}
96
+                        icon={"star"}
97
+                        color={this.props.theme.colors.tetrisScore}
98
+                    />
99
+                : null}
77 100
             >
78 101
                 {/*$FlowFixMe*/}
79 102
                 <FlatList
@@ -89,4 +112,6 @@ export default class GroupListAccordion extends React.Component<Props, State> {
89 112
             </List.Accordion>
90 113
         );
91 114
     }
92
-}
115
+}
116
+
117
+export default withTheme(GroupListAccordion)

+ 5
- 0
src/managers/AsyncStorageManager.js View File

@@ -84,6 +84,11 @@ export default class AsyncStorageManager {
84 84
             default: '',
85 85
             current: '',
86 86
         },
87
+        planexFavoriteGroups: {
88
+            key: 'planexFavoriteGroups',
89
+            default: '[]',
90
+            current: '',
91
+        },
87 92
     };
88 93
 
89 94
     /**

+ 53
- 3
src/screens/GroupSelectionScreen.js View File

@@ -7,6 +7,7 @@ import {Searchbar, withTheme} from "react-native-paper";
7 7
 import {stringMatchQuery} from "../utils/Search";
8 8
 import WebSectionList from "../components/Lists/WebSectionList";
9 9
 import GroupListAccordion from "../components/Lists/GroupListAccordion";
10
+import AsyncStorageManager from "../managers/AsyncStorageManager";
10 11
 
11 12
 const LIST_ITEM_HEIGHT = 70;
12 13
 
@@ -19,6 +20,7 @@ type Props = {
19 20
 
20 21
 type State = {
21 22
     currentSearchString: string,
23
+    favoriteGroups: Array<Object>,
22 24
 };
23 25
 
24 26
 function sortName(a, b) {
@@ -41,6 +43,7 @@ class GroupSelectionScreen extends React.Component<Props, State> {
41 43
         super(props);
42 44
         this.state = {
43 45
             currentSearchString: '',
46
+            favoriteGroups: JSON.parse(AsyncStorageManager.getInstance().preferences.planexFavoriteGroups.current),
44 47
         };
45 48
     }
46 49
 
@@ -93,6 +96,49 @@ class GroupSelectionScreen extends React.Component<Props, State> {
93 96
         });
94 97
     };
95 98
 
99
+    onListFavoritePress = (item: Object) => {
100
+        this.updateGroupFavorites(item);
101
+    };
102
+
103
+    isGroupInFavorites(group: Object) {
104
+        let isFav = false;
105
+        for (let i = 0; i < this.state.favoriteGroups.length; i++) {
106
+            if (group.id === this.state.favoriteGroups[i].id) {
107
+                isFav = true;
108
+                break;
109
+            }
110
+        }
111
+        return isFav;
112
+    }
113
+
114
+    removeGroupFromFavorites(favorites: Array<Object>, group: Object) {
115
+        for (let i = 0; i < favorites.length; i++) {
116
+            if (group.id === favorites[i].id) {
117
+                favorites.splice(i, 1);
118
+                break;
119
+            }
120
+        }
121
+    }
122
+
123
+    addGroupToFavorites(favorites: Array<Object>, group: Object) {
124
+        group.isFav = true;
125
+        favorites.push(group);
126
+        favorites.sort(sortName);
127
+    }
128
+
129
+    updateGroupFavorites(group: Object) {
130
+        let newFavorites = [...this.state.favoriteGroups]
131
+        if (this.isGroupInFavorites(group))
132
+            this.removeGroupFromFavorites(newFavorites, group);
133
+        else
134
+            this.addGroupToFavorites(newFavorites, group);
135
+        this.setState({favoriteGroups: newFavorites})
136
+        console.log(newFavorites);
137
+        AsyncStorageManager.getInstance().savePref(
138
+            AsyncStorageManager.getInstance().preferences.planexFavoriteGroups.key,
139
+            JSON.stringify(newFavorites));
140
+    }
141
+
96 142
     shouldDisplayAccordion(item: Object) {
97 143
         let shouldDisplay = false;
98 144
         for (let i = 0; i < item.content.length; i++) {
@@ -116,7 +162,9 @@ class GroupSelectionScreen extends React.Component<Props, State> {
116 162
                 <GroupListAccordion
117 163
                     item={item}
118 164
                     onGroupPress={this.onListItemPress}
165
+                    onFavoritePress={this.onListFavoritePress}
119 166
                     currentSearchString={this.state.currentSearchString}
167
+                    favoriteNumber={this.state.favoriteGroups.length}
120 168
                     height={LIST_ITEM_HEIGHT}
121 169
                 />
122 170
             );
@@ -127,16 +175,18 @@ class GroupSelectionScreen extends React.Component<Props, State> {
127 175
     generateData(fetchedData: Object) {
128 176
         let data = [];
129 177
         for (let key in fetchedData) {
130
-            this.formatGroupNames(fetchedData[key]);
178
+            this.formatGroups(fetchedData[key]);
131 179
             data.push(fetchedData[key]);
132 180
         }
133 181
         data.sort(sortName);
182
+        data.unshift({name: "FAVORITES", id: "0", content: this.state.favoriteGroups});
134 183
         return data;
135 184
     }
136 185
 
137
-    formatGroupNames(item: Object) {
186
+    formatGroups(item: Object) {
138 187
         for (let i = 0; i < item.content.length; i++) {
139 188
             item.content[i].name = item.content[i].name.replace(REPLACE_REGEX, " ")
189
+            item.content[i].isFav = this.isGroupInFavorites(item.content[i]);
140 190
         }
141 191
     }
142 192
 
@@ -167,7 +217,7 @@ class GroupSelectionScreen extends React.Component<Props, State> {
167 217
                     refreshOnFocus={false}
168 218
                     fetchUrl={GROUPS_URL}
169 219
                     renderItem={this.renderItem}
170
-                    updateData={this.state.currentSearchString}
220
+                    updateData={this.state.currentSearchString + this.state.favoriteGroups.length}
171 221
                     itemHeight={LIST_ITEM_HEIGHT}
172 222
                 />
173 223
             </View>

Loading…
Cancel
Save