Skip to content

Commit c1e3251

Browse files
committed
Merge platform modules
1 parent 0a99bfa commit c1e3251

File tree

4 files changed

+211
-232
lines changed

4 files changed

+211
-232
lines changed

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -150,25 +150,25 @@ The current supported permissions are:
150150

151151
| | Type | iOS | Android |
152152
| ------------------ | ------------------- | --- | ------- |
153-
| Location | `location` | ✔️ ||
154153
| Camera | `camera` | ✔️ ||
155-
| Microphone | `microphone` | ✔️ ||
156-
| Photos | `photo` | ✔️ ||
157154
| Contacts | `contacts` | ✔️ ||
158155
| 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` | ✔️ ||
163159
| Background Refresh | `backgroundRefresh` | ✔️ ||
164-
| Speech Recognition | `speechRecognition` | ✔️ ||
160+
| Bluetooth | `bluetooth` | ✔️ ||
165161
| Media Library | `mediaLibrary` | ✔️ ||
166162
| Motion Activity | `motion` | ✔️ ||
167-
| Storage | `storage` | ❌️ ||
163+
| Push Notifications | `notification` | ✔️ ||
164+
| Reminders | `reminder` | ✔️ ||
165+
| Speech Recognition | `speechRecognition` | ✔️ ||
166+
| Coarse location | `coarseLocation` |||
168167
| Phone Call | `callPhone` | ❌️ ||
169168
| Read SMS | `readSms` | ❌️ ||
170169
| Receive SMS | `receiveSms` | ❌️ ||
171170
| Send SMS | `sendSms` | ❌️ ||
171+
| Storage | `storage` | ❌️ ||
172172

173173
### Methods
174174

index.js

Lines changed: 202 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,204 @@
11
// @flow
22

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();

lib/permissions.android.js

Lines changed: 0 additions & 116 deletions
This file was deleted.

0 commit comments

Comments
 (0)