Browse Source

Improve intro slides usage

Arnaud Vergnet 3 years ago
parent
commit
a84a627fba

+ 3
- 11
locales/en.json View File

418
     },
418
     },
419
     "updateSlide0": {
419
     "updateSlide0": {
420
       "title": "New in this update!",
420
       "title": "New in this update!",
421
-      "text": "Faster than ever and easier to use!\nThis update includes lots of changes to improve your experience.\nUse the brand new feedback button on the home screen to talk to the developer!"
421
+      "text": ""
422
     },
422
     },
423
     "updateSlide1": {
423
     "updateSlide1": {
424
-      "title": "Improved Planex!",
425
-      "text": "You now have access to new controls, improved display, and you can also mark groups as favorites."
426
-    },
427
-    "updateSlide2": {
428
-      "title": "Scanotron 3000!",
429
-      "text": "Say hello to Scanotron 3000!\nAvailable from the Qr-Code button on the home screen, it will help you get information about clubs and events around the campus.\n(Useless right now but we have hope for next year)"
430
-    },
431
-    "updateSlide3": {
432
-      "title": "Amicale Account!",
433
-      "text": "You can now connect to your Amicale INSAT account from within the app! See all available clubs and more to come!\nClick on the login button from the home screen."
424
+      "title": "",
425
+      "text": ""
434
     },
426
     },
435
     "aprilFoolsSlide": {
427
     "aprilFoolsSlide": {
436
       "title": "New in this update!",
428
       "title": "New in this update!",

+ 3
- 11
locales/fr.json View File

417
     },
417
     },
418
     "updateSlide0": {
418
     "updateSlide0": {
419
       "title": "Nouveau dans cette mise à jour !",
419
       "title": "Nouveau dans cette mise à jour !",
420
-      "text": "Plus rapide que jamais et plus simple à utiliser !\nCette mise à jour contient de nombreux changements pour améliorer votre expérience.\nUtilisez le tout nouveau bouton de Feedback pour parler directement au développeur!"
420
+      "text": ""
421
     },
421
     },
422
     "updateSlide1": {
422
     "updateSlide1": {
423
-      "title": "Planex tout beau !",
424
-      "text": "Vous avez maintenant accès à de nouveaux contrôles, un affichage amélioré, et vous pouvez marquer des groupes en favoris."
425
-    },
426
-    "updateSlide2": {
427
-      "title": "Scanotron 3000 !",
428
-      "text": "Dites bonjour à Scanotron 3000 !\nDisponible depuis le bouton Qr-Code sur le menu principal, il vous aidera à avoir des informations sur les clubs et les événements du campus.\n(Inutile tout de suite mais on verra l'année pro)"
429
-    },
430
-    "updateSlide3": {
431
-      "title": "Compte Amicale !",
432
-      "text": "Vous pouvez maintenant vous connecter à votre compte Amicale depuis l'appli ! Accédez à la liste des clubs et plus à venir !\nCliquez sur le bouton Se Connecter dans le menu principal."
423
+      "title": "",
424
+      "text": ""
433
     },
425
     },
434
     "aprilFoolsSlide": {
426
     "aprilFoolsSlide": {
435
       "title": "Nouveau dans cette mise à jour !",
427
       "title": "Nouveau dans cette mise à jour !",

+ 41
- 0
src/components/Intro/IconIntro.js View File

1
+// @flow
2
+
3
+import * as React from 'react';
4
+import {StyleSheet, View} from 'react-native';
5
+import * as Animatable from 'react-native-animatable';
6
+import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
7
+
8
+type PropsType = {
9
+  icon: string,
10
+};
11
+
12
+const styles = StyleSheet.create({
13
+  center: {
14
+    marginTop: 'auto',
15
+    marginBottom: 'auto',
16
+    marginRight: 'auto',
17
+    marginLeft: 'auto',
18
+  },
19
+});
20
+
21
+class IntroIcon extends React.Component<PropsType> {
22
+  shouldComponentUpdate(): boolean {
23
+    return false;
24
+  }
25
+
26
+  render(): React.Node {
27
+    const {icon} = this.props;
28
+    return (
29
+      <View style={{flex: 1}}>
30
+        <Animatable.View
31
+          useNativeDriver
32
+          style={styles.center}
33
+          animation="fadeIn">
34
+          <MaterialCommunityIcons name={icon} color="#fff" size={200} />
35
+        </Animatable.View>
36
+      </View>
37
+    );
38
+  }
39
+}
40
+
41
+export default IntroIcon;

+ 46
- 0
src/components/Intro/MascotIntroEnd.js View File

1
+// @flow
2
+
3
+import * as React from 'react';
4
+import {StyleSheet, View} from 'react-native';
5
+import Mascot, {MASCOT_STYLE} from '../Mascot/Mascot';
6
+
7
+const styles = StyleSheet.create({
8
+  center: {
9
+    marginTop: 'auto',
10
+    marginBottom: 'auto',
11
+    marginRight: 'auto',
12
+    marginLeft: 'auto',
13
+  },
14
+});
15
+
16
+class MascotIntroEnd extends React.Component<null> {
17
+  shouldComponentUpdate(): boolean {
18
+    return false;
19
+  }
20
+
21
+  render(): React.Node {
22
+    return (
23
+      <View style={{flex: 1}}>
24
+        <Mascot
25
+          style={{
26
+            ...styles.center,
27
+            height: '80%',
28
+          }}
29
+          emotion={MASCOT_STYLE.COOL}
30
+          animated
31
+          entryAnimation={{
32
+            animation: 'slideInDown',
33
+            duration: 2000,
34
+          }}
35
+          loopAnimation={{
36
+            animation: 'pulse',
37
+            duration: 2000,
38
+            iterationCount: 'infinite',
39
+          }}
40
+        />
41
+      </View>
42
+    );
43
+  }
44
+}
45
+
46
+export default MascotIntroEnd;

+ 76
- 0
src/components/Intro/MascotIntroWelcome.js View File

1
+// @flow
2
+
3
+import * as React from 'react';
4
+import {StyleSheet, View} from 'react-native';
5
+import * as Animatable from 'react-native-animatable';
6
+import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
7
+import Mascot, {MASCOT_STYLE} from '../Mascot/Mascot';
8
+
9
+const styles = StyleSheet.create({
10
+  center: {
11
+    marginTop: 'auto',
12
+    marginBottom: 'auto',
13
+    marginRight: 'auto',
14
+    marginLeft: 'auto',
15
+  },
16
+});
17
+
18
+class MascotIntroWelcome extends React.Component<null> {
19
+  shouldComponentUpdate(): boolean {
20
+    return false;
21
+  }
22
+
23
+  render(): React.Node {
24
+    return (
25
+      <View style={{flex: 1}}>
26
+        <Mascot
27
+          style={{
28
+            ...styles.center,
29
+            height: '80%',
30
+          }}
31
+          emotion={MASCOT_STYLE.NORMAL}
32
+          animated
33
+          entryAnimation={{
34
+            animation: 'bounceIn',
35
+            duration: 2000,
36
+          }}
37
+        />
38
+        <Animatable.Text
39
+          useNativeDriver
40
+          animation="fadeInUp"
41
+          duration={500}
42
+          style={{
43
+            color: '#fff',
44
+            textAlign: 'center',
45
+            fontSize: 25,
46
+          }}>
47
+          PABLO
48
+        </Animatable.Text>
49
+        <Animatable.View
50
+          useNativeDriver
51
+          animation="fadeInUp"
52
+          duration={500}
53
+          delay={200}
54
+          style={{
55
+            position: 'absolute',
56
+            bottom: 30,
57
+            right: '20%',
58
+            width: 50,
59
+            height: 50,
60
+          }}>
61
+          <MaterialCommunityIcons
62
+            style={{
63
+              ...styles.center,
64
+              transform: [{rotateZ: '70deg'}],
65
+            }}
66
+            name="undo"
67
+            color="#fff"
68
+            size={40}
69
+          />
70
+        </Animatable.View>
71
+      </View>
72
+    );
73
+  }
74
+}
75
+
76
+export default MascotIntroWelcome;

+ 13
- 112
src/components/Overrides/CustomIntroSlider.js View File

2
 
2
 
3
 import * as React from 'react';
3
 import * as React from 'react';
4
 import {Platform, StatusBar, StyleSheet, View} from 'react-native';
4
 import {Platform, StatusBar, StyleSheet, View} from 'react-native';
5
-import type {MaterialCommunityIconsGlyphs} from 'react-native-vector-icons/MaterialCommunityIcons';
6
 import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
5
 import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
7
 import i18n from 'i18n-js';
6
 import i18n from 'i18n-js';
8
 import AppIntroSlider from 'react-native-app-intro-slider';
7
 import AppIntroSlider from 'react-native-app-intro-slider';
12
 import Update from '../../constants/Update';
11
 import Update from '../../constants/Update';
13
 import ThemeManager from '../../managers/ThemeManager';
12
 import ThemeManager from '../../managers/ThemeManager';
14
 import Mascot, {MASCOT_STYLE} from '../Mascot/Mascot';
13
 import Mascot, {MASCOT_STYLE} from '../Mascot/Mascot';
14
+import MascotIntroWelcome from '../Intro/MascotIntroWelcome';
15
+import IntroIcon from '../Intro/IconIntro';
16
+import MascotIntroEnd from '../Intro/MascotIntroEnd';
15
 
17
 
16
 type PropsType = {
18
 type PropsType = {
17
   onDone: () => void,
19
   onDone: () => void,
23
   currentSlide: number,
25
   currentSlide: number,
24
 };
26
 };
25
 
27
 
26
-type IntroSlideType = {
28
+export type IntroSlideType = {
27
   key: string,
29
   key: string,
28
   title: string,
30
   title: string,
29
   text: string,
31
   text: string,
30
   view: () => React.Node,
32
   view: () => React.Node,
31
-  mascotStyle: number,
33
+  mascotStyle?: number,
32
   colors: [string, string],
34
   colors: [string, string],
33
 };
35
 };
34
 
36
 
88
         key: '0', // Mascot
90
         key: '0', // Mascot
89
         title: i18n.t('intro.slideMain.title'),
91
         title: i18n.t('intro.slideMain.title'),
90
         text: i18n.t('intro.slideMain.text'),
92
         text: i18n.t('intro.slideMain.text'),
91
-        view: this.getWelcomeView,
92
-        mascotStyle: MASCOT_STYLE.NORMAL,
93
+        view: (): React.Node => <MascotIntroWelcome />,
93
         colors: ['#be1522', '#57080e'],
94
         colors: ['#be1522', '#57080e'],
94
       },
95
       },
95
       {
96
       {
96
         key: '1',
97
         key: '1',
97
         title: i18n.t('intro.slidePlanex.title'),
98
         title: i18n.t('intro.slidePlanex.title'),
98
         text: i18n.t('intro.slidePlanex.text'),
99
         text: i18n.t('intro.slidePlanex.text'),
99
-        view: (): React.Node => CustomIntroSlider.getIconView('calendar-clock'),
100
+        view: (): React.Node => <IntroIcon icon="calendar-clock" />,
100
         mascotStyle: MASCOT_STYLE.INTELLO,
101
         mascotStyle: MASCOT_STYLE.INTELLO,
101
         colors: ['#be1522', '#57080e'],
102
         colors: ['#be1522', '#57080e'],
102
       },
103
       },
104
         key: '2',
105
         key: '2',
105
         title: i18n.t('intro.slideEvents.title'),
106
         title: i18n.t('intro.slideEvents.title'),
106
         text: i18n.t('intro.slideEvents.text'),
107
         text: i18n.t('intro.slideEvents.text'),
107
-        view: (): React.Node => CustomIntroSlider.getIconView('calendar-star'),
108
+        view: (): React.Node => <IntroIcon icon="calendar-star" />,
108
         mascotStyle: MASCOT_STYLE.HAPPY,
109
         mascotStyle: MASCOT_STYLE.HAPPY,
109
         colors: ['#be1522', '#57080e'],
110
         colors: ['#be1522', '#57080e'],
110
       },
111
       },
112
         key: '3',
113
         key: '3',
113
         title: i18n.t('intro.slideServices.title'),
114
         title: i18n.t('intro.slideServices.title'),
114
         text: i18n.t('intro.slideServices.text'),
115
         text: i18n.t('intro.slideServices.text'),
115
-        view: (): React.Node =>
116
-          CustomIntroSlider.getIconView('view-dashboard-variant'),
116
+        view: (): React.Node => <IntroIcon icon="view-dashboard-variant" />,
117
         mascotStyle: MASCOT_STYLE.CUTE,
117
         mascotStyle: MASCOT_STYLE.CUTE,
118
         colors: ['#be1522', '#57080e'],
118
         colors: ['#be1522', '#57080e'],
119
       },
119
       },
121
         key: '4',
121
         key: '4',
122
         title: i18n.t('intro.slideDone.title'),
122
         title: i18n.t('intro.slideDone.title'),
123
         text: i18n.t('intro.slideDone.text'),
123
         text: i18n.t('intro.slideDone.text'),
124
-        view: (): React.Node => this.getEndView(),
125
-        mascotStyle: MASCOT_STYLE.COOL,
124
+        view: (): React.Node => <MascotIntroEnd />,
126
         colors: ['#9c165b', '#3e042b'],
125
         colors: ['#9c165b', '#3e042b'],
127
       },
126
       },
128
     ];
127
     ];
129
-    // $FlowFixMe
130
-    this.updateSlides = [];
131
-    for (let i = 0; i < Update.slidesNumber; i += 1) {
132
-      this.updateSlides.push({
133
-        key: i.toString(),
134
-        title: Update.getInstance().titleList[i],
135
-        text: Update.getInstance().descriptionList[i],
136
-        icon: Update.iconList[i],
137
-        colors: Update.colorsList[i],
138
-      });
139
-    }
128
+
129
+    this.updateSlides = new Update().getUpdateSlides();
140
 
130
 
141
     this.aprilFoolsSlides = [
131
     this.aprilFoolsSlides = [
142
       {
132
       {
175
           <View style={{height: '100%', flex: 1}}>
165
           <View style={{height: '100%', flex: 1}}>
176
             <View style={{flex: 1}}>{item.view()}</View>
166
             <View style={{flex: 1}}>{item.view()}</View>
177
             <Animatable.View useNativeDriver animation="fadeIn">
167
             <Animatable.View useNativeDriver animation="fadeIn">
178
-              {index !== 0 && index !== this.introSlides.length - 1 ? (
168
+              {item.mascotStyle != null ? (
179
                 <Mascot
169
                 <Mascot
180
                   style={{
170
                   style={{
181
                     marginLeft: 30,
171
                     marginLeft: 30,
244
     );
234
     );
245
   };
235
   };
246
 
236
 
247
-  getEndView = (): React.Node => {
248
-    return (
249
-      <View style={{flex: 1}}>
250
-        <Mascot
251
-          style={{
252
-            ...styles.center,
253
-            height: '80%',
254
-          }}
255
-          emotion={MASCOT_STYLE.COOL}
256
-          animated
257
-          entryAnimation={{
258
-            animation: 'slideInDown',
259
-            duration: 2000,
260
-          }}
261
-          loopAnimation={{
262
-            animation: 'pulse',
263
-            duration: 2000,
264
-            iterationCount: 'infinite',
265
-          }}
266
-        />
267
-      </View>
268
-    );
269
-  };
270
-
271
-  getWelcomeView = (): React.Node => {
272
-    return (
273
-      <View style={{flex: 1}}>
274
-        <Mascot
275
-          style={{
276
-            ...styles.center,
277
-            height: '80%',
278
-          }}
279
-          emotion={MASCOT_STYLE.NORMAL}
280
-          animated
281
-          entryAnimation={{
282
-            animation: 'bounceIn',
283
-            duration: 2000,
284
-          }}
285
-        />
286
-        <Animatable.Text
287
-          useNativeDriver
288
-          animation="fadeInUp"
289
-          duration={500}
290
-          style={{
291
-            color: '#fff',
292
-            textAlign: 'center',
293
-            fontSize: 25,
294
-          }}>
295
-          PABLO
296
-        </Animatable.Text>
297
-        <Animatable.View
298
-          useNativeDriver
299
-          animation="fadeInUp"
300
-          duration={500}
301
-          delay={200}
302
-          style={{
303
-            position: 'absolute',
304
-            bottom: 30,
305
-            right: '20%',
306
-            width: 50,
307
-            height: 50,
308
-          }}>
309
-          <MaterialCommunityIcons
310
-            style={{
311
-              ...styles.center,
312
-              transform: [{rotateZ: '70deg'}],
313
-            }}
314
-            name="undo"
315
-            color="#fff"
316
-            size={40}
317
-          />
318
-        </Animatable.View>
319
-      </View>
320
-    );
321
-  };
322
-
323
-  static getIconView(icon: MaterialCommunityIconsGlyphs): React.Node {
324
-    return (
325
-      <View style={{flex: 1}}>
326
-        <Animatable.View
327
-          useNativeDriver
328
-          style={styles.center}
329
-          animation="fadeIn">
330
-          <MaterialCommunityIcons name={icon} color="#fff" size={200} />
331
-        </Animatable.View>
332
-      </View>
333
-    );
334
-  }
335
-
336
   static setStatusBarColor(color: string) {
237
   static setStatusBarColor(color: string) {
337
     if (Platform.OS === 'android') StatusBar.setBackgroundColor(color, true);
238
     if (Platform.OS === 'android') StatusBar.setBackgroundColor(color, true);
338
   }
239
   }

+ 24
- 33
src/constants/Update.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import * as React from 'react';
3
 import i18n from 'i18n-js';
4
 import i18n from 'i18n-js';
5
+import type {IntroSlideType} from '../components/Overrides/CustomIntroSlider';
6
+import MascotIntroWelcome from '../components/Intro/MascotIntroWelcome';
7
+import IntroIcon from '../components/Intro/IconIntro';
4
 
8
 
5
 /**
9
 /**
6
  * Singleton used to manage update slides.
10
  * Singleton used to manage update slides.
15
  */
19
  */
16
 export default class Update {
20
 export default class Update {
17
   // Increment the number to show the update slide
21
   // Increment the number to show the update slide
18
-  static number = 6;
22
+  static number = 7;
19
 
23
 
20
-  // Change the number of slides to display
21
-  static slidesNumber = 4;
22
-
23
-  // Change the icons to be displayed on the update slide
24
-  static iconList = ['star', 'clock', 'qrcode-scan', 'account'];
25
-
26
-  static colorsList = [
27
-    ['#e01928', '#be1522'],
28
-    ['#7c33ec', '#5e11d1'],
29
-    ['#337aec', '#114ed1'],
30
-    ['#e01928', '#be1522'],
31
-  ];
32
-
33
-  static instance: Update | null = null;
34
-
35
-  titleList: Array<string>;
36
-
37
-  descriptionList: Array<string>;
24
+  updateSlides: Array<IntroSlideType>;
38
 
25
 
39
   /**
26
   /**
40
    * Init translations
27
    * Init translations
41
    */
28
    */
42
   constructor() {
29
   constructor() {
43
-    this.titleList = [];
44
-    this.descriptionList = [];
45
-    for (let i = 0; i < Update.slidesNumber; i += 1) {
46
-      this.titleList.push(i18n.t(`intro.updateSlide${i}.title`));
47
-      this.descriptionList.push(i18n.t(`intro.updateSlide${i}.text`));
48
-    }
30
+    this.updateSlides = [
31
+      {
32
+        key: '0',
33
+        title: i18n.t(`intro.updateSlide0.title`),
34
+        text: i18n.t(`intro.updateSlide0.text`),
35
+        view: (): React.Node => <MascotIntroWelcome />,
36
+        colors: ['#be1522', '#57080e'],
37
+      },
38
+      {
39
+        key: '1',
40
+        title: i18n.t(`intro.updateSlide1.title`),
41
+        text: i18n.t(`intro.updateSlide1.text`),
42
+        view: (): React.Node => <IntroIcon icon="account-heart-outline" />,
43
+        colors: ['#9c165b', '#3e042b'],
44
+      },
45
+    ];
49
   }
46
   }
50
 
47
 
51
-  /**
52
-   * Get this class instance or create one if none is found
53
-   *
54
-   * @returns {Update}
55
-   */
56
-  static getInstance(): Update {
57
-    if (Update.instance == null) Update.instance = new Update();
58
-    return Update.instance;
48
+  getUpdateSlides(): Array<IntroSlideType> {
49
+    return this.updateSlides;
59
   }
50
   }
60
 }
51
 }

Loading…
Cancel
Save