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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. type PropsType = {
  25. theme: ReactNativePaper.Theme;
  26. onPress: () => void;
  27. onStarPress: () => void;
  28. item: PlanexGroupType;
  29. favorites: Array<PlanexGroupType>;
  30. height: number;
  31. };
  32. const REPLACE_REGEX = /_/g;
  33. class GroupListItem extends React.Component<PropsType> {
  34. isFav: boolean;
  35. starRef: {current: null | Animatable.View};
  36. constructor(props: PropsType) {
  37. super(props);
  38. this.starRef = React.createRef<Animatable.View>();
  39. this.isFav = this.isGroupInFavorites(props.favorites);
  40. }
  41. shouldComponentUpdate(nextProps: PropsType): boolean {
  42. const {favorites} = this.props;
  43. const favChanged = favorites.length !== nextProps.favorites.length;
  44. let newFavState = this.isFav;
  45. if (favChanged) {
  46. newFavState = this.isGroupInFavorites(nextProps.favorites);
  47. }
  48. const shouldUpdate = this.isFav !== newFavState;
  49. this.isFav = newFavState;
  50. return shouldUpdate;
  51. }
  52. onStarPress = () => {
  53. const {props} = this;
  54. const ref = this.starRef;
  55. if (ref.current) {
  56. if (this.isFav) {
  57. ref.current.rubberBand();
  58. } else {
  59. ref.current.swing();
  60. }
  61. }
  62. props.onStarPress();
  63. };
  64. isGroupInFavorites(favorites: Array<PlanexGroupType>): boolean {
  65. const {item} = this.props;
  66. for (let i = 0; i < favorites.length; i += 1) {
  67. if (favorites[i].id === item.id) {
  68. return true;
  69. }
  70. }
  71. return false;
  72. }
  73. render() {
  74. const {props} = this;
  75. const {colors} = props.theme;
  76. return (
  77. <List.Item
  78. title={props.item.name.replace(REPLACE_REGEX, ' ')}
  79. onPress={props.onPress}
  80. left={(iconProps) => (
  81. <List.Icon
  82. color={iconProps.color}
  83. style={iconProps.style}
  84. icon="chevron-right"
  85. />
  86. )}
  87. right={(iconProps) => (
  88. <Animatable.View ref={this.starRef} useNativeDriver>
  89. <TouchableRipple
  90. onPress={this.onStarPress}
  91. style={{
  92. marginRight: 10,
  93. marginLeft: 'auto',
  94. marginTop: 'auto',
  95. marginBottom: 'auto',
  96. }}>
  97. <MaterialCommunityIcons
  98. size={30}
  99. style={{padding: 10}}
  100. name="star"
  101. color={this.isFav ? colors.tetrisScore : iconProps.color}
  102. />
  103. </TouchableRipple>
  104. </Animatable.View>
  105. )}
  106. style={{
  107. height: props.height,
  108. justifyContent: 'center',
  109. }}
  110. />
  111. );
  112. }
  113. }
  114. export default withTheme(GroupListItem);