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.

GroupSelectionScreen.js 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // @flow
  2. import * as React from 'react';
  3. import {Platform} from "react-native";
  4. import i18n from "i18n-js";
  5. import {Searchbar, withTheme} from "react-native-paper";
  6. import {stringMatchQuery} from "../../utils/Search";
  7. import WebSectionList from "../../components/Screens/WebSectionList";
  8. import GroupListAccordion from "../../components/Lists/PlanexGroups/GroupListAccordion";
  9. import AsyncStorageManager from "../../managers/AsyncStorageManager";
  10. const LIST_ITEM_HEIGHT = 70;
  11. type Props = {
  12. navigation: Object,
  13. route: Object,
  14. theme: Object,
  15. }
  16. type State = {
  17. currentSearchString: string,
  18. favoriteGroups: Array<Object>,
  19. };
  20. function sortName(a, b) {
  21. if (a.name.toLowerCase() < b.name.toLowerCase())
  22. return -1;
  23. if (a.name.toLowerCase() > b.name.toLowerCase())
  24. return 1;
  25. return 0;
  26. }
  27. const GROUPS_URL = 'http://planex.insa-toulouse.fr/wsAdeGrp.php?projectId=1';
  28. const REPLACE_REGEX = /_/g;
  29. /**
  30. * Class defining proximo's article list of a certain category.
  31. */
  32. class GroupSelectionScreen extends React.Component<Props, State> {
  33. constructor(props) {
  34. super(props);
  35. this.state = {
  36. currentSearchString: '',
  37. favoriteGroups: JSON.parse(AsyncStorageManager.getInstance().preferences.planexFavoriteGroups.current),
  38. };
  39. }
  40. /**
  41. * Creates the header content
  42. */
  43. componentDidMount() {
  44. this.props.navigation.setOptions({
  45. headerTitle: this.getSearchBar,
  46. headerBackTitleVisible: false,
  47. headerTitleContainerStyle: Platform.OS === 'ios' ?
  48. {marginHorizontal: 0, width: '70%'} :
  49. {marginHorizontal: 0, right: 50, left: 50},
  50. });
  51. }
  52. /**
  53. * Gets the header search bar
  54. *
  55. * @return {*}
  56. */
  57. getSearchBar = () => {
  58. return (
  59. <Searchbar
  60. placeholder={i18n.t('proximoScreen.search')}
  61. onChangeText={this.onSearchStringChange}
  62. />
  63. );
  64. };
  65. /**
  66. * Callback used when the search changes
  67. *
  68. * @param str The new search string
  69. */
  70. onSearchStringChange = (str: string) => {
  71. this.setState({currentSearchString: str})
  72. };
  73. /**
  74. * Callback used when clicking an article in the list.
  75. * It opens the modal to show detailed information about the article
  76. *
  77. * @param item The article pressed
  78. */
  79. onListItemPress = (item: Object) => {
  80. this.props.navigation.navigate("planex", {
  81. screen: "index",
  82. params: {group: item}
  83. });
  84. };
  85. onListFavoritePress = (item: Object) => {
  86. this.updateGroupFavorites(item);
  87. };
  88. isGroupInFavorites(group: Object) {
  89. let isFav = false;
  90. for (let i = 0; i < this.state.favoriteGroups.length; i++) {
  91. if (group.id === this.state.favoriteGroups[i].id) {
  92. isFav = true;
  93. break;
  94. }
  95. }
  96. return isFav;
  97. }
  98. removeGroupFromFavorites(favorites: Array<Object>, group: Object) {
  99. for (let i = 0; i < favorites.length; i++) {
  100. if (group.id === favorites[i].id) {
  101. favorites.splice(i, 1);
  102. break;
  103. }
  104. }
  105. }
  106. addGroupToFavorites(favorites: Array<Object>, group: Object) {
  107. group.isFav = true;
  108. favorites.push(group);
  109. favorites.sort(sortName);
  110. }
  111. updateGroupFavorites(group: Object) {
  112. let newFavorites = [...this.state.favoriteGroups]
  113. if (this.isGroupInFavorites(group))
  114. this.removeGroupFromFavorites(newFavorites, group);
  115. else
  116. this.addGroupToFavorites(newFavorites, group);
  117. this.setState({favoriteGroups: newFavorites})
  118. AsyncStorageManager.getInstance().savePref(
  119. AsyncStorageManager.getInstance().preferences.planexFavoriteGroups.key,
  120. JSON.stringify(newFavorites));
  121. }
  122. shouldDisplayAccordion(item: Object) {
  123. let shouldDisplay = false;
  124. for (let i = 0; i < item.content.length; i++) {
  125. if (stringMatchQuery(item.content[i].name, this.state.currentSearchString)) {
  126. shouldDisplay = true;
  127. break;
  128. }
  129. }
  130. return shouldDisplay;
  131. }
  132. /**
  133. * Gets a render item for the given article
  134. *
  135. * @param item The article to render
  136. * @return {*}
  137. */
  138. renderItem = ({item}: Object) => {
  139. if (this.shouldDisplayAccordion(item)) {
  140. return (
  141. <GroupListAccordion
  142. item={item}
  143. onGroupPress={this.onListItemPress}
  144. onFavoritePress={this.onListFavoritePress}
  145. currentSearchString={this.state.currentSearchString}
  146. favoriteNumber={this.state.favoriteGroups.length}
  147. height={LIST_ITEM_HEIGHT}
  148. />
  149. );
  150. } else
  151. return null;
  152. };
  153. generateData(fetchedData: Object) {
  154. let data = [];
  155. for (let key in fetchedData) {
  156. this.formatGroups(fetchedData[key]);
  157. data.push(fetchedData[key]);
  158. }
  159. data.sort(sortName);
  160. data.unshift({name: "FAVORITES", id: "0", content: this.state.favoriteGroups});
  161. return data;
  162. }
  163. formatGroups(item: Object) {
  164. for (let i = 0; i < item.content.length; i++) {
  165. item.content[i].name = item.content[i].name.replace(REPLACE_REGEX, " ")
  166. item.content[i].isFav = this.isGroupInFavorites(item.content[i]);
  167. }
  168. }
  169. /**
  170. * Creates the dataset to be used in the FlatList
  171. *
  172. * @param fetchedData
  173. * @return {*}
  174. * */
  175. createDataset = (fetchedData: Object) => {
  176. return [
  177. {
  178. title: '',
  179. data: this.generateData(fetchedData)
  180. }
  181. ];
  182. }
  183. render() {
  184. return (
  185. <WebSectionList
  186. {...this.props}
  187. createDataset={this.createDataset}
  188. autoRefreshTime={0}
  189. refreshOnFocus={false}
  190. fetchUrl={GROUPS_URL}
  191. renderItem={this.renderItem}
  192. updateData={this.state.currentSearchString + this.state.favoriteGroups.length}
  193. itemHeight={LIST_ITEM_HEIGHT}
  194. />
  195. );
  196. }
  197. }
  198. export default withTheme(GroupSelectionScreen);