Application Android et IOS pour l'amicale des élèves
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.

GroupListItem.tsx 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * Copyright (c) 2019 - 2020 Arnaud Vergnet.
  3. *
  4. * This file is part of Campus INSAT.
  5. *
  6. * Campus INSAT is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Campus INSAT is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import * as React from 'react';
  20. import {List, TouchableRipple, withTheme} from 'react-native-paper';
  21. import * as Animatable from 'react-native-animatable';
  22. import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
  23. import type {PlanexGroupType} from '../../../screens/Planex/GroupSelectionScreen';
  24. import {View} from 'react-native';
  25. type PropsType = {
  26. theme: ReactNativePaper.Theme;
  27. onPress: () => void;
  28. onStarPress: () => void;
  29. item: PlanexGroupType;
  30. favorites: Array<PlanexGroupType>;
  31. height: number;
  32. };
  33. const REPLACE_REGEX = /_/g;
  34. class GroupListItem extends React.Component<PropsType> {
  35. isFav: boolean;
  36. starRef: {current: null | (Animatable.View & View)};
  37. constructor(props: PropsType) {
  38. super(props);
  39. this.starRef = React.createRef();
  40. this.isFav = this.isGroupInFavorites(props.favorites);
  41. }
  42. shouldComponentUpdate(nextProps: PropsType): boolean {
  43. const {favorites} = this.props;
  44. const favChanged = favorites.length !== nextProps.favorites.length;
  45. let newFavState = this.isFav;
  46. if (favChanged) {
  47. newFavState = this.isGroupInFavorites(nextProps.favorites);
  48. }
  49. const shouldUpdate = this.isFav !== newFavState;
  50. this.isFav = newFavState;
  51. return shouldUpdate;
  52. }
  53. onStarPress = () => {
  54. const {props} = this;
  55. const ref = this.starRef;
  56. if (ref.current && ref.current.rubberBand && ref.current.swing) {
  57. if (this.isFav) {
  58. ref.current.rubberBand();
  59. } else {
  60. ref.current.swing();
  61. }
  62. }
  63. props.onStarPress();
  64. };
  65. isGroupInFavorites(favorites: Array<PlanexGroupType>): boolean {
  66. const {item} = this.props;
  67. for (let i = 0; i < favorites.length; i += 1) {
  68. if (favorites[i].id === item.id) {
  69. return true;
  70. }
  71. }
  72. return false;
  73. }
  74. render() {
  75. const {props} = this;
  76. const {colors} = props.theme;
  77. return (
  78. <List.Item
  79. title={props.item.name.replace(REPLACE_REGEX, ' ')}
  80. onPress={props.onPress}
  81. left={(iconProps) => (
  82. <List.Icon
  83. color={iconProps.color}
  84. style={iconProps.style}
  85. icon="chevron-right"
  86. />
  87. )}
  88. right={(iconProps) => (
  89. <Animatable.View ref={this.starRef} useNativeDriver>
  90. <TouchableRipple
  91. onPress={this.onStarPress}
  92. style={{
  93. marginRight: 10,
  94. marginLeft: 'auto',
  95. marginTop: 'auto',
  96. marginBottom: 'auto',
  97. }}>
  98. <MaterialCommunityIcons
  99. size={30}
  100. style={{padding: 10}}
  101. name="star"
  102. color={this.isFav ? colors.tetrisScore : iconProps.color}
  103. />
  104. </TouchableRipple>
  105. </Animatable.View>
  106. )}
  107. style={{
  108. height: props.height,
  109. justifyContent: 'center',
  110. }}
  111. />
  112. );
  113. }
  114. }
  115. export default withTheme(GroupListItem);