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.

AboutScreen.js 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. // @flow
  2. import * as React from 'react';
  3. import {FlatList, Linking, Platform} from 'react-native';
  4. import i18n from 'i18n-js';
  5. import {Avatar, Card, List, Title, withTheme} from 'react-native-paper';
  6. import {StackNavigationProp} from '@react-navigation/stack';
  7. import packageJson from '../../../package.json';
  8. import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatList';
  9. import APP_LOGO from '../../../assets/android.icon.png';
  10. type ListItemType = {
  11. onPressCallback: () => void,
  12. icon: string,
  13. text: string,
  14. showChevron: boolean,
  15. };
  16. const links = {
  17. appstore: 'https://apps.apple.com/us/app/campus-amicale-insat/id1477722148',
  18. playstore:
  19. 'https://play.google.com/store/apps/details?id=fr.amicaleinsat.application',
  20. git:
  21. 'https://git.etud.insa-toulouse.fr/vergnet/application-amicale/src/branch/master/README.md',
  22. changelog:
  23. 'https://git.etud.insa-toulouse.fr/vergnet/application-amicale/src/branch/master/Changelog.md',
  24. license:
  25. 'https://git.etud.insa-toulouse.fr/vergnet/application-amicale/src/branch/master/LICENSE',
  26. authorMail:
  27. 'mailto:vergnet@etud.insa-toulouse.fr?' +
  28. 'subject=' +
  29. 'Application Amicale INSA Toulouse' +
  30. '&body=' +
  31. 'Coucou !\n\n',
  32. authorLinkedin: 'https://www.linkedin.com/in/arnaud-vergnet-434ba5179/',
  33. yohanMail:
  34. 'mailto:ysimard@etud.insa-toulouse.fr?' +
  35. 'subject=' +
  36. 'Application Amicale INSA Toulouse' +
  37. '&body=' +
  38. 'Coucou !\n\n',
  39. yohanLinkedin: 'https://www.linkedin.com/in/yohan-simard',
  40. react: 'https://facebook.github.io/react-native/',
  41. meme: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
  42. };
  43. type PropsType = {
  44. navigation: StackNavigationProp,
  45. };
  46. /**
  47. * Opens a link in the device's browser
  48. * @param link The link to open
  49. */
  50. function openWebLink(link: string) {
  51. Linking.openURL(link);
  52. }
  53. /**
  54. * Class defining an about screen. This screen shows the user information about the app and it's author.
  55. */
  56. class AboutScreen extends React.Component<PropsType> {
  57. /**
  58. * Data to be displayed in the app card
  59. */
  60. appData = [
  61. {
  62. onPressCallback: () => {
  63. openWebLink(Platform.OS === 'ios' ? links.appstore : links.playstore);
  64. },
  65. icon: Platform.OS === 'ios' ? 'apple' : 'google-play',
  66. text:
  67. Platform.OS === 'ios'
  68. ? i18n.t('screens.about.appstore')
  69. : i18n.t('screens.about.playstore'),
  70. showChevron: true,
  71. },
  72. {
  73. onPressCallback: () => {
  74. const {navigation} = this.props;
  75. navigation.navigate('feedback');
  76. },
  77. icon: 'bug',
  78. text: i18n.t('screens.feedback.homeButtonTitle'),
  79. showChevron: true,
  80. },
  81. {
  82. onPressCallback: () => {
  83. openWebLink(links.git);
  84. },
  85. icon: 'git',
  86. text: 'Git',
  87. showChevron: true,
  88. },
  89. {
  90. onPressCallback: () => {
  91. openWebLink(links.changelog);
  92. },
  93. icon: 'refresh',
  94. text: i18n.t('screens.about.changelog'),
  95. showChevron: true,
  96. },
  97. {
  98. onPressCallback: () => {
  99. openWebLink(links.license);
  100. },
  101. icon: 'file-document',
  102. text: i18n.t('screens.about.license'),
  103. showChevron: true,
  104. },
  105. ];
  106. /**
  107. * Data to be displayed in the author card
  108. */
  109. authorData = [
  110. {
  111. onPressCallback: () => {
  112. openWebLink(links.meme);
  113. },
  114. icon: 'account-circle',
  115. text: 'Arnaud VERGNET',
  116. showChevron: false,
  117. },
  118. {
  119. onPressCallback: () => {
  120. openWebLink(links.authorMail);
  121. },
  122. icon: 'email',
  123. text: i18n.t('screens.about.authorMail'),
  124. showChevron: true,
  125. },
  126. {
  127. onPressCallback: () => {
  128. openWebLink(links.authorLinkedin);
  129. },
  130. icon: 'linkedin',
  131. text: 'Linkedin',
  132. showChevron: true,
  133. },
  134. ];
  135. /**
  136. * Data to be displayed in the additional developer card
  137. */
  138. additionalDevData = [
  139. {
  140. onPressCallback: () => {},
  141. icon: 'account',
  142. text: 'Yohan SIMARD',
  143. showChevron: false,
  144. },
  145. {
  146. onPressCallback: () => {
  147. openWebLink(links.yohanMail);
  148. },
  149. icon: 'email',
  150. text: i18n.t('screens.about.authorMail'),
  151. showChevron: true,
  152. },
  153. {
  154. onPressCallback: () => {
  155. openWebLink(links.yohanLinkedin);
  156. },
  157. icon: 'linkedin',
  158. text: 'Linkedin',
  159. showChevron: true,
  160. },
  161. ];
  162. /**
  163. * Data to be displayed in the technologies card
  164. */
  165. technoData = [
  166. {
  167. onPressCallback: () => {
  168. openWebLink(links.react);
  169. },
  170. icon: 'react',
  171. text: i18n.t('screens.about.reactNative'),
  172. showChevron: true,
  173. },
  174. {
  175. onPressCallback: () => {
  176. const {navigation} = this.props;
  177. navigation.navigate('dependencies');
  178. },
  179. icon: 'developer-board',
  180. text: i18n.t('screens.about.libs'),
  181. showChevron: true,
  182. },
  183. ];
  184. /**
  185. * Order of information cards
  186. */
  187. dataOrder = [
  188. {
  189. id: 'app',
  190. },
  191. {
  192. id: 'team',
  193. },
  194. {
  195. id: 'techno',
  196. },
  197. ];
  198. /**
  199. * Gets the app card showing information and links about the app.
  200. *
  201. * @return {*}
  202. */
  203. getAppCard(): React.Node {
  204. return (
  205. <Card style={{marginBottom: 10}}>
  206. <Card.Title
  207. title="Campus"
  208. subtitle={packageJson.version}
  209. left={({size}: {size: number}): React.Node => (
  210. <Avatar.Image
  211. size={size}
  212. source={APP_LOGO}
  213. style={{backgroundColor: 'transparent'}}
  214. />
  215. )}
  216. />
  217. <Card.Content>
  218. <FlatList
  219. data={this.appData}
  220. keyExtractor={this.keyExtractor}
  221. renderItem={this.getCardItem}
  222. />
  223. </Card.Content>
  224. </Card>
  225. );
  226. }
  227. /**
  228. * Gets the team card showing information and links about the team
  229. *
  230. * @return {*}
  231. */
  232. getTeamCard(): React.Node {
  233. return (
  234. <Card style={{marginBottom: 10}}>
  235. <Card.Title
  236. title={i18n.t('screens.about.team')}
  237. left={({size, color}: {size: number, color: string}): React.Node => (
  238. <Avatar.Icon size={size} color={color} icon="account-multiple" />
  239. )}
  240. />
  241. <Card.Content>
  242. <Title>{i18n.t('screens.about.author')}</Title>
  243. <FlatList
  244. data={this.authorData}
  245. keyExtractor={this.keyExtractor}
  246. listKey="1"
  247. renderItem={this.getCardItem}
  248. />
  249. <Title>{i18n.t('screens.about.additionalDev')}</Title>
  250. <FlatList
  251. data={this.additionalDevData}
  252. keyExtractor={this.keyExtractor}
  253. listKey="2"
  254. renderItem={this.getCardItem}
  255. />
  256. </Card.Content>
  257. </Card>
  258. );
  259. }
  260. /**
  261. * Gets the techno card showing information and links about the technologies used in the app
  262. *
  263. * @return {*}
  264. */
  265. getTechnoCard(): React.Node {
  266. return (
  267. <Card style={{marginBottom: 10}}>
  268. <Card.Content>
  269. <Title>{i18n.t('screens.about.technologies')}</Title>
  270. <FlatList
  271. data={this.technoData}
  272. keyExtractor={this.keyExtractor}
  273. renderItem={this.getCardItem}
  274. />
  275. </Card.Content>
  276. </Card>
  277. );
  278. }
  279. /**
  280. * Gets a chevron icon
  281. *
  282. * @param props
  283. * @return {*}
  284. */
  285. static getChevronIcon({
  286. size,
  287. color,
  288. }: {
  289. size: number,
  290. color: string,
  291. }): React.Node {
  292. return <List.Icon size={size} color={color} icon="chevron-right" />;
  293. }
  294. /**
  295. * Gets a custom list item icon
  296. *
  297. * @param item The item to show the icon for
  298. * @param props
  299. * @return {*}
  300. */
  301. static getItemIcon(
  302. item: ListItemType,
  303. {size, color}: {size: number, color: string},
  304. ): React.Node {
  305. return <List.Icon size={size} color={color} icon={item.icon} />;
  306. }
  307. /**
  308. * Gets a clickable card item to be rendered inside a card.
  309. *
  310. * @returns {*}
  311. */
  312. getCardItem = ({item}: {item: ListItemType}): React.Node => {
  313. const getItemIcon = (props: {size: number, color: string}): React.Node =>
  314. AboutScreen.getItemIcon(item, props);
  315. if (item.showChevron) {
  316. return (
  317. <List.Item
  318. title={item.text}
  319. left={getItemIcon}
  320. right={AboutScreen.getChevronIcon}
  321. onPress={item.onPressCallback}
  322. />
  323. );
  324. }
  325. return (
  326. <List.Item
  327. title={item.text}
  328. left={getItemIcon}
  329. onPress={item.onPressCallback}
  330. />
  331. );
  332. };
  333. /**
  334. * Gets a card, depending on the given item's id
  335. *
  336. * @param item The item to show
  337. * @return {*}
  338. */
  339. getMainCard = ({item}: {item: {id: string}}): React.Node => {
  340. switch (item.id) {
  341. case 'app':
  342. return this.getAppCard();
  343. case 'team':
  344. return this.getTeamCard();
  345. case 'techno':
  346. return this.getTechnoCard();
  347. default:
  348. return null;
  349. }
  350. };
  351. /**
  352. * Extracts a key from the given item
  353. *
  354. * @param item The item to extract the key from
  355. * @return {string} The extracted key
  356. */
  357. keyExtractor = (item: ListItemType): string => item.icon;
  358. render(): React.Node {
  359. return (
  360. <CollapsibleFlatList
  361. style={{padding: 5}}
  362. data={this.dataOrder}
  363. renderItem={this.getMainCard}
  364. />
  365. );
  366. }
  367. }
  368. export default withTheme(AboutScreen);