From 9baaed9f6a26c0d6a33501f88105e947112407ce Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Thu, 16 Apr 2020 11:30:15 +0200 Subject: [PATCH] Added support for favorite groups --- src/components/Lists/GroupListAccordion.js | 41 ++++++++++++---- src/managers/AsyncStorageManager.js | 5 ++ src/screens/GroupSelectionScreen.js | 56 ++++++++++++++++++++-- 3 files changed, 91 insertions(+), 11 deletions(-) diff --git a/src/components/Lists/GroupListAccordion.js b/src/components/Lists/GroupListAccordion.js index fd1a43c..dff8890 100644 --- a/src/components/Lists/GroupListAccordion.js +++ b/src/components/Lists/GroupListAccordion.js @@ -1,15 +1,18 @@ // @flow import * as React from 'react'; -import {List} from 'react-native-paper'; +import {IconButton, List, withTheme} from 'react-native-paper'; import {FlatList} from "react-native"; import {stringMatchQuery} from "../../utils/Search"; type Props = { item: Object, onGroupPress: Function, + onFavoritePress: Function, currentSearchString: string, + favoriteNumber: number, height: number, + theme: Object, } type State = { @@ -18,10 +21,13 @@ type State = { const LIST_ITEM_HEIGHT = 64; -export default class GroupListAccordion extends React.Component { +class GroupListAccordion extends React.Component { - state = { - expanded: false, + constructor(props) { + super(props); + this.state = { + expanded: props.item.id === "0", + } } shouldComponentUpdate(nextProps: Props, nextSate: State) { @@ -29,16 +35,22 @@ export default class GroupListAccordion extends React.Component { this.state.expanded = nextProps.currentSearchString.length > 0; return (nextProps.currentSearchString !== this.props.currentSearchString) - || (nextSate.expanded !== this.state.expanded); + || (nextSate.expanded !== this.state.expanded) + || (nextProps.favoriteNumber !== this.props.favoriteNumber); } onPress = () => this.setState({expanded: !this.state.expanded}); keyExtractor = (item: Object) => item.id.toString(); + isItemFavorite(item: Object) { + return item.isFav !== undefined && item.isFav; + } + renderItem = ({item}: Object) => { if (stringMatchQuery(item.name, this.props.currentSearchString)) { const onPress = () => this.props.onGroupPress(item); + const onStartPress = () => this.props.onFavoritePress(item); return ( { {...props} icon={"chevron-right"}/>} right={props => - } + icon={"star"} + onPress={onStartPress} + color={this.isItemFavorite(item) ? this.props.theme.colors.tetrisScore : props.color} + />} style={{ height: LIST_ITEM_HEIGHT, justifyContent: 'center', @@ -74,6 +89,14 @@ export default class GroupListAccordion extends React.Component { height: this.props.height, justifyContent: 'center', }} + left={props => + item.id === "0" + ? + : null} > {/*$FlowFixMe*/} { ); } -} \ No newline at end of file +} + +export default withTheme(GroupListAccordion) \ No newline at end of file diff --git a/src/managers/AsyncStorageManager.js b/src/managers/AsyncStorageManager.js index 29c3ed0..99a50b9 100644 --- a/src/managers/AsyncStorageManager.js +++ b/src/managers/AsyncStorageManager.js @@ -84,6 +84,11 @@ export default class AsyncStorageManager { default: '', current: '', }, + planexFavoriteGroups: { + key: 'planexFavoriteGroups', + default: '[]', + current: '', + }, }; /** diff --git a/src/screens/GroupSelectionScreen.js b/src/screens/GroupSelectionScreen.js index 2c24a02..f080139 100644 --- a/src/screens/GroupSelectionScreen.js +++ b/src/screens/GroupSelectionScreen.js @@ -7,6 +7,7 @@ import {Searchbar, withTheme} from "react-native-paper"; import {stringMatchQuery} from "../utils/Search"; import WebSectionList from "../components/Lists/WebSectionList"; import GroupListAccordion from "../components/Lists/GroupListAccordion"; +import AsyncStorageManager from "../managers/AsyncStorageManager"; const LIST_ITEM_HEIGHT = 70; @@ -19,6 +20,7 @@ type Props = { type State = { currentSearchString: string, + favoriteGroups: Array, }; function sortName(a, b) { @@ -41,6 +43,7 @@ class GroupSelectionScreen extends React.Component { super(props); this.state = { currentSearchString: '', + favoriteGroups: JSON.parse(AsyncStorageManager.getInstance().preferences.planexFavoriteGroups.current), }; } @@ -93,6 +96,49 @@ class GroupSelectionScreen extends React.Component { }); }; + onListFavoritePress = (item: Object) => { + this.updateGroupFavorites(item); + }; + + isGroupInFavorites(group: Object) { + let isFav = false; + for (let i = 0; i < this.state.favoriteGroups.length; i++) { + if (group.id === this.state.favoriteGroups[i].id) { + isFav = true; + break; + } + } + return isFav; + } + + removeGroupFromFavorites(favorites: Array, group: Object) { + for (let i = 0; i < favorites.length; i++) { + if (group.id === favorites[i].id) { + favorites.splice(i, 1); + break; + } + } + } + + addGroupToFavorites(favorites: Array, group: Object) { + group.isFav = true; + favorites.push(group); + favorites.sort(sortName); + } + + updateGroupFavorites(group: Object) { + let newFavorites = [...this.state.favoriteGroups] + if (this.isGroupInFavorites(group)) + this.removeGroupFromFavorites(newFavorites, group); + else + this.addGroupToFavorites(newFavorites, group); + this.setState({favoriteGroups: newFavorites}) + console.log(newFavorites); + AsyncStorageManager.getInstance().savePref( + AsyncStorageManager.getInstance().preferences.planexFavoriteGroups.key, + JSON.stringify(newFavorites)); + } + shouldDisplayAccordion(item: Object) { let shouldDisplay = false; for (let i = 0; i < item.content.length; i++) { @@ -116,7 +162,9 @@ class GroupSelectionScreen extends React.Component { ); @@ -127,16 +175,18 @@ class GroupSelectionScreen extends React.Component { generateData(fetchedData: Object) { let data = []; for (let key in fetchedData) { - this.formatGroupNames(fetchedData[key]); + this.formatGroups(fetchedData[key]); data.push(fetchedData[key]); } data.sort(sortName); + data.unshift({name: "FAVORITES", id: "0", content: this.state.favoriteGroups}); return data; } - formatGroupNames(item: Object) { + formatGroups(item: Object) { for (let i = 0; i < item.content.length; i++) { item.content[i].name = item.content[i].name.replace(REPLACE_REGEX, " ") + item.content[i].isFav = this.isGroupInFavorites(item.content[i]); } } @@ -167,7 +217,7 @@ class GroupSelectionScreen extends React.Component { refreshOnFocus={false} fetchUrl={GROUPS_URL} renderItem={this.renderItem} - updateData={this.state.currentSearchString} + updateData={this.state.currentSearchString + this.state.favoriteGroups.length} itemHeight={LIST_ITEM_HEIGHT} />