Arnaud Vergnet 3 years ago
parent
commit
e1014a173e

+ 2
- 3
App.js View File

@@ -60,7 +60,6 @@ export default class App extends React.Component<Props, State> {
60 60
     constructor() {
61 61
         super();
62 62
         LocaleManager.initTranslations();
63
-        // SplashScreen.preventAutoHide();
64 63
         this.navigatorRef = React.createRef();
65 64
         this.defaultHomeRoute = null;
66 65
         this.defaultHomeData = {};
@@ -71,8 +70,7 @@ export default class App extends React.Component<Props, State> {
71 70
         this.loadAssetsAsync().then(() => {
72 71
             this.onLoadFinished();
73 72
         });
74
-        // console.log(Linking.makeUrl('path/into/app', { hello: 'world', goodbye: 'now' }))
75
-        console.log(global.HermesInternal !== null);
73
+        console.log("USING HERMES:" + global.HermesInternal !== null);
76 74
     }
77 75
 
78 76
     /**
@@ -176,6 +174,7 @@ export default class App extends React.Component<Props, State> {
176 174
             showUpdate: this.storageManager.preferences.updateNumber.current !== Update.number.toString(),
177 175
             showAprilFools: AprilFoolsManager.getInstance().isAprilFoolsEnabled() && this.storageManager.preferences.showAprilFoolsStart.current === '1',
178 176
         });
177
+        console.log('hiding splash');
179 178
         SplashScreen.hide();
180 179
     }
181 180
 

+ 7
- 0
__mocks__/react-native-keychain/index.js View File

@@ -0,0 +1,7 @@
1
+const keychainMock = {
2
+    SECURITY_LEVEL_ANY: "MOCK_SECURITY_LEVEL_ANY",
3
+    SECURITY_LEVEL_SECURE_SOFTWARE: "MOCK_SECURITY_LEVEL_SECURE_SOFTWARE",
4
+    SECURITY_LEVEL_SECURE_HARDWARE: "MOCK_SECURITY_LEVEL_SECURE_HARDWARE",
5
+}
6
+
7
+export default keychainMock;

+ 2
- 40
__tests__/managers/ConnectionManager.test.js View File

@@ -1,7 +1,8 @@
1
+jest.mock('react-native-keychain');
2
+
1 3
 import React from 'react';
2 4
 import ConnectionManager from "../../src/managers/ConnectionManager";
3 5
 import {ERROR_TYPE} from "../../src/utils/WebData";
4
-import * as SecureStore from 'expo-secure-store';
5 6
 
6 7
 let fetch = require('isomorphic-fetch'); // fetch is not implemented in nodeJS but in react-native
7 8
 
@@ -25,45 +26,6 @@ test('isLoggedIn no', () => {
25 26
     return expect(c.isLoggedIn()).toBe(false);
26 27
 });
27 28
 
28
-test('recoverLogin error crypto', () => {
29
-    jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => {
30
-        return Promise.reject();
31
-    });
32
-    return expect(c.recoverLogin()).rejects.toBe(false);
33
-});
34
-
35
-test('recoverLogin success crypto', () => {
36
-    jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => {
37
-        return Promise.resolve('token1');
38
-    });
39
-    return expect(c.recoverLogin()).resolves.toBe('token1');
40
-});
41
-
42
-test('saveLogin success', () => {
43
-    jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => {
44
-        return Promise.resolve();
45
-    });
46
-    return expect(c.saveLogin('email', 'token2')).resolves.toBeTruthy();
47
-});
48
-
49
-test('saveLogin error', () => {
50
-    jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => {
51
-        return Promise.reject();
52
-    });
53
-    return expect(c.saveLogin('email', 'token3')).rejects.toBeFalsy();
54
-});
55
-
56
-test('recoverLogin error crypto with saved token', () => {
57
-    jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => {
58
-        return Promise.reject();
59
-    });
60
-    return expect(c.recoverLogin()).resolves.toBe('token2');
61
-});
62
-
63
-test('recoverLogin success saved', () => {
64
-    return expect(c.recoverLogin()).resolves.toBe('token2');
65
-});
66
-
67 29
 test("isConnectionResponseValid", () => {
68 30
     let json = {
69 31
         error: 0,

+ 3
- 18
android/app/src/main/AndroidManifest.xml View File

@@ -1,24 +1,9 @@
1 1
 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="fr.amicaleinsat.application">
2 2
   <uses-permission android:name="android.permission.INTERNET"/>
3
-  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
4
-  <uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
5
-  <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
6
-  <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
7
-  <uses-permission android:name="android.permission.USE_FINGERPRINT"/>
8
-  <uses-permission android:name="android.permission.VIBRATE"/>
9
-  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
10
-  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
11
-  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
12 3
   <uses-permission android:name="android.permission.CAMERA" />
13
-  <uses-permission android:name="android.permission.READ_CONTACTS"/>
14
-  <uses-permission android:name="android.permission.READ_CALENDAR"/>
15
-  <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
16
-  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
17
-  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
18
-  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
19
-  <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
20
-  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
21
-  <uses-permission android:name="android.permission.WAKE_LOCK"/>
4
+  <uses-permission android:name="android.permission.VIBRATE"/>
5
+  <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
6
+
22 7
   <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
23 8
   <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme">
24 9
     <meta-data android:name="com.facebook.sdk.AutoInitEnabled" android:value="false"/>

+ 0
- 2
android/app/src/main/java/fr/amicaleinsat/application/generated/BasePackageList.java View File

@@ -16,10 +16,8 @@ public class BasePackageList {
16 16
         new expo.modules.imageloader.ImageLoaderPackage(),
17 17
         new expo.modules.keepawake.KeepAwakePackage(),
18 18
         new expo.modules.lineargradient.LinearGradientPackage(),
19
-        new expo.modules.localization.LocalizationPackage(),
20 19
         new expo.modules.location.LocationPackage(),
21 20
         new expo.modules.permissions.PermissionsPackage(),
22
-        new expo.modules.securestore.SecureStorePackage(),
23 21
         new expo.modules.sqlite.SQLitePackage(),
24 22
         new expo.modules.webbrowser.WebBrowserPackage()
25 23
     );

+ 0
- 2
clear-node-cache.sh View File

@@ -16,5 +16,3 @@ echo "Installing dependencies..."
16 16
 npm install
17 17
 echo -e "Done\n"
18 18
 
19
-echo "Starting expo with clear cache..."
20
-expo r -c

+ 0
- 20
ios/Campus/Info.plist View File

@@ -52,28 +52,8 @@
52 52
 			</dict>
53 53
 		</dict>
54 54
 	</dict>
55
-	<key>NSCalendarsUsageDescription</key>
56
-	<string>Allow Campus to access your calendar</string>
57 55
 	<key>NSCameraUsageDescription</key>
58 56
 	<string>Allow Campus to use the camera</string>
59
-	<key>NSContactsUsageDescription</key>
60
-	<string>Allow Campus experiences to access your contacts</string>
61
-	<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
62
-	<string>Allow Campus to use your location</string>
63
-	<key>NSLocationAlwaysUsageDescription</key>
64
-	<string>Allow Campus to use your location</string>
65
-	<key>NSLocationWhenInUseUsageDescription</key>
66
-	<string>Allow Campus to use your location</string>
67
-	<key>NSMicrophoneUsageDescription</key>
68
-	<string>Allow Campus to access your microphone</string>
69
-	<key>NSMotionUsageDescription</key>
70
-	<string>Allow Campus to access your device's accelerometer</string>
71
-	<key>NSPhotoLibraryAddUsageDescription</key>
72
-	<string>Give Campus periences permission to save photos</string>
73
-	<key>NSPhotoLibraryUsageDescription</key>
74
-	<string>Give Campus periences permission to access your photos</string>
75
-	<key>NSRemindersUsageDescription</key>
76
-	<string>Allow Campus to access your reminders</string>
77 57
 	<key>UILaunchStoryboardName</key>
78 58
 	<string>LaunchScreen</string>
79 59
 	<key>UIRequiredDeviceCapabilities</key>

+ 6
- 0
ios/Podfile View File

@@ -44,4 +44,10 @@ target 'Campus' do
44 44
   # react-native-cli autolinking
45 45
   use_native_modules!
46 46
 
47
+  # Permissions
48
+  permissions_path = '../node_modules/react-native-permissions/ios'
49
+
50
+  pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications.podspec"
51
+  pod 'Permission-Camera', :path => "#{permissions_path}/Camera.podspec"
52
+
47 53
 end

+ 4
- 4
package.json View File

@@ -27,10 +27,6 @@
27 27
     "expo": "^37.0.0",
28 28
     "expo-barcode-scanner": "~8.1.0",
29 29
     "expo-camera": "latest",
30
-    "expo-linear-gradient": "~8.1.0",
31
-    "expo-localization": "~8.1.0",
32
-    "expo-permissions": "~8.1.0",
33
-    "expo-secure-store": "~8.1.0",
34 30
     "i18n-js": "^3.3.0",
35 31
     "react": "~16.9.0",
36 32
     "react-dom": "16.9.0",
@@ -43,8 +39,12 @@
43 39
     "react-native-collapsible": "^1.5.2",
44 40
     "react-native-gesture-handler": "~1.6.0",
45 41
     "react-native-image-modal": "^1.0.6",
42
+    "react-native-keychain": "^6.0.0",
43
+    "react-native-linear-gradient": "^2.5.6",
44
+    "react-native-localize": "^1.4.0",
46 45
     "react-native-modalize": "^1.3.6",
47 46
     "react-native-paper": "^3.8.0",
47
+    "react-native-permissions": "^2.1.3",
48 48
     "react-native-reanimated": "~1.7.0",
49 49
     "react-native-render-html": "^4.1.2",
50 50
     "react-native-safe-area-context": "0.7.3",

+ 1
- 2
src/components/Overrides/CustomHTML.js View File

@@ -1,7 +1,7 @@
1 1
 import * as React from 'react';
2 2
 import {Text, withTheme} from 'react-native-paper';
3 3
 import HTML from "react-native-render-html";
4
-import {Linking} from "expo";
4
+import {Linking} from "react-native";
5 5
 
6 6
 type Props = {
7 7
     theme: Object,
@@ -18,7 +18,6 @@ class CustomHTML extends React.Component<Props> {
18 18
     };
19 19
 
20 20
     getBasicText = (htmlAttribs, children, convertedCSSStyles, passProps) => {
21
-        // console.log(convertedCSSStyles);
22 21
         return <Text {...passProps}>{children}</Text>;
23 22
     };
24 23
 

+ 8
- 8
src/components/Overrides/CustomIntroSlider.js View File

@@ -1,7 +1,6 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {LinearGradient} from "expo-linear-gradient";
5 4
 import {Image, Platform, StatusBar, StyleSheet, View} from "react-native";
6 5
 import {MaterialCommunityIcons} from "@expo/vector-icons";
7 6
 import {Text} from "react-native-paper";
@@ -9,6 +8,7 @@ import i18n from 'i18n-js';
9 8
 import AppIntroSlider from "react-native-app-intro-slider";
10 9
 import Update from "../../constants/Update";
11 10
 import ThemeManager from "../../managers/ThemeManager";
11
+import LinearGradient from 'react-native-linear-gradient';
12 12
 
13 13
 type Props = {
14 14
     onDone: Function,
@@ -40,49 +40,49 @@ export default class CustomIntroSlider extends React.Component<Props> {
40 40
                 title: i18n.t('intro.slide1.title'),
41 41
                 text: i18n.t('intro.slide1.text'),
42 42
                 image: require('../../../assets/splash.png'),
43
-                colors: ['#e01928', '#be1522'],
43
+                colors: ['#dc2634', '#be1522'],
44 44
             },
45 45
             {
46 46
                 key: '2',
47 47
                 title: i18n.t('intro.slide2.title'),
48 48
                 text: i18n.t('intro.slide2.text'),
49 49
                 icon: 'calendar-range',
50
-                colors: ['#d99e09', '#c28d08'],
50
+                colors: ['#d99e09', '#9e7205'],
51 51
             },
52 52
             {
53 53
                 key: '3',
54 54
                 title: i18n.t('intro.slide3.title'),
55 55
                 text: i18n.t('intro.slide3.text'),
56 56
                 icon: 'washing-machine',
57
-                colors: ['#1fa5ee', '#1c97da'],
57
+                colors: ['#1fa5ee', '#0976b1'],
58 58
             },
59 59
             {
60 60
                 key: '4',
61 61
                 title: i18n.t('intro.slide4.title'),
62 62
                 text: i18n.t('intro.slide4.text'),
63 63
                 icon: 'shopping',
64
-                colors: ['#ec5904', '#da5204'],
64
+                colors: ['#ec5904', '#b64300'],
65 65
             },
66 66
             {
67 67
                 key: '5',
68 68
                 title: i18n.t('intro.slide5.title'),
69 69
                 text: i18n.t('intro.slide5.text'),
70 70
                 icon: 'timetable',
71
-                colors: ['#7c33ec', '#732fda'],
71
+                colors: ['#7c33ec', '#5e11d1'],
72 72
             },
73 73
             {
74 74
                 key: '6',
75 75
                 title: i18n.t('intro.slide6.title'),
76 76
                 text: i18n.t('intro.slide6.text'),
77 77
                 icon: 'silverware-fork-knife',
78
-                colors: ['#ec1213', '#ff372f'],
78
+                colors: ['#ec1213', '#970902'],
79 79
             },
80 80
             {
81 81
                 key: '7',
82 82
                 title: i18n.t('intro.slide7.title'),
83 83
                 text: i18n.t('intro.slide7.text'),
84 84
                 icon: 'cogs',
85
-                colors: ['#37c13e', '#26852b'],
85
+                colors: ['#37c13e', '#1a5a1d'],
86 86
             },
87 87
         ];
88 88
         this.updateSlides = [

+ 1
- 2
src/components/Screens/WebViewScreen.js View File

@@ -7,9 +7,8 @@ import ErrorView from "./ErrorView";
7 7
 import {ERROR_TYPE} from "../../utils/WebData";
8 8
 import MaterialHeaderButtons, {Item} from '../Overrides/CustomHeaderButton';
9 9
 import {HiddenItem} from "react-navigation-header-buttons";
10
-import {Linking} from "expo";
11 10
 import i18n from 'i18n-js';
12
-import {Animated, BackHandler} from "react-native";
11
+import {Animated, BackHandler, Linking} from "react-native";
13 12
 import {withCollapsible} from "../../utils/withCollapsible";
14 13
 
15 14
 type Props = {

+ 12
- 13
src/managers/ConnectionManager.js View File

@@ -1,6 +1,6 @@
1 1
 // @flow
2 2
 
3
-import * as SecureStore from 'expo-secure-store';
3
+import * as Keychain from 'react-native-keychain';
4 4
 import {apiRequest, ERROR_TYPE, isResponseValid} from "../utils/WebData";
5 5
 
6 6
 /**
@@ -14,7 +14,7 @@ import {apiRequest, ERROR_TYPE, isResponseValid} from "../utils/WebData";
14 14
  * 500 : SERVER_ERROR -> pb coté serveur
15 15
  */
16 16
 
17
-
17
+const SERVER_NAME = "amicale-insat.fr";
18 18
 const AUTH_PATH = "password";
19 19
 
20 20
 export default class ConnectionManager {
@@ -60,16 +60,16 @@ export default class ConnectionManager {
60 60
             if (this.getToken() !== null)
61 61
                 resolve(this.getToken());
62 62
             else {
63
-                SecureStore.getItemAsync('token')
64
-                    .then((token) => {
65
-                        this.#token = token;
66
-                        if (token !== null) {
63
+                Keychain.getInternetCredentials(SERVER_NAME)
64
+                    .then((data) => {
65
+                        if (data) {
66
+                            this.#token = data.password;
67 67
                             this.onLoginStateChange(true);
68
-                            resolve(token);
68
+                            resolve(this.#token);
69 69
                         } else
70 70
                             reject(false);
71 71
                     })
72
-                    .catch(error => {
72
+                    .catch(() => {
73 73
                         reject(false);
74 74
                     });
75 75
             }
@@ -82,14 +82,14 @@ export default class ConnectionManager {
82 82
 
83 83
     async saveLogin(email: string, token: string) {
84 84
         return new Promise((resolve, reject) => {
85
-            SecureStore.setItemAsync('token', token)
85
+            Keychain.setInternetCredentials(SERVER_NAME, 'token', token)
86 86
                 .then(() => {
87 87
                     this.#token = token;
88 88
                     this.#email = email;
89 89
                     this.onLoginStateChange(true);
90 90
                     resolve(true);
91 91
                 })
92
-                .catch(error => {
92
+                .catch(() => {
93 93
                     reject(false);
94 94
                 });
95 95
         });
@@ -97,13 +97,13 @@ export default class ConnectionManager {
97 97
 
98 98
     async disconnect() {
99 99
         return new Promise((resolve, reject) => {
100
-            SecureStore.deleteItemAsync('token')
100
+            Keychain.resetInternetCredentials(SERVER_NAME)
101 101
                 .then(() => {
102 102
                     this.#token = null;
103 103
                     this.onLoginStateChange(false);
104 104
                     resolve(true);
105 105
                 })
106
-                .catch((error) => {
106
+                .catch(() => {
107 107
                     reject(false);
108 108
                 });
109 109
         });
@@ -143,7 +143,6 @@ export default class ConnectionManager {
143 143
     async authenticatedRequest(path: string, params: Object) {
144 144
         return new Promise((resolve, reject) => {
145 145
             if (this.getToken() !== null) {
146
-                // console.log(data);
147 146
                 let data = {
148 147
                     token: this.getToken(),
149 148
                     ...params

+ 3
- 3
src/managers/LocaleManager.js View File

@@ -1,7 +1,7 @@
1 1
 // @flow
2 2
 
3 3
 import i18n from 'i18n-js';
4
-import * as Localization from 'expo-localization';
4
+import * as RNLocalize from "react-native-localize";
5 5
 
6 6
 import en from '../../translations/en';
7 7
 import fr from '../../translations/fr';
@@ -17,10 +17,10 @@ export default class LocaleManager {
17 17
     static initTranslations() {
18 18
         i18n.fallbacks = true;
19 19
         i18n.translations = {fr, en};
20
-        i18n.locale = Localization.locale;
20
+        i18n.locale = RNLocalize.findBestAvailableLanguage(["en", "fr"]).languageTag;
21 21
     }
22 22
 
23 23
     static getCurrentLocale() {
24
-        return Localization.locale;
24
+        return RNLocalize.findBestAvailableLanguage(["en", "fr"]).languageTag;
25 25
     }
26 26
 }

+ 1
- 2
src/screens/Amicale/AmicaleContactScreen.js View File

@@ -1,10 +1,9 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {Animated, FlatList, Image, View} from 'react-native';
4
+import {Animated, FlatList, Image, Linking, View} from 'react-native';
5 5
 import {Card, List, Text, withTheme} from 'react-native-paper';
6 6
 import i18n from 'i18n-js';
7
-import {Linking} from "expo";
8 7
 import {Collapsible} from "react-navigation-collapsible";
9 8
 import CustomTabBar from "../../components/Tabbar/CustomTabBar";
10 9
 import {withCollapsible} from "../../utils/withCollapsible";

+ 1
- 2
src/screens/Amicale/Clubs/ClubDisplayScreen.js View File

@@ -1,7 +1,7 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {ScrollView, View} from 'react-native';
4
+import {Linking, ScrollView, View} from 'react-native';
5 5
 import {Avatar, Button, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
6 6
 import ImageModal from 'react-native-image-modal';
7 7
 import i18n from "i18n-js";
@@ -11,7 +11,6 @@ import CustomTabBar from "../../../components/Tabbar/CustomTabBar";
11 11
 import type {category, club} from "./ClubListScreen";
12 12
 import type {CustomTheme} from "../../../managers/ThemeManager";
13 13
 import {StackNavigationProp} from "@react-navigation/stack";
14
-import {Linking} from "expo";
15 14
 import {ERROR_TYPE} from "../../../utils/WebData";
16 15
 
17 16
 type Props = {

+ 1
- 2
src/screens/Amicale/LoginScreen.js View File

@@ -1,7 +1,7 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {Animated, KeyboardAvoidingView, StyleSheet, View} from "react-native";
4
+import {Animated, KeyboardAvoidingView, Linking, StyleSheet, View} from "react-native";
5 5
 import {Avatar, Button, Card, HelperText, Paragraph, TextInput, withTheme} from 'react-native-paper';
6 6
 import ConnectionManager from "../../managers/ConnectionManager";
7 7
 import i18n from 'i18n-js';
@@ -10,7 +10,6 @@ import {withCollapsible} from "../../utils/withCollapsible";
10 10
 import {Collapsible} from "react-navigation-collapsible";
11 11
 import CustomTabBar from "../../components/Tabbar/CustomTabBar";
12 12
 import type {CustomTheme} from "../../managers/ThemeManager";
13
-import {Linking} from "expo";
14 13
 
15 14
 type Props = {
16 15
     navigation: Object,

+ 1
- 2
src/screens/Home/FeedItemScreen.js View File

@@ -1,12 +1,11 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {ScrollView, View} from 'react-native';
4
+import {Linking, ScrollView, View} from 'react-native';
5 5
 import {Avatar, Card, Text, withTheme} from 'react-native-paper';
6 6
 import ImageModal from 'react-native-image-modal';
7 7
 import Autolink from "react-native-autolink";
8 8
 import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
9
-import {Linking} from "expo";
10 9
 import CustomTabBar from "../../components/Tabbar/CustomTabBar";
11 10
 
12 11
 type Props = {

+ 1
- 2
src/screens/Home/ScannerScreen.js View File

@@ -1,12 +1,11 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {StyleSheet, View} from "react-native";
4
+import {Linking, StyleSheet, View} from "react-native";
5 5
 import {Button, Text, withTheme} from 'react-native-paper';
6 6
 import {BarCodeScanner} from "expo-barcode-scanner";
7 7
 import {Camera} from 'expo-camera';
8 8
 import URLHandler from "../../utils/URLHandler";
9
-import {Linking} from "expo";
10 9
 import AlertDialog from "../../components/Dialogs/AlertDialog";
11 10
 import i18n from 'i18n-js';
12 11
 import CustomTabBar from "../../components/Tabbar/CustomTabBar";

+ 1
- 2
src/screens/Other/FeedbackScreen.js View File

@@ -3,8 +3,7 @@
3 3
 import * as React from 'react';
4 4
 import {Avatar, Button, Card, Paragraph, withTheme} from "react-native-paper";
5 5
 import i18n from "i18n-js";
6
-import {ScrollView} from "react-native";
7
-import {Linking} from "expo";
6
+import {Linking, ScrollView} from "react-native";
8 7
 import type {CustomTheme} from "../../managers/ThemeManager";
9 8
 
10 9
 type Props = {

+ 0
- 1
src/screens/Planning/PlanningScreen.js View File

@@ -228,7 +228,6 @@ class PlanningScreen extends React.Component<Props, State> {
228 228
     }
229 229
 
230 230
     render() {
231
-        // console.log("rendering PlanningScreen");
232 231
         return (
233 232
             <CustomAgenda
234 233
                 {...this.props}

+ 23
- 14
src/utils/Notifications.js View File

@@ -1,6 +1,6 @@
1 1
 // @flow
2 2
 
3
-import * as Permissions from 'expo-permissions';
3
+import {checkNotifications, requestNotifications, RESULTS} from 'react-native-permissions';
4 4
 import {Notifications} from 'expo';
5 5
 import AsyncStorageManager from "../managers/AsyncStorageManager";
6 6
 import LocaleManager from "../managers/LocaleManager";
@@ -14,13 +14,22 @@ const EXPO_TOKEN_SERVER = 'https://etud.insa-toulouse.fr/~amicale_app/expo_notif
14 14
  * @returns {Promise}
15 15
  */
16 16
 export async function askPermissions() {
17
-    const {status: existingStatus} = await Permissions.getAsync(Permissions.NOTIFICATIONS);
18
-    let finalStatus = existingStatus;
19
-    if (existingStatus !== 'granted') {
20
-        const {status} = await Permissions.askAsync(Permissions.NOTIFICATIONS);
21
-        finalStatus = status;
22
-    }
23
-    return finalStatus === 'granted';
17
+    return new Promise(((resolve, reject) => {
18
+        checkNotifications().then(({status, settings}) => {
19
+            if (status === RESULTS.GRANTED)
20
+                resolve();
21
+            else if (status === RESULTS.BLOCKED)
22
+                reject()
23
+            else {
24
+                requestNotifications().then(({status, settings}) => {
25
+                    if (status === RESULTS.GRANTED)
26
+                        resolve();
27
+                    else
28
+                        reject();
29
+                });
30
+            }
31
+        });
32
+    }));
24 33
 }
25 34
 
26 35
 /**
@@ -33,12 +42,12 @@ export async function askPermissions() {
33 42
 export async function initExpoToken() {
34 43
     let token = AsyncStorageManager.getInstance().preferences.expoToken.current;
35 44
     if (token === '') {
36
-        try {
37
-            await askPermissions();
38
-            let expoToken = await Notifications.getExpoPushTokenAsync();
39
-            // Save token for instant use later on
40
-            AsyncStorageManager.getInstance().savePref(AsyncStorageManager.getInstance().preferences.expoToken.key, expoToken);
41
-        } catch (e) {}
45
+        askPermissions().then(() => {
46
+            Notifications.getExpoPushTokenAsync().then((token) => {
47
+                // Save token for instant use later on
48
+                AsyncStorageManager.getInstance().savePref(AsyncStorageManager.getInstance().preferences.expoToken.key, token);
49
+            });
50
+        });
42 51
     }
43 52
 }
44 53
 

Loading…
Cancel
Save