Browse Source

Add support for new server news api

Arnaud Vergnet 3 years ago
parent
commit
795980dc8d

+ 23
- 15
src/components/Home/FeedItem.js View File

8
 import ImageModal from 'react-native-image-modal';
8
 import ImageModal from 'react-native-image-modal';
9
 import {StackNavigationProp} from '@react-navigation/stack';
9
 import {StackNavigationProp} from '@react-navigation/stack';
10
 import type {FeedItemType} from '../../screens/Home/HomeScreen';
10
 import type {FeedItemType} from '../../screens/Home/HomeScreen';
11
-
12
-const ICON_AMICALE = require('../../../assets/amicale.png');
11
+import NewsSourcesConstants from '../../constants/NewsSourcesConstants';
12
+import type {NewsSourceType} from '../../constants/NewsSourcesConstants';
13
 
13
 
14
 type PropsType = {
14
 type PropsType = {
15
   navigation: StackNavigationProp,
15
   navigation: StackNavigationProp,
16
   item: FeedItemType,
16
   item: FeedItemType,
17
-  title: string,
18
-  subtitle: string,
19
   height: number,
17
   height: number,
20
 };
18
 };
21
 
19
 
23
  * Component used to display a feed item
21
  * Component used to display a feed item
24
  */
22
  */
25
 class FeedItem extends React.Component<PropsType> {
23
 class FeedItem extends React.Component<PropsType> {
24
+  /**
25
+   * Converts a dateString using Unix Timestamp to a formatted date
26
+   *
27
+   * @param dateString {string} The Unix Timestamp representation of a date
28
+   * @return {string} The formatted output date
29
+   */
30
+  static getFormattedDate(dateString: number): string {
31
+    const date = new Date(dateString * 1000);
32
+    return date.toLocaleString();
33
+  }
34
+
26
   shouldComponentUpdate(): boolean {
35
   shouldComponentUpdate(): boolean {
27
     return false;
36
     return false;
28
   }
37
   }
29
 
38
 
30
   onPress = () => {
39
   onPress = () => {
31
-    const {props} = this;
32
-    props.navigation.navigate('feed-information', {
33
-      data: props.item,
34
-      date: props.subtitle,
40
+    const {item, navigation} = this.props;
41
+    navigation.navigate('feed-information', {
42
+      data: item,
43
+      date: FeedItem.getFormattedDate(item.time),
35
     });
44
     });
36
   };
45
   };
37
 
46
 
38
   render(): React.Node {
47
   render(): React.Node {
39
     const {props} = this;
48
     const {props} = this;
40
     const {item} = props;
49
     const {item} = props;
41
-    const hasImage =
42
-      item.full_picture !== '' && item.full_picture !== undefined;
43
-
50
+    const hasImage = item.image !== '' && item.image != null;
51
+    const pageSource: NewsSourceType = NewsSourcesConstants[item.page_id];
44
     const cardMargin = 10;
52
     const cardMargin = 10;
45
     const cardHeight = props.height - 2 * cardMargin;
53
     const cardHeight = props.height - 2 * cardMargin;
46
     const imageSize = 250;
54
     const imageSize = 250;
58
         <TouchableRipple style={{flex: 1}} onPress={this.onPress}>
66
         <TouchableRipple style={{flex: 1}} onPress={this.onPress}>
59
           <View>
67
           <View>
60
             <Card.Title
68
             <Card.Title
61
-              title={props.title}
62
-              subtitle={props.subtitle}
69
+              title={pageSource.name}
70
+              subtitle={FeedItem.getFormattedDate(item.time)}
63
               left={(): React.Node => (
71
               left={(): React.Node => (
64
                 <Image
72
                 <Image
65
                   size={48}
73
                   size={48}
66
-                  source={ICON_AMICALE}
74
+                  source={pageSource.icon}
67
                   style={{
75
                   style={{
68
                     width: 48,
76
                     width: 48,
69
                     height: 48,
77
                     height: 48,
82
                     height: imageSize,
90
                     height: imageSize,
83
                   }}
91
                   }}
84
                   source={{
92
                   source={{
85
-                    uri: item.full_picture,
93
+                    uri: item.image,
86
                   }}
94
                   }}
87
                 />
95
                 />
88
               </View>
96
               </View>

+ 20
- 0
src/constants/NewsSourcesConstants.js View File

1
+// @flow
2
+
3
+import ICON_AMICALE from '../../assets/amicale.png';
4
+import ICON_CAMPUS from '../../assets/android.icon.png';
5
+
6
+export type NewsSourceType = {
7
+  icon: number,
8
+  name: string,
9
+};
10
+
11
+export default {
12
+  'amicale.deseleves': {
13
+    icon: ICON_AMICALE,
14
+    name: 'Amicale INSA Toulouse',
15
+  },
16
+  'campus.insat': {
17
+    icon: ICON_CAMPUS,
18
+    name: 'Application Campus',
19
+  },
20
+};

+ 3
- 4
src/screens/Home/FeedItemScreen.js View File

47
    * Opens the feed item out link in browser or compatible app
47
    * Opens the feed item out link in browser or compatible app
48
    */
48
    */
49
   onOutLinkPress = () => {
49
   onOutLinkPress = () => {
50
-    Linking.openURL(this.displayData.permalink_url);
50
+    Linking.openURL(this.displayData.url);
51
   };
51
   };
52
 
52
 
53
   /**
53
   /**
70
 
70
 
71
   render(): React.Node {
71
   render(): React.Node {
72
     const hasImage =
72
     const hasImage =
73
-      this.displayData.full_picture !== '' &&
74
-      this.displayData.full_picture != null;
73
+      this.displayData.image !== '' && this.displayData.image != null;
75
     return (
74
     return (
76
       <CollapsibleScrollView style={{margin: 5}} hasTab>
75
       <CollapsibleScrollView style={{margin: 5}} hasTab>
77
         <Card.Title
76
         <Card.Title
95
                 height: 250,
94
                 height: 250,
96
               }}
95
               }}
97
               source={{
96
               source={{
98
-                uri: this.displayData.full_picture,
97
+                uri: this.displayData.image,
99
               }}
98
               }}
100
             />
99
             />
101
           </View>
100
           </View>

+ 24
- 22
src/screens/Home/HomeScreen.js View File

30
 import {getDisplayEvent, getFutureEvents} from '../../utils/Home';
30
 import {getDisplayEvent, getFutureEvents} from '../../utils/Home';
31
 // import DATA from "../dashboard_data.json";
31
 // import DATA from "../dashboard_data.json";
32
 
32
 
33
-const NAME_AMICALE = 'Amicale INSA Toulouse';
34
 const DATA_URL =
33
 const DATA_URL =
35
   'https://etud.insa-toulouse.fr/~amicale_app/v2/dashboard/dashboard_data.json';
34
   'https://etud.insa-toulouse.fr/~amicale_app/v2/dashboard/dashboard_data.json';
36
 const FEED_ITEM_HEIGHT = 500;
35
 const FEED_ITEM_HEIGHT = 500;
40
 const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds
39
 const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds
41
 
40
 
42
 export type FeedItemType = {
41
 export type FeedItemType = {
43
-  full_picture: string,
44
-  message: string,
45
-  permalink_url: string,
46
-  created_time: number,
47
   id: string,
42
   id: string,
43
+  message: string,
44
+  url: string,
45
+  image: string | null,
46
+  video: string | null,
47
+  link: string | null,
48
+  time: number,
49
+  page_id: string,
48
 };
50
 };
49
 
51
 
50
 export type EventType = {
52
 export type EventType = {
68
   available_tutorials: number,
70
   available_tutorials: number,
69
 };
71
 };
70
 
72
 
73
+type RawNewsFeedType = {[key: string]: Array<FeedItemType>};
74
+
71
 type RawDashboardType = {
75
 type RawDashboardType = {
72
-  news_feed: {
73
-    data: Array<FeedItemType>,
74
-  },
76
+  news_feed: RawNewsFeedType,
75
   dashboard: FullDashboardType,
77
   dashboard: FullDashboardType,
76
 };
78
 };
77
 
79
 
89
  * Class defining the app's home screen
91
  * Class defining the app's home screen
90
  */
92
  */
91
 class HomeScreen extends React.Component<PropsType, StateType> {
93
 class HomeScreen extends React.Component<PropsType, StateType> {
94
+  static sortFeedTime = (a: FeedItemType, b: FeedItemType): number =>
95
+    b.time - a.time;
96
+
92
   isLoggedIn: boolean | null;
97
   isLoggedIn: boolean | null;
93
 
98
 
94
   fabRef: {current: null | AnimatedFAB};
99
   fabRef: {current: null | AnimatedFAB};
122
   }
127
   }
123
 
128
 
124
   /**
129
   /**
125
-   * Converts a dateString using Unix Timestamp to a formatted date
126
-   *
127
-   * @param dateString {string} The Unix Timestamp representation of a date
128
-   * @return {string} The formatted output date
129
-   */
130
-  static getFormattedDate(dateString: number): string {
131
-    const date = new Date(dateString * 1000);
132
-    return date.toLocaleString();
133
-  }
134
-
135
-  /**
136
    * Updates login state and navigation parameters on screen focus
130
    * Updates login state and navigation parameters on screen focus
137
    */
131
    */
138
   onScreenFocus = () => {
132
   onScreenFocus = () => {
285
       <FeedItem
279
       <FeedItem
286
         navigation={props.navigation}
280
         navigation={props.navigation}
287
         item={item}
281
         item={item}
288
-        title={NAME_AMICALE}
289
-        subtitle={HomeScreen.getFormattedDate(item.created_time)}
290
         height={FEED_ITEM_HEIGHT}
282
         height={FEED_ITEM_HEIGHT}
291
       />
283
       />
292
     );
284
     );
415
     // fetchedData = DATA;
407
     // fetchedData = DATA;
416
     if (fetchedData != null) {
408
     if (fetchedData != null) {
417
       if (fetchedData.news_feed != null)
409
       if (fetchedData.news_feed != null)
418
-        this.currentNewFeed = fetchedData.news_feed.data;
410
+        this.currentNewFeed = this.generateNewsFeed(fetchedData.news_feed);
419
       if (fetchedData.dashboard != null)
411
       if (fetchedData.dashboard != null)
420
         this.currentDashboard = fetchedData.dashboard;
412
         this.currentDashboard = fetchedData.dashboard;
421
     }
413
     }
458
     });
450
     });
459
   };
451
   };
460
 
452
 
453
+  generateNewsFeed(rawFeed: RawNewsFeedType): Array<FeedItemType> {
454
+    const finalFeed = [];
455
+    Object.keys(rawFeed).forEach((key: string) => {
456
+      const category: Array<FeedItemType> | null = rawFeed[key];
457
+      if (category != null && category.length > 0) finalFeed.push(...category);
458
+    });
459
+    finalFeed.sort(HomeScreen.sortFeedTime);
460
+    return finalFeed;
461
+  }
462
+
461
   render(): React.Node {
463
   render(): React.Node {
462
     const {props, state} = this;
464
     const {props, state} = this;
463
     return (
465
     return (

Loading…
Cancel
Save