Browse Source

Updated intro slides to make them shorter and include the mascot

Arnaud Vergnet 1 year ago
parent
commit
434d8b6565
4 changed files with 339 additions and 131 deletions
  1. 0
    8
      locales/en.json
  2. 11
    19
      locales/fr.json
  3. 131
    30
      src/components/Mascot/Mascot.js
  4. 197
    74
      src/components/Overrides/CustomIntroSlider.js

+ 0
- 8
locales/en.json View File

@@ -379,18 +379,10 @@
379 379
       "title": "Stay up to date",
380 380
       "text": "CAMPUS allows you to be aware of any event occurring on the campus, from pancake sales to Enfoiros concerts!"
381 381
     },
382
-    "slideProxiwash": {
383
-      "title": "Never forget your laundry",
384
-      "text": "CAMPUS will inform you on the availability of washing machines and will remind you just before yours finishes!"
385
-    },
386 382
     "slidePlanex": {
387 383
       "title": "Planex",
388 384
       "text": "Lookup your next course on CAMPUS with a mobile friendly timetable"
389 385
     },
390
-    "slideRU": {
391
-      "title": "RU Menu",
392
-      "text": "For the hungry, check this week's menu!"
393
-    },
394 386
     "slideServices": {
395 387
       "title": "More services!",
396 388
       "text": "You can do much more with CAMPUS, explore the app to find out"

+ 11
- 19
locales/fr.json View File

@@ -372,32 +372,24 @@
372 372
   },
373 373
   "intro": {
374 374
     "slideMain": {
375
-      "title": "Bienvenue sur CAMPUS",
376
-      "text": "La nouvelle appli à consulter pendant la pause café pour être au courant de la vie du campus !"
377
-    },
378
-    "slideEvents": {
379
-      "title": "Restez informés",
380
-      "text": "CAMPUS vous permet d'être au courant de tous les événements qui ont lieu sur le campus, de la vente de crêpes jusqu'aux concerts enfoiros !"
381
-    },
382
-    "slideProxiwash": {
383
-      "title": "N'oubliez plus votre linge !",
384
-      "text": "CAMPUS vous informe de la disponibilité des machines et vous permet d'être notifié lorsque la vôtre se termine bientôt !"
375
+      "title": "Bienvenue sur CAMPUS !",
376
+      "text": "L'appli du campus de l'INSA Toulouse ! Laisse toi guider pour comprendre tout ce que tu peux faire."
385 377
     },
386 378
     "slidePlanex": {
387
-      "title": "Planex",
388
-      "text": "Vérifiez votre prochain cours sur CAMPUS avec un emploi du temps adapté mobile"
379
+      "title": "Planex tout beau",
380
+      "text": "Regarde ton emploi du temps et celui de tes amis avec un Planex adapté mobile !"
389 381
     },
390
-    "slideRU": {
391
-      "title": "Menu du RU",
392
-      "text": "Pour ceux qui ont faim, vérifiez le menu du RU de la semaine !"
382
+    "slideEvents": {
383
+      "title": "Plein d'infos",
384
+      "text": "Sois au courant de tout ce qui se passe sur le campus, de la vente de crêpes jusqu'aux concerts Enfoiros !"
393 385
     },
394 386
     "slideServices": {
395
-      "title": "Encore plus de services !",
396
-      "text": "CAMPUS vous permet de faire bien plus, explorez l'appli pour savoir quoi"
387
+      "title": "Et plus encore !",
388
+      "text": "Tu peux faire bien plus avec CAMPUS, mais je n'ai pas le temps de tout dire ici. Balade toi sur l'appli pour tout découvrir !"
397 389
     },
398 390
     "slideDone": {
399
-      "title": "Fait par un étudiant",
400
-      "text": "Cette appli à été réalisée par un seul étudiant (avec un peu d'aide par-ci par-là), donc tous les retours sont les bienvenus !"
391
+      "title": "Réalisé par un étudiant",
392
+      "text": "Cette appli à été réalisée par un seul étudiant (avec un peu d'aide par-ci par-là), donc tes retours sont les bienvenus !"
401 393
     },
402 394
     "updateSlide0": {
403 395
       "title": "Nouveau dans cette mise à jour !",

+ 131
- 30
src/components/Mascot/Mascot.js View File

@@ -2,26 +2,46 @@
2 2
 
3 3
 import * as React from 'react';
4 4
 import * as Animatable from "react-native-animatable";
5
-import {Image, View} from "react-native-animatable";
5
+import {Image, TouchableWithoutFeedback, View} from "react-native";
6 6
 
7 7
 type Props = {
8 8
     size: number,
9 9
     emotion: number,
10 10
     animated: boolean,
11
+    entryAnimation: Animatable.AnimatableProperties | null,
12
+    loopAnimation: Animatable.AnimatableProperties | null,
13
+    onPress?: (viewRef: AnimatableViewRef) => null,
14
+    onLongPress?: (viewRef: AnimatableViewRef) => null,
11 15
 }
12 16
 
17
+type State = {
18
+    currentEmotion: number,
19
+}
20
+
21
+export type AnimatableViewRef = {current: null | Animatable.View};
22
+
13 23
 const MASCOT_IMAGE = require("../../../assets/mascot/mascot.png");
14 24
 const MASCOT_EYES_NORMAL = require("../../../assets/mascot/mascot_eyes_normal.png");
15 25
 const MASCOT_EYES_GIRLY = require("../../../assets/mascot/mascot_eyes_girly.png");
16 26
 const MASCOT_EYES_CUTE = require("../../../assets/mascot/mascot_eyes_cute.png");
17 27
 const MASCOT_EYES_WINK = require("../../../assets/mascot/mascot_eyes_wink.png");
28
+const MASCOT_EYES_HEART = require("../../../assets/mascot/mascot_eyes_heart.png");
29
+const MASCOT_EYES_ANGRY = require("../../../assets/mascot/mascot_eyes_angry.png");
18 30
 const MASCOT_GLASSES = require("../../../assets/mascot/mascot_glasses.png");
31
+const MASCOT_SUNGLASSES = require("../../../assets/mascot/mascot_sunglasses.png");
19 32
 
20 33
 export const EYE_STYLE = {
21 34
     NORMAL: 0,
22 35
     GIRLY: 2,
23 36
     CUTE: 3,
24 37
     WINK: 4,
38
+    HEART: 5,
39
+    ANGRY: 6,
40
+}
41
+
42
+const GLASSES_STYLE = {
43
+    NORMAL: 0,
44
+    COOl: 1
25 45
 }
26 46
 
27 47
 export const MASCOT_STYLE = {
@@ -31,30 +51,96 @@ export const MASCOT_STYLE = {
31 51
     WINK: 3,
32 52
     CUTE: 4,
33 53
     INTELLO: 5,
54
+    LOVE: 6,
55
+    COOL: 7,
56
+    ANGRY: 8,
34 57
 };
35 58
 
36 59
 
37
-class Mascot extends React.Component<Props> {
60
+class Mascot extends React.Component<Props, State> {
61
+
62
+    state = {
63
+        currentEmotion: this.props.emotion
64
+    }
38 65
 
39 66
     static defaultProps = {
40
-        animated: false
67
+        animated: false,
68
+        entryAnimation: {
69
+            useNativeDriver: true,
70
+            animation: "rubberBand",
71
+            duration: 2000,
72
+        },
73
+        loopAnimation: {
74
+            useNativeDriver: true,
75
+            animation: "swing",
76
+            duration: 2000,
77
+            iterationDelay: 250,
78
+            iterationCount: "infinite",
79
+        },
80
+        clickAnimation: {
81
+            useNativeDriver: true,
82
+            animation: "rubberBand",
83
+            duration: 2000,
84
+        },
41 85
     }
42 86
 
43
-    eyeList: { [key: number]: number | string }
87
+    viewRef: AnimatableViewRef;
88
+    eyeList: { [key: number]: number | string };
89
+    glassesList: { [key: number]: number | string };
90
+
91
+    onPress: (viewRef: AnimatableViewRef) => null;
92
+    onLongPress: (viewRef: AnimatableViewRef) => null;
44 93
 
45 94
     constructor(props: Props) {
46 95
         super(props);
96
+        this.viewRef = React.createRef();
47 97
         this.eyeList = {};
98
+        this.glassesList = {};
48 99
         this.eyeList[EYE_STYLE.NORMAL] = MASCOT_EYES_NORMAL;
49 100
         this.eyeList[EYE_STYLE.GIRLY] = MASCOT_EYES_GIRLY;
50 101
         this.eyeList[EYE_STYLE.CUTE] = MASCOT_EYES_CUTE;
51 102
         this.eyeList[EYE_STYLE.WINK] = MASCOT_EYES_WINK;
103
+        this.eyeList[EYE_STYLE.HEART] = MASCOT_EYES_HEART;
104
+        this.eyeList[EYE_STYLE.ANGRY] = MASCOT_EYES_ANGRY;
105
+
106
+        this.glassesList[GLASSES_STYLE.NORMAL] = MASCOT_GLASSES;
107
+        this.glassesList[GLASSES_STYLE.COOl] = MASCOT_SUNGLASSES;
108
+
109
+        if (this.props.onPress == null) {
110
+            this.onPress = (viewRef: AnimatableViewRef) => {
111
+                if (viewRef.current != null) {
112
+                    this.setState({currentEmotion: MASCOT_STYLE.LOVE});
113
+                    viewRef.current.rubberBand(1500).then(() => {
114
+                        this.setState({currentEmotion: this.props.emotion});
115
+                    });
116
+
117
+                }
118
+                return null;
119
+            }
120
+        } else
121
+            this.onPress = this.props.onPress;
122
+
123
+        if (this.props.onLongPress == null) {
124
+            this.onLongPress = (viewRef: AnimatableViewRef) => {
125
+                if (viewRef.current != null) {
126
+                    this.setState({currentEmotion: MASCOT_STYLE.ANGRY});
127
+                    viewRef.current.tada(1000).then(() => {
128
+                        this.setState({currentEmotion: this.props.emotion});
129
+                    });
130
+
131
+                }
132
+                return null;
133
+            }
134
+        } else
135
+            this.onLongPress = this.props.onLongPress;
136
+
52 137
     }
53 138
 
54
-    getGlasses() {
139
+    getGlasses(style: number) {
140
+        const glasses = this.glassesList[style];
55 141
         return <Image
56 142
             key={"glasses"}
57
-            source={MASCOT_GLASSES}
143
+            source={glasses != null ? glasses : this.glassesList[GLASSES_STYLE.NORMAL]}
58 144
             style={{
59 145
                 position: "absolute",
60 146
                 top: "15%",
@@ -65,7 +151,7 @@ class Mascot extends React.Component<Props> {
65 151
         />
66 152
     }
67 153
 
68
-    getEye(style: number, isRight: boolean) {
154
+    getEye(style: number, isRight: boolean, rotation: string="0deg") {
69 155
         const eye = this.eyeList[style];
70 156
         return <Image
71 157
             key={isRight ? "right" : "left"}
@@ -76,6 +162,7 @@ class Mascot extends React.Component<Props> {
76 162
                 left: isRight ? "-11%" : "11%",
77 163
                 width: this.props.size,
78 164
                 height: this.props.size,
165
+                transform: [{rotateY: rotation}]
79 166
             }}
80 167
         />
81 168
     }
@@ -85,10 +172,10 @@ class Mascot extends React.Component<Props> {
85 172
         final.push(<View
86 173
             key={"container"}
87 174
             style={{
88
-            position: "absolute",
89
-            width: this.props.size,
90
-            height: this.props.size,
91
-        }}/>);
175
+                position: "absolute",
176
+                width: this.props.size,
177
+                height: this.props.size,
178
+            }}/>);
92 179
         if (emotion === MASCOT_STYLE.CUTE) {
93 180
             final.push(this.getEye(EYE_STYLE.CUTE, true));
94 181
             final.push(this.getEye(EYE_STYLE.CUTE, false));
@@ -101,13 +188,21 @@ class Mascot extends React.Component<Props> {
101 188
         } else if (emotion === MASCOT_STYLE.WINK) {
102 189
             final.push(this.getEye(EYE_STYLE.WINK, true));
103 190
             final.push(this.getEye(EYE_STYLE.NORMAL, false));
191
+        } else if (emotion === MASCOT_STYLE.LOVE) {
192
+            final.push(this.getEye(EYE_STYLE.HEART, true));
193
+            final.push(this.getEye(EYE_STYLE.HEART, false));
194
+        } else if (emotion === MASCOT_STYLE.ANGRY) {
195
+            final.push(this.getEye(EYE_STYLE.ANGRY, true));
196
+            final.push(this.getEye(EYE_STYLE.ANGRY, false, "180deg"));
197
+        } else if (emotion === MASCOT_STYLE.COOL) {
198
+            final.push(this.getGlasses(GLASSES_STYLE.COOl));
104 199
         } else {
105 200
             final.push(this.getEye(EYE_STYLE.NORMAL, true));
106 201
             final.push(this.getEye(EYE_STYLE.NORMAL, false));
107 202
         }
108 203
 
109
-        if (emotion === MASCOT_STYLE.INTELLO) {
110
-            final.push(this.getGlasses())
204
+        if (emotion === MASCOT_STYLE.INTELLO) { // Needs to have normal eyes behind the glasses
205
+            final.push(this.getGlasses(GLASSES_STYLE.NORMAL));
111 206
         }
112 207
         final.push(<View key={"container2"}/>);
113 208
         return final;
@@ -115,31 +210,37 @@ class Mascot extends React.Component<Props> {
115 210
 
116 211
     render() {
117 212
         const size = this.props.size;
213
+        const entryAnimation = this.props.animated ? this.props.entryAnimation : null;
214
+        const loopAnimation = this.props.animated ? this.props.loopAnimation : null;
118 215
         return (
119 216
             <Animatable.View
120 217
                 style={{
121 218
                     width: size,
122 219
                     height: size,
123 220
                 }}
124
-                useNativeDriver={true}
125
-                animation={this.props.animated ? "rubberBand" : null}
126
-                duration={2000}
221
+                {...entryAnimation}
127 222
             >
128
-                <View
129
-                    useNativeDriver={true}
130
-                    animation={this.props.animated ? "swing" : null}
131
-                    duration={2000}
132
-                    iterationCount={"infinite"}
223
+                <TouchableWithoutFeedback
224
+                    onPress={() => this.onPress(this.viewRef)}
225
+                    onLongPress={() => this.onLongPress(this.viewRef)}
133 226
                 >
134
-                    <Image
135
-                        source={MASCOT_IMAGE}
136
-                        style={{
137
-                            width: size,
138
-                            height: size,
139
-                        }}
140
-                    />
141
-                    {this.getEyes(this.props.emotion)}
142
-                </View>
227
+                    <Animatable.View
228
+                        ref={this.viewRef}
229
+                    >
230
+                        <Animatable.View
231
+                            {...loopAnimation}
232
+                        >
233
+                            <Image
234
+                                source={MASCOT_IMAGE}
235
+                                style={{
236
+                                    width: size,
237
+                                    height: size,
238
+                                }}
239
+                            />
240
+                            {this.getEyes(this.state.currentEmotion)}
241
+                        </Animatable.View>
242
+                    </Animatable.View>
243
+                </TouchableWithoutFeedback>
143 244
             </Animatable.View>
144 245
         );
145 246
     }

+ 197
- 74
src/components/Overrides/CustomIntroSlider.js View File

@@ -1,14 +1,17 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {Image, 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";
5 6
 import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
6
-import {Text} from "react-native-paper";
7 7
 import i18n from 'i18n-js';
8 8
 import AppIntroSlider from "react-native-app-intro-slider";
9 9
 import Update from "../../constants/Update";
10 10
 import ThemeManager from "../../managers/ThemeManager";
11 11
 import LinearGradient from 'react-native-linear-gradient';
12
+import Mascot, {MASCOT_STYLE} from "../Mascot/Mascot";
13
+import * as Animatable from "react-native-animatable";
14
+import {Card} from "react-native-paper";
12 15
 
13 16
 type Props = {
14 17
     onDone: Function,
@@ -16,17 +19,34 @@ type Props = {
16 19
     isAprilFools: boolean,
17 20
 };
18 21
 
22
+type State = {
23
+    currentSlide: number,
24
+}
25
+
26
+type Slide = {
27
+    key: string,
28
+    title: string,
29
+    text: string,
30
+    view: () => React.Node,
31
+    mascotStyle: number,
32
+    colors: [string, string]
33
+};
34
+
19 35
 /**
20 36
  * Class used to create intro slides
21 37
  */
22
-export default class CustomIntroSlider extends React.Component<Props> {
38
+export default class CustomIntroSlider extends React.Component<Props, State> {
23 39
 
24
-    sliderRef: {current: null | AppIntroSlider};
40
+    state = {
41
+        currentSlide: 0,
42
+    }
25 43
 
26
-    introSlides: Array<Object>;
27
-    updateSlides: Array<Object>;
28
-    aprilFoolsSlides: Array<Object>;
29
-    currentSlides: Array<Object>;
44
+    sliderRef: { current: null | AppIntroSlider };
45
+
46
+    introSlides: Array<Slide>;
47
+    updateSlides: Array<Slide>;
48
+    aprilFoolsSlides: Array<Slide>;
49
+    currentSlides: Array<Slide>;
30 50
 
31 51
     /**
32 52
      * Generates intro slides
@@ -36,53 +56,44 @@ export default class CustomIntroSlider extends React.Component<Props> {
36 56
         this.sliderRef = React.createRef();
37 57
         this.introSlides = [
38 58
             {
39
-                key: 'main',
59
+                key: '0', // Mascot
40 60
                 title: i18n.t('intro.slideMain.title'),
41 61
                 text: i18n.t('intro.slideMain.text'),
42
-                image: require('../../../assets/splash.png'),
43
-                colors: ['#be1522', '#740d15'],
62
+                view: this.getWelcomeView,
63
+                mascotStyle: MASCOT_STYLE.NORMAL,
64
+                colors: ['#be1522', '#57080e'],
44 65
             },
45 66
             {
46
-                key: 'Planex',
67
+                key: '1',
47 68
                 title: i18n.t('intro.slidePlanex.title'),
48 69
                 text: i18n.t('intro.slidePlanex.text'),
49
-                icon: 'timetable',
50
-                colors: ['#e77020', '#803e12'],
51
-            },
52
-            {
53
-                key: 'RU',
54
-                title: i18n.t('intro.slideRU.title'),
55
-                text: i18n.t('intro.slideRU.text'),
56
-                icon: 'silverware-fork-knife',
57
-                colors: ['#dcac18', '#8b6a15'],
70
+                view: () => this.getIconView("calendar-clock"),
71
+                mascotStyle: MASCOT_STYLE.INTELLO,
72
+                colors: ['#be1522', '#57080e'],
58 73
             },
59 74
             {
60
-                key: 'events',
75
+                key: '2',
61 76
                 title: i18n.t('intro.slideEvents.title'),
62 77
                 text: i18n.t('intro.slideEvents.text'),
63
-                icon: 'calendar-range',
64
-                colors: ['#41a006', '#095c03'],
78
+                view: () => this.getIconView("calendar-star",),
79
+                mascotStyle: MASCOT_STYLE.HAPPY,
80
+                colors: ['#be1522', '#57080e'],
65 81
             },
66 82
             {
67
-                key: 'proxiwash',
68
-                title: i18n.t('intro.slideProxiwash.title'),
69
-                text: i18n.t('intro.slideProxiwash.text'),
70
-                icon: 'washing-machine',
71
-                colors: ['#1fa5ee', '#06537d'],
72
-            },
73
-            {
74
-                key: 'services',
83
+                key: '3',
75 84
                 title: i18n.t('intro.slideServices.title'),
76 85
                 text: i18n.t('intro.slideServices.text'),
77
-                icon: 'view-dashboard-variant',
78
-                colors: ['#6737c1', '#281a5a'],
86
+                view: () => this.getIconView("view-dashboard-variant",),
87
+                mascotStyle: MASCOT_STYLE.CUTE,
88
+                colors: ['#be1522', '#57080e'],
79 89
             },
80 90
             {
81
-                key: 'done',
91
+                key: '4',
82 92
                 title: i18n.t('intro.slideDone.title'),
83 93
                 text: i18n.t('intro.slideDone.text'),
84
-                icon: 'account-heart',
85
-                colors: ['#b837c1', '#501a5a'],
94
+                view: () => this.getIconView("account-heart",),
95
+                mascotStyle: MASCOT_STYLE.COOL,
96
+                colors: ['#9c165b', '#3e042b'],
86 97
             },
87 98
         ];
88 99
         this.updateSlides = [];
@@ -103,50 +114,127 @@ export default class CustomIntroSlider extends React.Component<Props> {
103 114
                 key: '1',
104 115
                 title: i18n.t('intro.aprilFoolsSlide.title'),
105 116
                 text: i18n.t('intro.aprilFoolsSlide.text'),
106
-                icon: 'fish',
117
+                view: () => <View/>,
118
+                mascotStyle: MASCOT_STYLE.NORMAL,
107 119
                 colors: ['#e01928', '#be1522'],
108 120
             },
109 121
         ];
110 122
     }
111 123
 
112
-
113 124
     /**
114 125
      * Render item to be used for the intro introSlides
115 126
      *
116 127
      * @param item The item to be displayed
117 128
      * @param dimensions Dimensions of the item
118 129
      */
119
-    static getIntroRenderItem({item, dimensions}: Object) {
130
+    getIntroRenderItem = ({item, dimensions}: { item: Slide, dimensions: { width: number, height: number } }) => {
131
+        const index = parseInt(item.key);
120 132
         return (
121 133
             <LinearGradient
122 134
                 style={[
123 135
                     styles.mainContent,
124
-                    dimensions,
136
+                    dimensions
125 137
                 ]}
126 138
                 colors={item.colors}
127 139
                 start={{x: 0, y: 0.1}}
128 140
                 end={{x: 0.1, y: 1}}
129 141
             >
130
-                {item.image !== undefined ?
131
-                    <View style={styles.image}>
132
-                        <Image
133
-                            source={item.image}
134
-                            resizeMode={"contain"}
135
-                            style={{width: '100%', height: '100%'}}
136
-                            />
137
-                    </View>
138
-                    : <MaterialCommunityIcons
139
-                        name={item.icon}
140
-                        color={'#fff'}
141
-                        size={200}/>}
142
-                <View style={{marginTop: 20}}>
143
-                    <Text style={styles.title}>{item.title}</Text>
144
-                    <Text style={styles.text}>{item.text}</Text>
145
-                </View>
142
+                {this.state.currentSlide === index
143
+                    ? <View style={{height: "100%", flex: 1}}>
144
+                        <View style={{flex: 1}}>
145
+                            {item.view()}
146
+                        </View>
147
+                        <Animatable.View
148
+                            animation={"fadeIn"}>
149
+                            {index !== 0
150
+                                ? <Animatable.View
151
+                                    animation={"pulse"}
152
+                                    iterationCount={"infinite"}
153
+                                    duration={2000}
154
+                                    style={{
155
+                                        marginLeft: 30,
156
+                                        marginBottom: 0,
157
+                                        width: 80
158
+                                    }}>
159
+                                    <Mascot emotion={item.mascotStyle} size={80}/>
160
+                                </Animatable.View> : null}
161
+
162
+                            <View style={{
163
+                                marginLeft: 50,
164
+                                width: 0,
165
+                                height: 0,
166
+                                borderLeftWidth: 20,
167
+                                borderRightWidth: 0,
168
+                                borderBottomWidth: 20,
169
+                                borderStyle: 'solid',
170
+                                backgroundColor: 'transparent',
171
+                                borderLeftColor: 'transparent',
172
+                                borderRightColor: 'transparent',
173
+                                borderBottomColor: "rgba(0,0,0,0.60)",
174
+                            }}/>
175
+                            <Card style={{
176
+                                backgroundColor: "rgba(0,0,0,0.38)",
177
+                                marginHorizontal: 20,
178
+                                borderColor: "rgba(0,0,0,0.60)",
179
+                                borderWidth: 4,
180
+                                borderRadius: 10,
181
+                            }}>
182
+                                <Card.Content>
183
+                                    <Animatable.Text
184
+                                        animation={"fadeIn"}
185
+                                        delay={100}
186
+                                        style={styles.title}>
187
+                                        {item.title}
188
+                                    </Animatable.Text>
189
+                                    <Animatable.Text
190
+                                        animation={"fadeIn"}
191
+                                        delay={200}
192
+                                        style={styles.text}>
193
+                                        {item.text}
194
+                                    </Animatable.Text>
195
+                                </Card.Content>
196
+                            </Card>
197
+                        </Animatable.View>
198
+                    </View> : null}
146 199
             </LinearGradient>
147 200
         );
148 201
     }
149 202
 
203
+    getWelcomeView = () => {
204
+        return (
205
+            <View style={{flex: 1}}>
206
+                <View
207
+                    style={styles.center}>
208
+                    <Mascot
209
+                        size={250}
210
+                        emotion={MASCOT_STYLE.NORMAL}
211
+                        animated={true}
212
+                        entryAnimation={{
213
+                            animation: "bounceIn",
214
+                            duration: 2000,
215
+                        }}
216
+                    />
217
+                </View>
218
+            </View>
219
+        )
220
+    }
221
+
222
+    getIconView(icon: MaterialCommunityIconsGlyphs) {
223
+        return (
224
+            <View style={{flex: 1}}>
225
+                <Animatable.View
226
+                    style={styles.center}
227
+                    animation={"fadeIn"}
228
+                >
229
+                    <MaterialCommunityIcons
230
+                        name={icon}
231
+                        color={'#fff'}
232
+                        size={200}/>
233
+                </Animatable.View>
234
+            </View>
235
+        )
236
+    }
237
+
150 238
     setStatusBarColor(color: string) {
151 239
         if (Platform.OS === 'android')
152 240
             StatusBar.setBackgroundColor(color, true);
@@ -154,12 +242,13 @@ export default class CustomIntroSlider extends React.Component<Props> {
154 242
 
155 243
     onSlideChange = (index: number, lastIndex: number) => {
156 244
         this.setStatusBarColor(this.currentSlides[index].colors[0]);
245
+        this.setState({currentSlide: index});
157 246
     };
158 247
 
159 248
     onSkip = () => {
160
-        this.setStatusBarColor(this.currentSlides[this.currentSlides.length-1].colors[0]);
249
+        this.setStatusBarColor(this.currentSlides[this.currentSlides.length - 1].colors[0]);
161 250
         if (this.sliderRef.current != null)
162
-            this.sliderRef.current.goToSlide(this.currentSlides.length-1);
251
+            this.sliderRef.current.goToSlide(this.currentSlides.length - 1);
163 252
     }
164 253
 
165 254
     onDone = () => {
@@ -167,6 +256,42 @@ export default class CustomIntroSlider extends React.Component<Props> {
167 256
         this.props.onDone();
168 257
     }
169 258
 
259
+    renderNextButton = () => {
260
+        return (
261
+            <Animatable.View
262
+                animation={"fadeIn"}
263
+
264
+                style={{
265
+                    borderRadius: 25,
266
+                    padding: 5,
267
+                    backgroundColor: "rgba(0,0,0,0.2)"
268
+                }}>
269
+                <MaterialCommunityIcons
270
+                    name={"arrow-right"}
271
+                    color={'#fff'}
272
+                    size={40}/>
273
+            </Animatable.View>
274
+        )
275
+    }
276
+
277
+    renderDoneButton = () => {
278
+        return (
279
+            <Animatable.View
280
+                animation={"bounceIn"}
281
+
282
+                style={{
283
+                    borderRadius: 25,
284
+                    padding: 5,
285
+                    backgroundColor: "rgb(190,21,34)"
286
+                }}>
287
+                <MaterialCommunityIcons
288
+                    name={"check"}
289
+                    color={'#fff'}
290
+                    size={40}/>
291
+            </Animatable.View>
292
+        )
293
+    }
294
+
170 295
     render() {
171 296
         this.currentSlides = this.introSlides;
172 297
         if (this.props.isUpdate)
@@ -177,16 +302,16 @@ export default class CustomIntroSlider extends React.Component<Props> {
177 302
         return (
178 303
             <AppIntroSlider
179 304
                 ref={this.sliderRef}
180
-                renderItem={CustomIntroSlider.getIntroRenderItem}
181 305
                 data={this.currentSlides}
306
+                extraData={this.state.currentSlide}
307
+
308
+                renderItem={this.getIntroRenderItem}
309
+                renderNextButton={this.renderNextButton}
310
+                renderDoneButton={this.renderDoneButton}
311
+
182 312
                 onDone={this.onDone}
183
-                bottomButton
184
-                showSkipButton
185 313
                 onSlideChange={this.onSlideChange}
186 314
                 onSkip={this.onSkip}
187
-                skipLabel={i18n.t('intro.buttons.skip')}
188
-                doneLabel={i18n.t('intro.buttons.done')}
189
-                nextLabel={i18n.t('intro.buttons.next')}
190 315
             />
191 316
         );
192 317
     }
@@ -196,15 +321,7 @@ export default class CustomIntroSlider extends React.Component<Props> {
196 321
 
197 322
 const styles = StyleSheet.create({
198 323
     mainContent: {
199
-        flex: 1,
200
-        alignItems: 'center',
201
-        justifyContent: 'center',
202
-        paddingBottom: 100
203
-    },
204
-    image: {
205
-        width: 300,
206
-        height: 300,
207
-        marginBottom: -50,
324
+        paddingBottom: 100,
208 325
     },
209 326
     text: {
210 327
         color: 'rgba(255, 255, 255, 0.8)',
@@ -219,4 +336,10 @@ const styles = StyleSheet.create({
219 336
         textAlign: 'center',
220 337
         marginBottom: 16,
221 338
     },
339
+    center: {
340
+        marginTop: 'auto',
341
+        marginBottom: 'auto',
342
+        marginRight: 'auto',
343
+        marginLeft: 'auto',
344
+    }
222 345
 });

Loading…
Cancel
Save