Browse Source

Improve intro slides usage

Arnaud Vergnet 1 year ago
parent
commit
a84a627fba

+ 3
- 11
locales/en.json View File

@@ -418,19 +418,11 @@
418 418
     },
419 419
     "updateSlide0": {
420 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 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 427
     "aprilFoolsSlide": {
436 428
       "title": "New in this update!",

+ 3
- 11
locales/fr.json View File

@@ -417,19 +417,11 @@
417 417
     },
418 418
     "updateSlide0": {
419 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 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 426
     "aprilFoolsSlide": {
435 427
       "title": "Nouveau dans cette mise à jour !",

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

@@ -0,0 +1,41 @@
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

@@ -0,0 +1,46 @@
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

@@ -0,0 +1,76 @@
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,7 +2,6 @@
2 2
 
3 3
 import * as React from 'react';
4 4
 import {Platform, StatusBar, StyleSheet, View} from 'react-native';
5
-import type {MaterialCommunityIconsGlyphs} from 'react-native-vector-icons/MaterialCommunityIcons';
6 5
 import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
7 6
 import i18n from 'i18n-js';
8 7
 import AppIntroSlider from 'react-native-app-intro-slider';
@@ -12,6 +11,9 @@ import {Card} from 'react-native-paper';
12 11
 import Update from '../../constants/Update';
13 12
 import ThemeManager from '../../managers/ThemeManager';
14 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 18
 type PropsType = {
17 19
   onDone: () => void,
@@ -23,12 +25,12 @@ type StateType = {
23 25
   currentSlide: number,
24 26
 };
25 27
 
26
-type IntroSlideType = {
28
+export type IntroSlideType = {
27 29
   key: string,
28 30
   title: string,
29 31
   text: string,
30 32
   view: () => React.Node,
31
-  mascotStyle: number,
33
+  mascotStyle?: number,
32 34
   colors: [string, string],
33 35
 };
34 36
 
@@ -88,15 +90,14 @@ export default class CustomIntroSlider extends React.Component<
88 90
         key: '0', // Mascot
89 91
         title: i18n.t('intro.slideMain.title'),
90 92
         text: i18n.t('intro.slideMain.text'),
91
-        view: this.getWelcomeView,
92
-        mascotStyle: MASCOT_STYLE.NORMAL,
93
+        view: (): React.Node => <MascotIntroWelcome />,
93 94
         colors: ['#be1522', '#57080e'],
94 95
       },
95 96
       {
96 97
         key: '1',
97 98
         title: i18n.t('intro.slidePlanex.title'),
98 99
         text: i18n.t('intro.slidePlanex.text'),
99
-        view: (): React.Node => CustomIntroSlider.getIconView('calendar-clock'),
100
+        view: (): React.Node => <IntroIcon icon="calendar-clock" />,
100 101
         mascotStyle: MASCOT_STYLE.INTELLO,
101 102
         colors: ['#be1522', '#57080e'],
102 103
       },
@@ -104,7 +105,7 @@ export default class CustomIntroSlider extends React.Component<
104 105
         key: '2',
105 106
         title: i18n.t('intro.slideEvents.title'),
106 107
         text: i18n.t('intro.slideEvents.text'),
107
-        view: (): React.Node => CustomIntroSlider.getIconView('calendar-star'),
108
+        view: (): React.Node => <IntroIcon icon="calendar-star" />,
108 109
         mascotStyle: MASCOT_STYLE.HAPPY,
109 110
         colors: ['#be1522', '#57080e'],
110 111
       },
@@ -112,8 +113,7 @@ export default class CustomIntroSlider extends React.Component<
112 113
         key: '3',
113 114
         title: i18n.t('intro.slideServices.title'),
114 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 117
         mascotStyle: MASCOT_STYLE.CUTE,
118 118
         colors: ['#be1522', '#57080e'],
119 119
       },
@@ -121,22 +121,12 @@ export default class CustomIntroSlider extends React.Component<
121 121
         key: '4',
122 122
         title: i18n.t('intro.slideDone.title'),
123 123
         text: i18n.t('intro.slideDone.text'),
124
-        view: (): React.Node => this.getEndView(),
125
-        mascotStyle: MASCOT_STYLE.COOL,
124
+        view: (): React.Node => <MascotIntroEnd />,
126 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 131
     this.aprilFoolsSlides = [
142 132
       {
@@ -175,7 +165,7 @@ export default class CustomIntroSlider extends React.Component<
175 165
           <View style={{height: '100%', flex: 1}}>
176 166
             <View style={{flex: 1}}>{item.view()}</View>
177 167
             <Animatable.View useNativeDriver animation="fadeIn">
178
-              {index !== 0 && index !== this.introSlides.length - 1 ? (
168
+              {item.mascotStyle != null ? (
179 169
                 <Mascot
180 170
                   style={{
181 171
                     marginLeft: 30,
@@ -244,95 +234,6 @@ export default class CustomIntroSlider extends React.Component<
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 237
   static setStatusBarColor(color: string) {
337 238
     if (Platform.OS === 'android') StatusBar.setBackgroundColor(color, true);
338 239
   }

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

@@ -1,6 +1,10 @@
1 1
 // @flow
2 2
 
3
+import * as React from 'react';
3 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 10
  * Singleton used to manage update slides.
@@ -15,46 +19,33 @@ import i18n from 'i18n-js';
15 19
  */
16 20
 export default class Update {
17 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 27
    * Init translations
41 28
    */
42 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