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.8KB

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