diff --git a/src/components/Animations/AnimatedAccordion.js b/src/components/Animations/AnimatedAccordion.js new file mode 100644 index 0000000..1441624 --- /dev/null +++ b/src/components/Animations/AnimatedAccordion.js @@ -0,0 +1,87 @@ +// @flow + +import * as React from 'react'; +import {View} from "react-native"; +import {List, withTheme} from 'react-native-paper'; +import Collapsible from "react-native-collapsible"; +import * as Animatable from "react-native-animatable"; +import type {CustomTheme} from "../../managers/ThemeManager"; + +type Props = { + theme: CustomTheme, + title: string, + subtitle?: string, + left?: (props: { [keys: string]: any }) => React.Node, + startOpen: boolean, + keepOpen: boolean, + unmountWhenCollapsed: boolean, + children?: React.Node, +} + +type State = { + expanded: boolean +} + +const AnimatedListIcon = Animatable.createAnimatableComponent(List.Icon); + +class AnimatedAccordion extends React.PureComponent { + + static defaultProps = { + startOpen: false, + keepOpen: false, + unmountWhenCollapsed: false, + } + chevronRef: { current: null | AnimatedListIcon }; + state = { + expanded: false, + } + + constructor(props) { + super(props); + this.chevronRef = React.createRef(); + } + + componentDidMount() { + if (this.props.startOpen) + this.toggleAccordion(); + } + + toggleAccordion = () => { + if (!this.props.keepOpen) { + if (this.chevronRef.current != null) + this.chevronRef.current.transitionTo({rotate: this.state.expanded ? '0deg' : '180deg'}); + this.setState({expanded: !this.state.expanded}) + } + }; + + render() { + const colors = this.props.theme.colors; + return ( + + } + left={this.props.left} + /> + + {!this.props.unmountWhenCollapsed || (this.props.unmountWhenCollapsed && this.state.expanded) + ? this.props.children + : null} + + + ); + } + +} + +export default withTheme(AnimatedAccordion); \ No newline at end of file diff --git a/src/components/Lists/Clubs/ClubListHeader.js b/src/components/Lists/Clubs/ClubListHeader.js index c430e1c..edb91b3 100644 --- a/src/components/Lists/Clubs/ClubListHeader.js +++ b/src/components/Lists/Clubs/ClubListHeader.js @@ -4,21 +4,15 @@ import * as React from 'react'; import {Card, List, Text, withTheme} from 'react-native-paper'; import {StyleSheet, View} from "react-native"; import i18n from 'i18n-js'; +import AnimatedAccordion from "../../Animations/AnimatedAccordion"; type Props = { categoryRender: Function, categories: Array, } -type State = { - expanded: boolean, -} +class ClubListHeader extends React.Component { -class ClubListHeader extends React.Component { - - state = { - expanded: true - }; colors: Object; @@ -35,22 +29,19 @@ class ClubListHeader extends React.Component { return final; } - onPress = () => this.setState({expanded: !this.state.expanded}); - render() { return ( - } - expanded={this.state.expanded} - onPress={this.onPress} + startOpen={true} > {i18n.t("clubs.categoriesFilterMessage")} {this.getCategoriesRender()} - + ); } diff --git a/src/components/Lists/PlanexGroups/GroupListAccordion.js b/src/components/Lists/PlanexGroups/GroupListAccordion.js index ce660a5..bf3875c 100644 --- a/src/components/Lists/PlanexGroups/GroupListAccordion.js +++ b/src/components/Lists/PlanexGroups/GroupListAccordion.js @@ -4,9 +4,9 @@ import * as React from 'react'; import {List, withTheme} from 'react-native-paper'; import {FlatList, View} from "react-native"; import {stringMatchQuery} from "../../../utils/Search"; -import Collapsible from "react-native-collapsible"; import * as Animatable from "react-native-animatable"; import GroupListItem from "./GroupListItem"; +import AnimatedAccordion from "../../Animations/AnimatedAccordion"; type Props = { item: Object, @@ -47,11 +47,6 @@ class GroupListAccordion extends React.Component { || (nextProps.item.content.length !== this.props.item.content.length); } - onPress = () => { - this.chevronRef.current.transitionTo({rotate: this.state.expanded ? '0deg' : '180deg'}); - this.setState({expanded: !this.state.expanded}) - }; - keyExtractor = (item: Object) => item.id.toString(); renderItem = ({item}: Object) => { @@ -73,20 +68,14 @@ class GroupListAccordion extends React.Component { render() { const item = this.props.item; - const accordionColor = this.state.expanded - ? this.props.theme.colors.primary - : this.props.theme.colors.text; - // console.log(item.id); return ( - item.id === "0" ? { color={this.props.theme.colors.tetrisScore} /> : null} - right={(props) => } - /> - - {this.state.expanded // Only render list if expanded for increased performance - ? - : null} - - + + ); } diff --git a/src/components/Sidebar/SideBarSection.js b/src/components/Sidebar/SideBarSection.js index 6d2ff78..1f73ef0 100644 --- a/src/components/Sidebar/SideBarSection.js +++ b/src/components/Sidebar/SideBarSection.js @@ -1,11 +1,10 @@ // @flow import * as React from 'react'; -import {FlatList, View} from "react-native"; -import {Drawer, List, withTheme} from 'react-native-paper'; +import {FlatList} from "react-native"; +import {Drawer, withTheme} from 'react-native-paper'; import {Linking} from "expo"; -import Collapsible from "react-native-collapsible"; -import * as Animatable from "react-native-animatable"; +import AnimatedAccordion from "../Animations/AnimatedAccordion"; type Props = { navigation: Object, @@ -17,28 +16,17 @@ type Props = { listData: Array, } -type State = { - expanded: boolean -} - -const AnimatedListIcon = Animatable.createAnimatableComponent(List.Icon); - const LIST_ITEM_HEIGHT = 48; -class SideBarSection extends React.PureComponent { - - state = { - expanded: this.props.startOpen, - }; +class SideBarSection extends React.PureComponent { colors: Object; - shouldExpand: boolean; - chevronRef: Object; + accordionRef: {current: null | AnimatedAccordion}; constructor(props) { super(props); this.colors = props.theme.colors; - this.chevronRef = React.createRef(); + this.accordionRef = React.createRef(); } /** @@ -50,7 +38,7 @@ class SideBarSection extends React.PureComponent { shouldExpandList() { for (let i = 0; i < this.props.listData.length; i++) { if (this.props.listData[i].route === this.props.activeRoute) { - return this.state.expanded === false; + return true; } } return false; @@ -109,13 +97,6 @@ class SideBarSection extends React.PureComponent { ); }; - toggleAccordion = () => { - if ((!this.state.expanded && this.shouldExpand) || !this.shouldExpand) { - this.chevronRef.current.transitionTo({ rotate: this.state.expanded ? '0deg' : '180deg' }); - this.setState({expanded: !this.state.expanded}) - } - }; - shouldRenderAccordion() { let itemsToRender = 0; for (let i = 0; i < this.props.listData.length; i++) { @@ -144,26 +125,13 @@ class SideBarSection extends React.PureComponent { render() { if (this.shouldRenderAccordion()) { - this.shouldExpand = this.shouldExpandList(); - if (this.shouldExpand) - this.toggleAccordion(); return ( - - } - /> - - {this.getFlatList()} - - + + {this.getFlatList()} + ); } else return this.getFlatList(); diff --git a/src/screens/Other/SettingsScreen.js b/src/screens/Other/SettingsScreen.js index 80f75e7..b07da1a 100644 --- a/src/screens/Other/SettingsScreen.js +++ b/src/screens/Other/SettingsScreen.js @@ -8,6 +8,7 @@ import AsyncStorageManager from "../../managers/AsyncStorageManager"; import {setMachineReminderNotificationTime} from "../../utils/Notifications"; import {Card, List, Switch, ToggleButton} from 'react-native-paper'; import {Appearance} from "react-native-appearance"; +import AnimatedAccordion from "../../components/Animations/AnimatedAccordion"; type Props = { navigation: Object, @@ -89,6 +90,7 @@ export default class SettingsScreen extends React.Component { @@ -107,6 +109,7 @@ export default class SettingsScreen extends React.Component { @@ -188,25 +191,25 @@ export default class SettingsScreen extends React.Component { this.state.nightMode ) : null } - } > {this.getStartScreenPicker()} - + - } > {this.getProxiwashNotifPicker()} - +