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.

FeedItem.tsx 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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 { Button, Card, Text, TouchableRipple } from 'react-native-paper';
  21. import { Image, StyleSheet, View } from 'react-native';
  22. import Autolink from 'react-native-autolink';
  23. import i18n from 'i18n-js';
  24. import type { FeedItemType } from '../../screens/Home/HomeScreen';
  25. import NewsSourcesConstants, {
  26. AvailablePages,
  27. } from '../../constants/NewsSourcesConstants';
  28. import type { NewsSourceType } from '../../constants/NewsSourcesConstants';
  29. import ImageGalleryButton from '../Media/ImageGalleryButton';
  30. import { useNavigation } from '@react-navigation/native';
  31. import GENERAL_STYLES from '../../constants/Styles';
  32. type PropsType = {
  33. item: FeedItemType;
  34. height: number;
  35. };
  36. /**
  37. * Converts a dateString using Unix Timestamp to a formatted date
  38. *
  39. * @param dateString {string} The Unix Timestamp representation of a date
  40. * @return {string} The formatted output date
  41. */
  42. function getFormattedDate(dateString: number): string {
  43. const date = new Date(dateString * 1000);
  44. return date.toLocaleString();
  45. }
  46. const styles = StyleSheet.create({
  47. image: {
  48. width: 48,
  49. height: 48,
  50. },
  51. button: {
  52. marginLeft: 'auto',
  53. marginRight: 'auto',
  54. },
  55. action: {
  56. marginLeft: 'auto',
  57. },
  58. });
  59. /**
  60. * Component used to display a feed item
  61. */
  62. function FeedItem(props: PropsType) {
  63. const navigation = useNavigation();
  64. const onPress = () => {
  65. navigation.navigate('feed-information', {
  66. data: item,
  67. date: getFormattedDate(props.item.time),
  68. });
  69. };
  70. const { item, height } = props;
  71. const image = item.image !== '' && item.image != null ? item.image : null;
  72. const pageSource: NewsSourceType =
  73. NewsSourcesConstants[item.page_id as AvailablePages];
  74. const cardMargin = 10;
  75. const cardHeight = height - 2 * cardMargin;
  76. const imageSize = 250;
  77. const titleHeight = 80;
  78. const actionsHeight = 60;
  79. const textHeight =
  80. image != null
  81. ? cardHeight - titleHeight - actionsHeight - imageSize
  82. : cardHeight - titleHeight - actionsHeight;
  83. return (
  84. <Card
  85. style={{
  86. margin: cardMargin,
  87. height: cardHeight,
  88. }}
  89. >
  90. <TouchableRipple style={GENERAL_STYLES.flex} onPress={onPress}>
  91. <View>
  92. <Card.Title
  93. title={pageSource.name}
  94. subtitle={getFormattedDate(item.time)}
  95. left={() => <Image source={pageSource.icon} style={styles.image} />}
  96. style={{ height: titleHeight }}
  97. />
  98. {image != null ? (
  99. <ImageGalleryButton
  100. images={[{ url: image }]}
  101. style={{
  102. ...styles.button,
  103. width: imageSize,
  104. height: imageSize,
  105. }}
  106. />
  107. ) : null}
  108. <Card.Content>
  109. {item.message !== undefined ? (
  110. <Autolink
  111. text={item.message}
  112. hashtag={'facebook'}
  113. component={Text}
  114. style={{ height: textHeight }}
  115. truncate={32}
  116. email={true}
  117. url={true}
  118. phone={true}
  119. />
  120. ) : null}
  121. </Card.Content>
  122. <Card.Actions style={{ height: actionsHeight }}>
  123. <Button onPress={onPress} icon="plus" style={styles.action}>
  124. {i18n.t('screens.home.dashboard.seeMore')}
  125. </Button>
  126. </Card.Actions>
  127. </View>
  128. </TouchableRipple>
  129. </Card>
  130. );
  131. }
  132. export default React.memo(FeedItem, () => true);