Application Android et IOS pour l'amicale des élèves https://play.google.com/store/apps/details?id=fr.amicaleinsat.application
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SideBarSection.js 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // @flow
  2. import * as React from 'react';
  3. import {FlatList} from "react-native";
  4. import {Drawer, withTheme} from 'react-native-paper';
  5. import {Linking} from "expo";
  6. import AnimatedAccordion from "../Animations/AnimatedAccordion";
  7. import {StackActions} from '@react-navigation/native';
  8. type Props = {
  9. navigation: Object,
  10. startOpen: boolean,
  11. isLoggedIn: boolean,
  12. sectionName: string,
  13. activeRoute: string,
  14. listKey: string,
  15. listData: Array<Object>,
  16. }
  17. const LIST_ITEM_HEIGHT = 48;
  18. class SideBarSection extends React.PureComponent<Props> {
  19. colors: Object;
  20. accordionRef: {current: null | AnimatedAccordion};
  21. constructor(props) {
  22. super(props);
  23. this.colors = props.theme.colors;
  24. this.accordionRef = React.createRef();
  25. }
  26. /**
  27. * Searches if the current route is contained in the given list data.
  28. * If this is the case and the list is collapsed, we should expand this list.
  29. *
  30. * @return boolean
  31. */
  32. shouldExpandList() {
  33. for (let i = 0; i < this.props.listData.length; i++) {
  34. if (this.props.listData[i].route === this.props.activeRoute) {
  35. return true;
  36. }
  37. }
  38. return false;
  39. }
  40. /**
  41. * Callback when a drawer item is pressed.
  42. * It will either navigate to the associated screen, or open the browser to the associated link
  43. *
  44. * @param item The item pressed
  45. */
  46. onListItemPress(item: Object) {
  47. if (item.link !== undefined)
  48. Linking.openURL(item.link);
  49. else if (item.action !== undefined)
  50. item.action();
  51. else if (this.props.activeRoute === "main")
  52. this.props.navigation.navigate(item.route);
  53. else {
  54. this.props.navigation.dispatch(
  55. StackActions.replace(item.route)
  56. );
  57. this.props.navigation.closeDrawer();
  58. }
  59. }
  60. /**
  61. * Key extractor for list items
  62. *
  63. * @param item The item to extract the key from
  64. * @return {string} The extracted key
  65. */
  66. listKeyExtractor = (item: Object) => item.route;
  67. shouldHideItem(item: Object) {
  68. const onlyWhenLoggedOut = item.onlyWhenLoggedOut !== undefined && item.onlyWhenLoggedOut === true;
  69. const onlyWhenLoggedIn = item.onlyWhenLoggedIn !== undefined && item.onlyWhenLoggedIn === true;
  70. return (onlyWhenLoggedIn && !this.props.isLoggedIn || onlyWhenLoggedOut && this.props.isLoggedIn);
  71. }
  72. /**
  73. * Gets the render item for the given list item
  74. *
  75. * @param item The item to render
  76. * @return {*}
  77. */
  78. getRenderItem = ({item}: Object) => {
  79. const onListItemPress = this.onListItemPress.bind(this, item);
  80. if (this.shouldHideItem(item))
  81. return null;
  82. return (
  83. <Drawer.Item
  84. label={item.name}
  85. active={this.props.activeRoute === item.route}
  86. icon={item.icon}
  87. onPress={onListItemPress}
  88. style={{
  89. height: LIST_ITEM_HEIGHT,
  90. justifyContent: 'center',
  91. }}
  92. />
  93. );
  94. };
  95. shouldRenderAccordion() {
  96. let itemsToRender = 0;
  97. for (let i = 0; i < this.props.listData.length; i++) {
  98. if (!this.shouldHideItem(this.props.listData[i]))
  99. itemsToRender += 1;
  100. }
  101. return itemsToRender > 1;
  102. }
  103. itemLayout = (data, index) => ({length: LIST_ITEM_HEIGHT, offset: LIST_ITEM_HEIGHT * index, index});
  104. getFlatList() {
  105. return (
  106. // $FlowFixMe
  107. <FlatList
  108. data={this.props.listData}
  109. extraData={this.props.isLoggedIn.toString() + this.props.activeRoute}
  110. renderItem={this.getRenderItem}
  111. keyExtractor={this.listKeyExtractor}
  112. listKey={this.props.listKey}
  113. // Performance props, see https://reactnative.dev/docs/optimizing-flatlist-configuration
  114. getItemLayout={this.itemLayout}
  115. />
  116. );
  117. }
  118. render() {
  119. if (this.shouldRenderAccordion()) {
  120. return (
  121. <AnimatedAccordion
  122. title={this.props.sectionName}
  123. keepOpen={this.shouldExpandList()}
  124. >
  125. {this.getFlatList()}
  126. </AnimatedAccordion>
  127. );
  128. } else
  129. return this.getFlatList();
  130. }
  131. }
  132. export default withTheme(SideBarSection);