Sfoglia il codice sorgente

Merge platform modules

Mathieu Acthernoene 5 anni fa
parent
commit
c1e3251a22
4 ha cambiato i file con 211 aggiunte e 232 eliminazioni
  1. 9
    9
      README.md
  2. 202
    2
      index.js
  3. 0
    116
      lib/permissions.android.js
  4. 0
    105
      lib/permissions.ios.js

+ 9
- 9
README.md Vedi File

@@ -150,25 +150,25 @@ The current supported permissions are:
150 150
 
151 151
 |                    | Type                | iOS | Android |
152 152
 | ------------------ | ------------------- | --- | ------- |
153
-| Location           | `location`          | ✔️  | ✔       |
154 153
 | Camera             | `camera`            | ✔️  | ✔       |
155
-| Microphone         | `microphone`        | ✔️  | ✔       |
156
-| Photos             | `photo`             | ✔️  | ✔       |
157 154
 | Contacts           | `contacts`          | ✔️  | ✔       |
158 155
 | Events             | `event`             | ✔️  | ✔       |
159
-| Coarse location    | `coarseLocation`    | ❌  | ✔       |
160
-| Bluetooth          | `bluetooth`         | ✔️  | ❌      |
161
-| Reminders          | `reminder`          | ✔️  | ❌      |
162
-| Push Notifications | `notification`      | ✔️  | ❌      |
156
+| Location           | `location`          | ✔️  | ✔       |
157
+| Microphone         | `microphone`        | ✔️  | ✔       |
158
+| Photos             | `photo`             | ✔️  | ✔       |
163 159
 | Background Refresh | `backgroundRefresh` | ✔️  | ❌      |
164
-| Speech Recognition | `speechRecognition` | ✔️  | ❌      |
160
+| Bluetooth          | `bluetooth`         | ✔️  | ❌      |
165 161
 | Media Library      | `mediaLibrary`      | ✔️  | ❌      |
166 162
 | Motion Activity    | `motion`            | ✔️  | ❌      |
167
-| Storage            | `storage`           | ❌️ | ✔       |
163
+| Push Notifications | `notification`      | ✔️  | ❌      |
164
+| Reminders          | `reminder`          | ✔️  | ❌      |
165
+| Speech Recognition | `speechRecognition` | ✔️  | ❌      |
166
+| Coarse location    | `coarseLocation`    | ❌  | ✔       |
168 167
 | Phone Call         | `callPhone`         | ❌️ | ✔       |
169 168
 | Read SMS           | `readSms`           | ❌️ | ✔       |
170 169
 | Receive SMS        | `receiveSms`        | ❌️ | ✔       |
171 170
 | Send SMS           | `sendSms`           | ❌️ | ✔       |
171
+| Storage            | `storage`           | ❌️ | ✔       |
172 172
 
173 173
 ### Methods
174 174
 

+ 202
- 2
index.js Vedi File

@@ -1,4 +1,204 @@
1 1
 // @flow
2 2
 
3
-import Permissions from './lib/permissions';
4
-export default Permissions;
3
+import {NativeModules, PermissionsAndroid, Platform} from 'react-native';
4
+import AsyncStorage from '@react-native-community/async-storage';
5
+const NativeModule = NativeModules.ReactNativePermissions;
6
+
7
+export type PermissionStatus =
8
+  | 'authorized'
9
+  | 'denied'
10
+  | 'restricted'
11
+  | 'undetermined';
12
+
13
+export type Rationale = {
14
+  title: string,
15
+  message: string,
16
+  buttonPositive?: string,
17
+  buttonNegative?: string,
18
+  buttonNeutral?: string,
19
+};
20
+
21
+const ASYNC_STORAGE_KEY = '@RNPermissions:didAskPermission:';
22
+
23
+const PERMISSIONS = Platform.select({
24
+  ios: {
25
+    backgroundRefresh: 'backgroundRefresh',
26
+    bluetooth: 'bluetooth',
27
+    camera: 'camera',
28
+    contacts: 'contacts',
29
+    event: 'event',
30
+    location: 'location',
31
+    mediaLibrary: 'mediaLibrary',
32
+    microphone: 'microphone',
33
+    motion: 'motion',
34
+    notification: 'notification',
35
+    photo: 'photo',
36
+    reminder: 'reminder',
37
+    speechRecognition: 'speechRecognition',
38
+  },
39
+  android: {
40
+    callPhone: PermissionsAndroid.PERMISSIONS.CALL_PHONE,
41
+    camera: PermissionsAndroid.PERMISSIONS.CAMERA,
42
+    coarseLocation: PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
43
+    contacts: PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
44
+    event: PermissionsAndroid.PERMISSIONS.READ_CALENDAR,
45
+    location: PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
46
+    microphone: PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
47
+    photo: PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
48
+    readSms: PermissionsAndroid.PERMISSIONS.READ_SMS,
49
+    receiveSms: PermissionsAndroid.PERMISSIONS.RECEIVE_SMS,
50
+    sendSms: PermissionsAndroid.PERMISSIONS.SEND_SMS,
51
+    storage: PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
52
+  },
53
+});
54
+
55
+const IOS_DEFAULT_OPTIONS = {
56
+  location: 'whenInUse',
57
+  notification: ['alert', 'badge', 'sound'],
58
+};
59
+
60
+const ANDROID_RESULTS = {
61
+  granted: 'authorized',
62
+  denied: 'denied',
63
+  never_ask_again: 'restricted',
64
+};
65
+
66
+const setDidAskOnce = (permission: string) =>
67
+  AsyncStorage.setItem(ASYNC_STORAGE_KEY + permission, 'true');
68
+
69
+const getDidAskOnce = (permission: string) =>
70
+  AsyncStorage.getItem(ASYNC_STORAGE_KEY + permission).then(item => !!item);
71
+
72
+class ReactNativePermissions {
73
+  canOpenSettings(): Promise<boolean> {
74
+    return Platform.OS === 'ios'
75
+      ? NativeModule.canOpenSettings().then(result => !!result)
76
+      : Promise.resolve(false);
77
+  }
78
+
79
+  openSettings(): Promise<void> {
80
+    return Platform.OS === 'ios'
81
+      ? NativeModule.openSettings()
82
+      : Promise.reject(new Error("'openSettings' is deprecated on android"));
83
+  }
84
+
85
+  getTypes(): string[] {
86
+    return Object.keys(PERMISSIONS);
87
+  }
88
+
89
+  check = (
90
+    permission: string,
91
+    options?: string | {type?: string},
92
+  ): Promise<PermissionStatus> => {
93
+    if (!PERMISSIONS[permission]) {
94
+      return Promise.reject(
95
+        new Error(
96
+          `ReactNativePermissions: ${permission} is not a valid permission type`,
97
+        ),
98
+      );
99
+    }
100
+
101
+    if (Platform.OS === 'ios') {
102
+      let type = IOS_DEFAULT_OPTIONS[permission];
103
+
104
+      if (typeof options === 'string') {
105
+        type = options;
106
+      } else if (options && options.type) {
107
+        type = options.type;
108
+      }
109
+
110
+      return NativeModule.getPermissionStatus(permission, type);
111
+    }
112
+
113
+    if (Platform.OS === 'android') {
114
+      return PermissionsAndroid.check(PERMISSIONS[permission]).then(granted => {
115
+        if (granted) {
116
+          return 'authorized';
117
+        }
118
+
119
+        return getDidAskOnce(permission).then(didAsk => {
120
+          if (didAsk) {
121
+            return NativeModules.PermissionsAndroid.shouldShowRequestPermissionRationale(
122
+              PERMISSIONS[permission],
123
+            ).then(shouldShow => (shouldShow ? 'denied' : 'restricted'));
124
+          }
125
+
126
+          return 'undetermined';
127
+        });
128
+      });
129
+    }
130
+
131
+    return Promise.resolve('restricted');
132
+  };
133
+
134
+  request = (
135
+    permission: string,
136
+    options?: string | {type?: string, rationale?: Rationale},
137
+  ): Promise<PermissionStatus> => {
138
+    if (!PERMISSIONS[permission]) {
139
+      return Promise.reject(
140
+        new Error(
141
+          `ReactNativePermissions: ${permission} is not a valid permission type`,
142
+        ),
143
+      );
144
+    }
145
+
146
+    if (Platform.OS === 'ios') {
147
+      if (permission == 'backgroundRefresh') {
148
+        return Promise.reject(
149
+          new Error(
150
+            'ReactNativePermissions: You cannot request backgroundRefresh',
151
+          ),
152
+        );
153
+      }
154
+
155
+      let type = IOS_DEFAULT_OPTIONS[permission];
156
+
157
+      if (typeof options === 'string') {
158
+        type = options;
159
+      } else if (options && options.type) {
160
+        type = options.type;
161
+      }
162
+
163
+      return NativeModule.requestPermission(permission, type);
164
+    }
165
+
166
+    if (Platform.OS === 'android') {
167
+      let rationale: Rationale;
168
+
169
+      if (typeof options === 'object' && options.rationale) {
170
+        rationale = options.rationale;
171
+      }
172
+
173
+      return PermissionsAndroid.request(
174
+        PERMISSIONS[permission],
175
+        rationale,
176
+      ).then(result => {
177
+        // PermissionsAndroid.request() to native module resolves to boolean
178
+        // rather than string if running on OS version prior to Android M
179
+        if (typeof result === 'boolean') {
180
+          return result ? 'authorized' : 'denied';
181
+        }
182
+
183
+        return setDidAskOnce(permission).then(() => ANDROID_RESULTS[result]);
184
+      });
185
+    }
186
+
187
+    return Promise.resolve('restricted');
188
+  };
189
+
190
+  checkMultiple = (
191
+    permissions: string[],
192
+  ): Promise<{[permission: string]: PermissionStatus}> => {
193
+    return Promise.all(
194
+      permissions.map(permission => this.check(permission)),
195
+    ).then(result =>
196
+      result.reduce((acc, value, i) => {
197
+        acc[permissions[i]] = value;
198
+        return acc;
199
+      }, {}),
200
+    );
201
+  };
202
+}
203
+
204
+export default new ReactNativePermissions();

+ 0
- 116
lib/permissions.android.js Vedi File

@@ -1,116 +0,0 @@
1
-// @flow
2
-
3
-import {NativeModules, PermissionsAndroid} from 'react-native';
4
-import AsyncStorage from '@react-native-community/async-storage';
5
-
6
-type Status = 'authorized' | 'denied' | 'restricted' | 'undetermined';
7
-type Rationale = {title: string, message: string};
8
-type CheckOptions = string | {type: string};
9
-type RequestOptions = string | {type: string, rationale?: Rationale};
10
-
11
-const permissionTypes = {
12
-  location: PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
13
-  coarseLocation: RNPermissions.PERMISSIONS.ACCESS_COARSE_LOCATION,
14
-  camera: PermissionsAndroid.PERMISSIONS.CAMERA,
15
-  microphone: PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
16
-  contacts: PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
17
-  event: PermissionsAndroid.PERMISSIONS.READ_CALENDAR,
18
-  storage: PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
19
-  photo: PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
20
-  callPhone: PermissionsAndroid.PERMISSIONS.CALL_PHONE,
21
-  readSms: PermissionsAndroid.PERMISSIONS.READ_SMS,
22
-  receiveSms: PermissionsAndroid.PERMISSIONS.RECEIVE_SMS,
23
-  sendSms: PermissionsAndroid.PERMISSIONS.SEND_SMS,
24
-};
25
-
26
-const RESULTS = {
27
-  [PermissionsAndroid.RESULTS.GRANTED]: 'authorized',
28
-  [PermissionsAndroid.RESULTS.DENIED]: 'denied',
29
-  [PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN]: 'restricted',
30
-};
31
-
32
-const STORAGE_KEY = '@RNPermissions:didAskPermission:';
33
-
34
-const setDidAskOnce = (permission: string) =>
35
-  AsyncStorage.setItem(STORAGE_KEY + permission, 'true');
36
-
37
-const getDidAskOnce = (permission: string) =>
38
-  AsyncStorage.getItem(STORAGE_KEY + permission).then(item => !!item);
39
-
40
-class ReactNativePermissions {
41
-  canOpenSettings: () => Promise<boolean> = () => Promise.resolve(false);
42
-
43
-  openSettings: () => Promise<*> = () =>
44
-    Promise.reject(new Error("'openSettings' is deprecated on android"));
45
-
46
-  getTypes: () => Array<string> = () => Object.keys(permissionTypes);
47
-
48
-  check = (permission: string, options?: CheckOptions): Promise<Status> => {
49
-    if (!permissionTypes[permission]) {
50
-      const error = new Error(
51
-        `ReactNativePermissions: ${permission} is not a valid permission type on Android`,
52
-      );
53
-
54
-      return Promise.reject(error);
55
-    }
56
-
57
-    return PermissionsAndroid.check(permissionTypes[permission]).then(
58
-      isAuthorized => {
59
-        if (isAuthorized) {
60
-          return 'authorized';
61
-        }
62
-
63
-        return getDidAskOnce(permission).then(didAsk => {
64
-          if (didAsk) {
65
-            return NativeModules.PermissionsAndroid.shouldShowRequestPermissionRationale(
66
-              permissionTypes[permission],
67
-            ).then(shouldShow => (shouldShow ? 'denied' : 'restricted'));
68
-          }
69
-
70
-          return 'undetermined';
71
-        });
72
-      },
73
-    );
74
-  };
75
-
76
-  request = (permission: string, options?: RequestOptions): Promise<Status> => {
77
-    if (!permissionTypes[permission]) {
78
-      const error = new Error(
79
-        `ReactNativePermissions: ${permission} is not a valid permission type on Android`,
80
-      );
81
-
82
-      return Promise.reject(error);
83
-    }
84
-
85
-    let rationale;
86
-
87
-    if (options && options.rationale) {
88
-      rationale = options.rationale;
89
-    }
90
-
91
-    return PermissionsAndroid.request(
92
-      permissionTypes[permission],
93
-      rationale,
94
-    ).then(result => {
95
-      // PermissionsAndroid.request() to native module resolves to boolean
96
-      // rather than string if running on OS version prior to Android M
97
-      if (typeof result === 'boolean') {
98
-        return result ? 'authorized' : 'denied';
99
-      }
100
-
101
-      return setDidAskOnce(permission).then(() => RESULTS[result]);
102
-    });
103
-  };
104
-
105
-  checkMultiple = (permissions: Array<string>): Promise<{[string]: string}> =>
106
-    Promise.all(permissions.map(permission => this.check(permission))).then(
107
-      result =>
108
-        result.reduce((acc, value, index) => {
109
-          const name = permissions[index];
110
-          acc[name] = value;
111
-          return acc;
112
-        }, {}),
113
-    );
114
-}
115
-
116
-export default new ReactNativePermissions();

+ 0
- 105
lib/permissions.ios.js Vedi File

@@ -1,105 +0,0 @@
1
-// @flow
2
-
3
-import {NativeModules} from 'react-native';
4
-const PermissionsIOS = NativeModules.ReactNativePermissions;
5
-
6
-type Status = 'authorized' | 'denied' | 'restricted' | 'undetermined';
7
-type Rationale = {title: string, message: string};
8
-type CheckOptions = string | {type: string};
9
-type RequestOptions = string | {type: string, rationale?: Rationale};
10
-
11
-const permissionTypes = [
12
-  'location',
13
-  'camera',
14
-  'microphone',
15
-  'photo',
16
-  'contacts',
17
-  'event',
18
-  'reminder',
19
-  'bluetooth',
20
-  'notification',
21
-  'backgroundRefresh',
22
-  'speechRecognition',
23
-  'mediaLibrary',
24
-  'motion',
25
-];
26
-
27
-const DEFAULTS = {
28
-  location: 'whenInUse',
29
-  notification: ['alert', 'badge', 'sound'],
30
-};
31
-
32
-class ReactNativePermissions {
33
-  canOpenSettings: () => Promise<boolean> = () =>
34
-    PermissionsIOS.canOpenSettings().then(result => !!result);
35
-
36
-  openSettings: () => Promise<*> = () => PermissionsIOS.openSettings();
37
-
38
-  getTypes: () => Array<string> = () => permissionTypes;
39
-
40
-  check = (permission: string, options?: CheckOptions): Promise<Status> => {
41
-    if (!permissionTypes.includes(permission)) {
42
-      const error = new Error(
43
-        `ReactNativePermissions: ${permission} is not a valid permission type on iOS`,
44
-      );
45
-
46
-      return Promise.reject(error);
47
-    }
48
-
49
-    let type;
50
-
51
-    if (typeof options === 'string') {
52
-      type = options;
53
-    } else if (options && options.type) {
54
-      type = options.type;
55
-    }
56
-
57
-    return PermissionsIOS.getPermissionStatus(
58
-      permission,
59
-      type || DEFAULTS[permission],
60
-    );
61
-  };
62
-
63
-  request = (permission: string, options?: RequestOptions): Promise<Status> => {
64
-    if (!permissionTypes.includes(permission)) {
65
-      const error = new Error(
66
-        `ReactNativePermissions: ${permission} is not a valid permission type on iOS`,
67
-      );
68
-
69
-      return Promise.reject(error);
70
-    }
71
-
72
-    if (permission == 'backgroundRefresh') {
73
-      const error = new Error(
74
-        'ReactNativePermissions: You cannot request backgroundRefresh',
75
-      );
76
-
77
-      return Promise.reject(error);
78
-    }
79
-
80
-    let type;
81
-
82
-    if (typeof options === 'string') {
83
-      type = options;
84
-    } else if (options && options.type) {
85
-      type = options.type;
86
-    }
87
-
88
-    return PermissionsIOS.requestPermission(
89
-      permission,
90
-      type || DEFAULTS[permission],
91
-    );
92
-  };
93
-
94
-  checkMultiple = (permissions: Array<string>): Promise<{[string]: string}> =>
95
-    Promise.all(permissions.map(permission => this.check(permission))).then(
96
-      result =>
97
-        result.reduce((acc, value, index) => {
98
-          const name = permissions[index];
99
-          acc[name] = value;
100
-          return acc;
101
-        }, {}),
102
-    );
103
-}
104
-
105
-export default new ReactNativePermissions();