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.

HomeScreen.js 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. // @flow
  2. import * as React from 'react';
  3. import {Image, Linking, TouchableOpacity, View} from 'react-native';
  4. import {Body, Button, Card, CardItem, Left, Text, Thumbnail, H1, H3} from 'native-base';
  5. import i18n from "i18n-js";
  6. import CustomMaterialIcon from '../components/CustomMaterialIcon';
  7. import FetchedDataSectionList from "../components/FetchedDataSectionList";
  8. import Autolink from 'react-native-autolink';
  9. import ThemeManager from "../utils/ThemeManager";
  10. import PlatformTouchable from "react-native-platform-touchable";
  11. import HTML from 'react-native-render-html';
  12. import {LinearGradient} from 'expo-linear-gradient';
  13. import DATA from '../data_test'
  14. const ICON_AMICALE = require('../assets/amicale.png');
  15. const NAME_AMICALE = 'Amicale INSA Toulouse';
  16. const DATA_URL = "https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/dashboard/dashboard_data.json";
  17. const SECTIONS_ID = [
  18. 'dashboard',
  19. 'news_feed'
  20. ];
  21. const REFRESH_TIME = 1000 * 10; // Refresh every 10 seconds
  22. /**
  23. * Opens a link in the device's browser
  24. * @param link The link to open
  25. */
  26. function openWebLink(link) {
  27. Linking.openURL(link).catch((err) => console.error('Error opening link', err));
  28. }
  29. /**
  30. * Class defining the app's home screen
  31. */
  32. export default class HomeScreen extends FetchedDataSectionList {
  33. constructor() {
  34. super(DATA_URL, REFRESH_TIME);
  35. }
  36. getHeaderTranslation() {
  37. return i18n.t("screens.home");
  38. }
  39. getUpdateToastTranslations() {
  40. return [i18n.t("homeScreen.listUpdated"), i18n.t("homeScreen.listUpdateFail")];
  41. }
  42. getKeyExtractor(item: Object) {
  43. return item !== undefined ? item.id : undefined;
  44. }
  45. createDataset(fetchedData: Object) {
  46. // fetchedData = DATA;
  47. let newsData = [];
  48. let dashboardData = [];
  49. if (fetchedData['news_feed'] !== undefined)
  50. newsData = fetchedData['news_feed']['data'];
  51. if (fetchedData['dashboard'] !== undefined)
  52. dashboardData = this.generateDashboardDataset(fetchedData['dashboard']);
  53. return [
  54. {
  55. title: '',
  56. data: dashboardData,
  57. extraData: super.state,
  58. keyExtractor: this.getKeyExtractor,
  59. id: SECTIONS_ID[0]
  60. },
  61. {
  62. title: i18n.t('homeScreen.newsFeed'),
  63. data: newsData,
  64. extraData: super.state,
  65. keyExtractor: this.getKeyExtractor,
  66. id: SECTIONS_ID[1]
  67. }
  68. ];
  69. }
  70. generateDashboardDataset(dashboardData: Object) {
  71. let dataset = [
  72. {
  73. id: 'top',
  74. content: undefined
  75. },
  76. {
  77. id: 'middle',
  78. content: [{}, {}]
  79. },
  80. {
  81. id: 'bottom',
  82. content: undefined
  83. },
  84. ];
  85. for (let [key, value] of Object.entries(dashboardData)) {
  86. switch (key) {
  87. case 'today_events':
  88. dataset[0]['content'] = value;
  89. break;
  90. case 'proximo_articles':
  91. dataset[1]['content'][0] = {id: key, data: value};
  92. break;
  93. case 'today_menu':
  94. dataset[1]['content'][1] = {id: key, data: value};
  95. break;
  96. case 'available_machines':
  97. dataset[2]['content'] = value;
  98. break;
  99. }
  100. }
  101. return dataset
  102. }
  103. /**
  104. * Converts a dateString using Unix Timestamp to a formatted date
  105. * @param dateString {string} The Unix Timestamp representation of a date
  106. * @return {string} The formatted output date
  107. */
  108. static getFormattedDate(dateString: string) {
  109. let date = new Date(Number.parseInt(dateString) * 1000);
  110. return date.toLocaleString();
  111. }
  112. getRenderSectionHeader(title: string) {
  113. if (title === '') {
  114. return <View/>;
  115. } else {
  116. return (
  117. <View style={{
  118. backgroundColor: ThemeManager.getCurrentThemeVariables().containerBgColor
  119. }}>
  120. <H1 style={{
  121. marginLeft: 'auto',
  122. marginRight: 'auto',
  123. marginTop: 10,
  124. marginBottom: 10
  125. }}>{title}</H1>
  126. </View>
  127. );
  128. }
  129. }
  130. getDashboardItem(item: Object) {
  131. let content = item['content'];
  132. if (item['id'] === 'top')
  133. return this.getDashboardTopItem(content);
  134. else if (item['id'] === 'middle')
  135. return this.getDashboardMiddleItem(content);
  136. else
  137. return this.getDashboardBottomItem(content);
  138. }
  139. /**
  140. * Convert the date string given by in the event list json to a date object
  141. * @param dateString
  142. * @return {Date}
  143. */
  144. stringToDate(dateString: ?string): ?Date {
  145. let date = new Date();
  146. if (dateString === undefined || dateString === null)
  147. date = undefined;
  148. else if (dateString.split(' ').length > 1) {
  149. let timeStr = dateString.split(' ')[1];
  150. date.setHours(parseInt(timeStr.split(':')[0]), parseInt(timeStr.split(':')[1]), 0);
  151. } else
  152. date = undefined;
  153. return date;
  154. }
  155. /**
  156. * Get the time limit depending on the current day:
  157. * 17:30 for every day of the week except for thursday 11:30
  158. * 00:00 on weekends
  159. */
  160. getTodayEventTimeLimit() {
  161. let now = new Date();
  162. if (now.getDay() === 4) // Thursday
  163. now.setHours(11, 30, 0);
  164. else if (now.getDay() === 6 || now.getDay() === 0) // Weekend
  165. now.setHours(0, 0, 0);
  166. else
  167. now.setHours(17, 30, 0);
  168. return now;
  169. }
  170. /**
  171. * Get the duration (in milliseconds) of an event
  172. * @param event {Object}
  173. * @return {number} The number of milliseconds
  174. */
  175. getEventDuration(event: Object): number {
  176. let start = this.stringToDate(event['date_begin']);
  177. let end = this.stringToDate(event['date_end']);
  178. let duration = 0;
  179. if (start !== undefined && start !== null && end !== undefined && end !== null)
  180. duration = end - start;
  181. return duration;
  182. }
  183. /**
  184. * Get events starting after the limit
  185. *
  186. * @param events
  187. * @param limit
  188. * @return {Array<Object>}
  189. */
  190. getEventsAfterLimit(events: Object, limit: Date): Array<Object> {
  191. let validEvents = [];
  192. for (let event of events) {
  193. let startDate = this.stringToDate(event['date_begin']);
  194. if (startDate !== undefined && startDate !== null && startDate >= limit) {
  195. validEvents.push(event);
  196. }
  197. }
  198. return validEvents;
  199. }
  200. /**
  201. * Get the event with the longest duration in the given array.
  202. * If all events have the same duration, return the first in the array.
  203. * @param events
  204. */
  205. getLongestEvent(events: Array<Object>): Object {
  206. let longestEvent = events[0];
  207. let longestTime = 0;
  208. for (let event of events) {
  209. let time = this.getEventDuration(event);
  210. if (time > longestTime) {
  211. longestTime = time;
  212. longestEvent = event;
  213. }
  214. }
  215. return longestEvent;
  216. }
  217. /**
  218. * Get events that have not yet ended/started
  219. *
  220. * @param events
  221. */
  222. getFutureEvents(events: Array<Object>): Array<Object> {
  223. let validEvents = [];
  224. let now = new Date();
  225. for (let event of events) {
  226. let startDate = this.stringToDate(event['date_begin']);
  227. let endDate = this.stringToDate(event['date_end']);
  228. if (startDate !== undefined && startDate !== null) {
  229. if (startDate > now)
  230. validEvents.push(event);
  231. else if (endDate !== undefined && endDate !== null) {
  232. if (endDate > now || endDate < startDate) // Display event if it ends the following day
  233. validEvents.push(event);
  234. }
  235. }
  236. }
  237. return validEvents;
  238. }
  239. /**
  240. *
  241. *
  242. * @param events
  243. * @return {Object}
  244. */
  245. getDisplayEvent(events: Array<Object>): Object {
  246. let displayEvent = undefined;
  247. if (events.length > 1) {
  248. let eventsAfterLimit = this.getEventsAfterLimit(events, this.getTodayEventTimeLimit());
  249. if (eventsAfterLimit.length > 0) {
  250. if (eventsAfterLimit.length === 1)
  251. displayEvent = eventsAfterLimit[0];
  252. else
  253. displayEvent = this.getLongestEvent(events);
  254. } else {
  255. displayEvent = this.getLongestEvent(events);
  256. }
  257. } else if (events.length === 1) {
  258. displayEvent = events[0];
  259. }
  260. return displayEvent;
  261. }
  262. padStr(i: number) {
  263. return (i < 10) ? "0" + i : "" + i;
  264. }
  265. getFormattedEventTime(event: Object): string {
  266. let formattedStr = '';
  267. let startDate = this.stringToDate(event['date_begin']);
  268. let endDate = this.stringToDate(event['date_end']);
  269. if (startDate !== undefined && startDate !== null && endDate !== undefined && endDate !== null)
  270. formattedStr = this.padStr(startDate.getHours()) + ':' + this.padStr(startDate.getMinutes()) +
  271. ' - ' + this.padStr(endDate.getHours()) + ':' + this.padStr(endDate.getMinutes());
  272. else if (startDate !== undefined && startDate !== null)
  273. formattedStr = this.padStr(startDate.getHours()) + ':' + this.padStr(startDate.getMinutes());
  274. return formattedStr
  275. }
  276. getDashboardTopItem(content: Array<Object>) {
  277. let icon = 'calendar-range';
  278. let color = ThemeManager.getCurrentThemeVariables().planningColor;
  279. let title = i18n.t('homeScreen.dashboard.todayEventsTitle');
  280. let isAvailable = content.length > 0;
  281. let subtitle = '';
  282. let futureEvents = this.getFutureEvents(content);
  283. if (isAvailable) {
  284. subtitle =
  285. <Text>
  286. <Text style={{fontWeight: "bold"}}>{futureEvents.length}</Text>
  287. <Text>
  288. {
  289. futureEvents.length > 1 ?
  290. i18n.t('homeScreen.dashboard.todayEventsSubtitlePlural') :
  291. i18n.t('homeScreen.dashboard.todayEventsSubtitle')
  292. }
  293. </Text>
  294. </Text>;
  295. } else
  296. subtitle = i18n.t('homeScreen.dashboard.todayEventsSubtitleNA');
  297. let clickAction = () => this.props.navigation.navigate('Planning');
  298. let displayEvent = this.getDisplayEvent(futureEvents);
  299. return (
  300. <Card style={{
  301. flex: 0,
  302. marginLeft: 10,
  303. marginRight: 10,
  304. marginTop: 10,
  305. borderRadius: 20,
  306. backgroundColor: ThemeManager.getCurrentThemeVariables().cardDefaultBg,
  307. overflow: 'hidden',
  308. }}>
  309. <PlatformTouchable
  310. onPress={clickAction}
  311. style={{
  312. zIndex: 100,
  313. }}
  314. >
  315. <View>
  316. <CardItem style={{
  317. backgroundColor: 'transparent',
  318. }}>
  319. <Left>
  320. <CustomMaterialIcon
  321. icon={icon}
  322. color={
  323. isAvailable ?
  324. color :
  325. ThemeManager.getCurrentThemeVariables().textDisabledColor
  326. }
  327. fontSize={40}
  328. width={40}/>
  329. <Body>
  330. <H3 style={{
  331. color: isAvailable ?
  332. ThemeManager.getCurrentThemeVariables().textColor :
  333. ThemeManager.getCurrentThemeVariables().listNoteColor
  334. }}>
  335. {title}
  336. </H3>
  337. <Text style={{
  338. color: isAvailable ?
  339. ThemeManager.getCurrentThemeVariables().listNoteColor :
  340. ThemeManager.getCurrentThemeVariables().textDisabledColor
  341. }}>
  342. {subtitle}
  343. </Text>
  344. </Body>
  345. </Left>
  346. </CardItem>
  347. {displayEvent !== undefined ?
  348. <View>
  349. <CardItem style={{
  350. paddingTop: 0,
  351. paddingBottom: 0,
  352. backgroundColor: 'transparent',
  353. }}>
  354. <Left>
  355. {displayEvent['logo'] !== '' && displayEvent['logo'] !== null ?
  356. <Thumbnail source={{uri: displayEvent['logo']}} square/> :
  357. <View/>}
  358. <Body>
  359. <Text>{displayEvent['title']}</Text>
  360. <Text note>{this.getFormattedEventTime(displayEvent)}</Text>
  361. </Body>
  362. </Left>
  363. </CardItem>
  364. <CardItem style={{
  365. borderRadius: 30,
  366. backgroundColor: 'transparent',
  367. }}>
  368. <Body style={{
  369. height: displayEvent['description'].length > 50 ? 70 : 20,
  370. overflow: 'hidden',
  371. }}>
  372. <HTML html={"<div>" + displayEvent['description'] + "</div>"}
  373. tagsStyles={{
  374. p: {
  375. color: ThemeManager.getCurrentThemeVariables().textColor,
  376. fontSize: ThemeManager.getCurrentThemeVariables().fontSizeBase,
  377. },
  378. div: {color: ThemeManager.getCurrentThemeVariables().textColor},
  379. }}
  380. onLinkPress={(event, link) => openWebLink(link)}/>
  381. <LinearGradient
  382. colors={['transparent', ThemeManager.getCurrentThemeVariables().cardDefaultBg]}
  383. end={[0, 0.6]}
  384. style={{
  385. position: 'absolute',
  386. width: '100%',
  387. height: 60,
  388. bottom: 0,
  389. }}>
  390. <View style={{
  391. marginLeft: 'auto',
  392. marginTop: 'auto',
  393. flexDirection: 'row'
  394. }}>
  395. <Text style={{
  396. marginTop: 'auto',
  397. marginBottom: 'auto',
  398. padding: 0,
  399. }}>
  400. Click to see more
  401. </Text>
  402. <CustomMaterialIcon icon={'chevron-right'}/>
  403. </View>
  404. </LinearGradient>
  405. </Body>
  406. </CardItem>
  407. </View> :
  408. <View/>}
  409. </View>
  410. </PlatformTouchable>
  411. </Card>
  412. );
  413. }
  414. getSquareDashboardItem(isAvailable: boolean, icon: string, color: string, title: string, subtitle: React.Node, clickAction: Function, isLeftElement: boolean) {
  415. return (
  416. <Card style={{
  417. flex: 0,
  418. width: '48%',
  419. marginLeft: 0,
  420. marginRight: isLeftElement ? '4%' : 0,
  421. borderRadius: 20,
  422. backgroundColor: ThemeManager.getCurrentThemeVariables().cardDefaultBg,
  423. overflow: 'hidden',
  424. }}>
  425. <PlatformTouchable
  426. onPress={clickAction}
  427. style={{
  428. zIndex: 100,
  429. minHeight: 150,
  430. }}
  431. >
  432. <CardItem style={{
  433. backgroundColor: 'transparent'
  434. }}>
  435. <Body>
  436. <View style={{marginLeft: 'auto', marginRight: 'auto'}}>
  437. <CustomMaterialIcon
  438. icon={icon}
  439. color={
  440. isAvailable ?
  441. color :
  442. ThemeManager.getCurrentThemeVariables().textDisabledColor
  443. }
  444. fontSize={60}
  445. width={60}/>
  446. </View>
  447. <H3 style={{
  448. color: isAvailable ?
  449. ThemeManager.getCurrentThemeVariables().textColor :
  450. ThemeManager.getCurrentThemeVariables().listNoteColor,
  451. textAlign: 'center',
  452. width: '100%'
  453. }}>
  454. {title}
  455. </H3>
  456. <Text style={{
  457. color: isAvailable ?
  458. ThemeManager.getCurrentThemeVariables().listNoteColor :
  459. ThemeManager.getCurrentThemeVariables().textDisabledColor,
  460. textAlign: 'center',
  461. width: '100%'
  462. }}>
  463. {subtitle}
  464. </Text>
  465. </Body>
  466. </CardItem>
  467. </PlatformTouchable>
  468. </Card>
  469. );
  470. }
  471. getDashboardMiddleItem(content: Object) {
  472. let proximoData = content[0]['data'];
  473. let menuData = content[1]['data'];
  474. let proximoIcon = 'shopping';
  475. let proximoColor = ThemeManager.getCurrentThemeVariables().proximoColor;
  476. let proximoTitle = i18n.t('homeScreen.dashboard.proximoTitle');
  477. let isProximoAvailable = parseInt(proximoData) > 0;
  478. let proximoSubtitle = '';
  479. if (isProximoAvailable) {
  480. proximoSubtitle =
  481. <Text>
  482. <Text style={{fontWeight: "bold"}}>{proximoData}</Text>
  483. <Text>
  484. {
  485. proximoData > 1 ?
  486. i18n.t('homeScreen.dashboard.proximoSubtitlePlural') :
  487. i18n.t('homeScreen.dashboard.proximoSubtitle')
  488. }
  489. </Text>
  490. </Text>;
  491. } else
  492. proximoSubtitle = i18n.t('homeScreen.dashboard.proximoSubtitleNA');
  493. let proximoClickAction = () => this.props.navigation.navigate('Proximo');
  494. let menuIcon = 'silverware-fork-knife';
  495. let menuColor = ThemeManager.getCurrentThemeVariables().menuColor;
  496. let menuTitle = i18n.t('homeScreen.dashboard.menuTitle');
  497. let isMenuAvailable = menuData.length > 0;
  498. let menuSubtitle = '';
  499. if (isMenuAvailable) {
  500. menuSubtitle = i18n.t('homeScreen.dashboard.menuSubtitle');
  501. } else
  502. menuSubtitle = i18n.t('homeScreen.dashboard.menuSubtitleNA');
  503. let menuClickAction = () => this.props.navigation.navigate('SelfMenuScreen');
  504. return (
  505. <View style={{
  506. flexDirection: 'row',
  507. marginLeft: 10,
  508. marginRight: 10,
  509. }}>
  510. {this.getSquareDashboardItem(isProximoAvailable, proximoIcon, proximoColor, proximoTitle, proximoSubtitle, proximoClickAction, true)}
  511. {this.getSquareDashboardItem(isMenuAvailable, menuIcon, menuColor, menuTitle, menuSubtitle, menuClickAction, false)}
  512. </View>
  513. );
  514. }
  515. getDashboardBottomItem(content: Object) {
  516. let icon = 'washing-machine';
  517. let color = ThemeManager.getCurrentThemeVariables().proxiwashColor;
  518. let title = i18n.t('homeScreen.dashboard.proxiwashTitle');
  519. let isAvailable = parseInt(content['dryers']) > 0 || parseInt(content['washers']) > 0;
  520. let subtitle;
  521. let dryerColor = parseInt(content['dryers']) > 0 ?
  522. ThemeManager.getCurrentThemeVariables().textColor :
  523. ThemeManager.getCurrentThemeVariables().listNoteColor;
  524. let washerColor = parseInt(content['washers']) > 0 ?
  525. ThemeManager.getCurrentThemeVariables().textColor :
  526. ThemeManager.getCurrentThemeVariables().listNoteColor;
  527. let availableDryers = content['dryers'];
  528. let availableWashers = content['washers'];
  529. if (isAvailable) {
  530. subtitle =
  531. <Text>
  532. <Text style={{
  533. fontWeight: parseInt(content['dryers']) > 0 ?
  534. 'bold' :
  535. 'normal',
  536. color: dryerColor
  537. }}>
  538. {availableDryers}
  539. </Text>
  540. <Text>
  541. {
  542. availableDryers > 1 ?
  543. i18n.t('homeScreen.dashboard.proxiwashSubtitle1Plural') :
  544. i18n.t('homeScreen.dashboard.proxiwashSubtitle1')
  545. }
  546. </Text>
  547. <Text style={{
  548. fontWeight: parseInt(content['washers']) > 0 ?
  549. 'bold' :
  550. 'normal',
  551. color: washerColor
  552. }}>
  553. {availableWashers}
  554. </Text>
  555. <Text>
  556. {
  557. availableWashers > 1 ?
  558. i18n.t('homeScreen.dashboard.proxiwashSubtitle2Plural') :
  559. i18n.t('homeScreen.dashboard.proxiwashSubtitle2')
  560. }
  561. </Text>
  562. </Text>;
  563. } else
  564. subtitle = i18n.t('homeScreen.dashboard.proxiwashSubtitleNA');
  565. let clickAction = () => this.props.navigation.navigate('Proxiwash');
  566. return (
  567. <Card style={{
  568. flex: 0,
  569. marginLeft: 10,
  570. marginRight: 10,
  571. borderRadius: 20,
  572. backgroundColor: ThemeManager.getCurrentThemeVariables().cardDefaultBg,
  573. overflow: 'hidden',
  574. }}>
  575. <PlatformTouchable
  576. onPress={clickAction}
  577. style={{
  578. zIndex: 100,
  579. }}
  580. >
  581. <CardItem style={{
  582. backgroundColor: 'transparent'
  583. }}>
  584. <Left>
  585. <CustomMaterialIcon
  586. icon={icon}
  587. color={
  588. isAvailable ?
  589. color :
  590. ThemeManager.getCurrentThemeVariables().textDisabledColor
  591. }
  592. fontSize={40}
  593. width={40}/>
  594. <Body>
  595. <H3 style={{
  596. color: isAvailable ?
  597. ThemeManager.getCurrentThemeVariables().textColor :
  598. ThemeManager.getCurrentThemeVariables().listNoteColor
  599. }}>
  600. {title}
  601. </H3>
  602. <Text style={{
  603. color: isAvailable ?
  604. ThemeManager.getCurrentThemeVariables().listNoteColor :
  605. ThemeManager.getCurrentThemeVariables().textDisabledColor
  606. }}>
  607. {subtitle}
  608. </Text>
  609. </Body>
  610. </Left>
  611. </CardItem>
  612. </PlatformTouchable>
  613. </Card>
  614. );
  615. }
  616. getRenderItem(item: Object, section: Object, data: Object) {
  617. if (section['id'] === SECTIONS_ID[0]) {
  618. return this.getDashboardItem(item);
  619. } else {
  620. return (
  621. <Card style={{
  622. flex: 0,
  623. marginLeft: 10,
  624. marginRight: 10
  625. }}>
  626. <CardItem>
  627. <Left>
  628. <Thumbnail source={ICON_AMICALE} square/>
  629. <Body>
  630. <Text>{NAME_AMICALE}</Text>
  631. <Text note>{HomeScreen.getFormattedDate(item.created_time)}</Text>
  632. </Body>
  633. </Left>
  634. </CardItem>
  635. <CardItem>
  636. <Body>
  637. {item.full_picture !== '' && item.full_picture !== undefined ?
  638. <TouchableOpacity onPress={() => openWebLink(item.full_picture)}
  639. style={{width: '100%', height: 250}}>
  640. <Image source={{uri: item.full_picture}}
  641. style={{flex: 1, resizeMode: "contain"}}
  642. resizeMode="contain"
  643. />
  644. </TouchableOpacity>
  645. : <View/>}
  646. {item.message !== undefined ?
  647. <Autolink
  648. text={item.message}
  649. hashtag="facebook"
  650. style={{color: ThemeManager.getCurrentThemeVariables().textColor}}
  651. /> : <View/>
  652. }
  653. </Body>
  654. </CardItem>
  655. <CardItem>
  656. <Left>
  657. <Button transparent
  658. onPress={() => openWebLink(item.permalink_url)}>
  659. <CustomMaterialIcon
  660. icon="facebook"
  661. color="#57aeff"
  662. width={20}/>
  663. <Text>En savoir plus</Text>
  664. </Button>
  665. </Left>
  666. </CardItem>
  667. </Card>
  668. );
  669. }
  670. }
  671. }