Skip to content

Commit d969b46

Browse files
authored
Merge pull request #530 from bzoz/windows
Add Windows support
2 parents 98e8f03 + a9882a9 commit d969b46

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+8728
-101
lines changed

README.md

Lines changed: 114 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22

33
[![npm version](https://badge.fury.io/js/react-native-permissions.svg)](https://badge.fury.io/js/react-native-permissions)
44
[![npm](https://img.shields.io/npm/dt/react-native-permissions.svg)](https://www.npmjs.org/package/react-native-permissions)
5-
![Platform - Android and iOS](https://img.shields.io/badge/platform-Android%20%7C%20iOS-yellow.svg)
5+
![Platform - Android, iOS and Windows](https://img.shields.io/badge/platform-Android%20%7C%20iOS%20%7C%20Windows-yellow.svg)
66
![MIT](https://img.shields.io/dub/l/vibe-d.svg)
77
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
88

9-
A unified permissions API for React Native on iOS and Android.
9+
A unified permissions API for React Native on iOS, Android and Windows.
10+
11+
For Windows only builds 18362 and later are supported.
1012

1113
## Support
1214

13-
| version | react-native version |
14-
| ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
15-
| 2.0.0+ | 0.60.2+ |
15+
| version | react-native version |
16+
| ------- | -------------------- |
17+
| 2.0.0+ | 0.60.2+ |
1618

1719
## Setup
1820

@@ -173,9 +175,13 @@ Add all wanted permissions to your app `android/app/src/main/AndroidManifest.xml
173175
</manifest>
174176
```
175177

178+
### Windows
179+
180+
Open the project solution file from the `windows` folder. In the app project open `Package.appxmanifest` file. From there you can select which capabilites you want your app to support.
181+
176182
## 🆘 Manual linking
177183

178-
Because this package targets React Native 0.60.0+, you probably won't need to link it manually. Otherwise if it's not the case, follow these additional instructions:
184+
Because this package targets React Native 0.60.0+, you probably won't need to link it manually. Otherwise if it's not the case, follow these additional instructions. You also need to manual link the module on Windows when using React Native Windows prior to 0.63:
179185

180186
<details>
181187
<summary><b>👀 See manual linking instructions</b></summary>
@@ -231,6 +237,23 @@ public class MainApplication extends Application implements ReactApplication {
231237
}
232238
```
233239

240+
### Windows
241+
242+
1. In `windows/myapp.sln` add the `RNCConfig` project to your solution:
243+
244+
- Open the solution in Visual Studio 2019
245+
- Right-click Solution icon in Solution Explorer > Add > Existing Project
246+
- Select `node_modules\react-native-permissions\windows\RNPermissions\RNPermissions.vcxproj`
247+
248+
2. In `windows/myapp/myapp.vcxproj` ad a reference to `RNPermissions` to your main application project. From Visual Studio 2019:
249+
250+
- Right-click main application project > Add > Reference...
251+
- Check `RNPermissions` from Solution Projects.
252+
253+
3. In `pch.h` add `#include "winrt/RNPermissions.h"`.
254+
255+
4. In `app.cpp` add `PackageProviders().Append(winrt::RNPermissions::ReactPackageProvider());` before `InitializeComponent();`.
256+
234257
</details>
235258

236259
## Understanding permission flow
@@ -337,6 +360,56 @@ As permissions are not handled in the same way on iOS and Android, this library
337360
└─────────────────┘ └─────────────────┘
338361
```
339362

363+
### Windows flow
364+
365+
```
366+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
367+
┃ check(PERMISSIONS.WINDOWS.WEBCAM) ┃
368+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
369+
370+
Is the feature available
371+
on this device ?
372+
│ ╔════╗
373+
├───────────║ NO ║──────────────┐
374+
│ ╚════╝ │
375+
╔═════╗ ▼
376+
║ YES ║ ┌─────────────────────┐
377+
╚═════╝ │ RESULTS.UNAVAILABLE │
378+
│ └─────────────────────┘
379+
Is the permission
380+
requestable ?
381+
│ ╔════╗
382+
├───────────║ NO ║──────────────┐
383+
│ ╚════╝ │
384+
╔═════╗ ▼
385+
║ YES ║ ┌───────────────────┐
386+
╚═════╝ │ RESULTS.BLOCKED / │
387+
│ │ RESULTS.GRANTED │
388+
▼ └───────────────────┘
389+
┌────────────────┐
390+
│ RESULTS.DENIED │
391+
└────────────────┘
392+
393+
394+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
395+
┃ request(PERMISSIONS.WINDOWS.WEBCAM) ┃
396+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
397+
398+
Does the user accept
399+
the request ?
400+
│ ╔════╗
401+
├───────────║ NO ║──────────────┐
402+
│ ╚════╝ │
403+
╔═════╗ ▼
404+
║ YES ║ ┌─────────────────┐
405+
╚═════╝ │ RESULTS.BLOCKED │
406+
│ └─────────────────┘
407+
408+
┌─────────────────┐
409+
│ RESULTS.GRANTED │
410+
└─────────────────┘
411+
```
412+
340413
## API
341414

342415
### Supported permissions
@@ -394,6 +467,38 @@ PERMISSIONS.IOS.REMINDERS;
394467
PERMISSIONS.IOS.SIRI;
395468
PERMISSIONS.IOS.SPEECH_RECOGNITION;
396469
PERMISSIONS.IOS.STOREKIT;
470+
471+
// Windows permissions
472+
473+
PERMISSIONS.WINDOWS.APPOINTMENTS;
474+
PERMISSIONS.WINDOWS.BLOCKED_CHAT_MESSAGES;
475+
PERMISSIONS.WINDOWS.BLUETOOTH_GATT;
476+
PERMISSIONS.WINDOWS.BLUETOOTH_RFCOMM;
477+
PERMISSIONS.WINDOWS.CHAT;
478+
PERMISSIONS.WINDOWS.CODE_GENERATION;
479+
PERMISSIONS.WINDOWS.CONTACTS;
480+
PERMISSIONS.WINDOWS.DOCUMENTS_LIBRARY;
481+
PERMISSIONS.WINDOWS.ENTERPRISE_AUTHENTICATION;
482+
PERMISSIONS.WINDOWS.HUMAN_INTERFACE_DEVICE;
483+
PERMISSIONS.WINDOWS.INTERNET_CLIENT;
484+
PERMISSIONS.WINDOWS.INTERNET_CLIENT_SERVER;
485+
PERMISSIONS.WINDOWS.LOCATION;
486+
PERMISSIONS.WINDOWS.MICROPHONE;
487+
PERMISSIONS.WINDOWS.MUSIC_LIBRARY;
488+
PERMISSIONS.WINDOWS.OBJECTS_3D;
489+
PERMISSIONS.WINDOWS.PHONE_CALL;
490+
PERMISSIONS.WINDOWS.PHOTO_LIBRARY;
491+
PERMISSIONS.WINDOWS.POINT_OF_SERVICE;
492+
PERMISSIONS.WINDOWS.PRIVATE_NETWORK_CLIENT_SERVER;
493+
PERMISSIONS.WINDOWS.PROXIMITY;
494+
PERMISSIONS.WINDOWS.RECORDED_CALLS_FOLDER;
495+
PERMISSIONS.WINDOWS.REMOVABLE_STORAGE;
496+
PERMISSIONS.WINDOWS.SHARED_USER_CERTIFICATES;
497+
PERMISSIONS.WINDOWS.USB;
498+
PERMISSIONS.WINDOWS.USER_ACCOUNT_INFORMATION;
499+
PERMISSIONS.WINDOWS.VIDEOS_LIBRARY;
500+
PERMISSIONS.WINDOWS.VOIP_CALL;
501+
PERMISSIONS.WINDOWS.WEBCAM;
397502
```
398503

399504
### Permissions statuses
@@ -519,6 +624,8 @@ checkNotifications().then(({status, settings}) => {
519624

520625
Request notifications permission status and get notifications settings values.
521626

627+
You cannot request notifications permissions on Windows. Disabling or enabling notifications can only be done through the App Settings.
628+
522629
```ts
523630
// only used on iOS
524631
type NotificationOption =
@@ -637,6 +744,7 @@ request(
637744
Platform.select({
638745
android: PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
639746
ios: PERMISSIONS.IOS.LOCATION_WHEN_IN_USE,
747+
windows: PERMISSIONS.WINDOWS.LOCATION,
640748
}),
641749
);
642750
```

example/App.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ import theme from './theme';
1414
const {SIRI, ...PERMISSIONS_IOS} = PERMISSIONS.IOS; // remove siri (certificate required)
1515

1616
const PLATFORM_PERMISSIONS = Platform.select<
17-
typeof PERMISSIONS_IOS | typeof PERMISSIONS.ANDROID | {}
17+
| typeof PERMISSIONS_IOS
18+
| typeof PERMISSIONS.ANDROID
19+
| typeof PERMISSIONS.WINDOWS
20+
| {}
1821
>({
1922
ios: PERMISSIONS_IOS,
2023
android: PERMISSIONS.ANDROID,
24+
windows: PERMISSIONS.WINDOWS,
2125
default: {},
2226
});
2327

@@ -46,7 +50,10 @@ const PermissionRow = ({
4650
status: string;
4751
onPress: () => void;
4852
}) => (
49-
<TouchableRipple onPress={onPress}>
53+
<TouchableRipple
54+
onPress={onPress}
55+
accessible={true}
56+
accessibilityLabel={`${name}:${status}`}>
5057
<List.Item
5158
right={() => <List.Icon color={colors[status]} icon={icons[status]} />}
5259
title={name}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import {driver, By2} from 'selenium-appium';
2+
import {until} from 'selenium-webdriver';
3+
4+
const setup = require('../jest-setups/jest.setup');
5+
jest.setTimeout(50000);
6+
7+
beforeAll(() => {
8+
return driver.startWithCapabilities(setup.capabilites);
9+
});
10+
11+
afterAll(() => {
12+
return driver.quit();
13+
});
14+
15+
describe('Test App', () => {
16+
test('Permissions present', async () => {
17+
await driver.wait(
18+
until.elementLocated(By2.nativeName('CODE_GENERATION:granted')),
19+
);
20+
await driver.wait(
21+
until.elementLocated(By2.nativeName('DOCUMENTS_LIBRARY:unavailable')),
22+
);
23+
await driver.wait(until.elementLocated(By2.nativeName('CONTACTS:denied')));
24+
await driver.wait(until.elementLocated(By2.nativeName('LOCATION:blocked')));
25+
});
26+
});

example/jest-setups/jest.setup.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* eslint-disable no-undef */
2+
import {windowsAppDriverCapabilities} from 'selenium-appium';
3+
4+
switch (platform) {
5+
case 'windows':
6+
const webViewWindowsAppId = 'PermissionsExample_nsp2ha5jnb6xr!App';
7+
module.exports = {
8+
capabilites: windowsAppDriverCapabilities(webViewWindowsAppId),
9+
};
10+
break;
11+
default:
12+
throw 'Unknown platform: ' + platform;
13+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/* eslint-disable no-undef */
2+
platform = 'windows';

example/metro.config.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
1+
const path = require('path');
2+
const blacklist = require('metro-config/src/defaults/blacklist');
3+
14
module.exports = {
5+
resolver: {
6+
blacklistRE: blacklist([
7+
// This stops "react-native run-windows" from causing the metro server to crash if its already running
8+
new RegExp(
9+
`${path.resolve(__dirname, 'windows').replace(/[/\\]/g, '/')}.*`,
10+
),
11+
// This prevents "react-native run-windows" from hitting: EBUSY: resource busy or locked, open msbuild.ProjectImports.zip
12+
new RegExp(
13+
`${path
14+
.resolve(__dirname, 'msbuild.ProjectImports.zip')
15+
.replace(/[/\\]/g, '/')}.*`,
16+
),
17+
]),
18+
},
219
transformer: {
320
getTransformOptions: async () => ({
421
transform: {

example/package.json

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,52 @@
33
"version": "0.0.1",
44
"private": true,
55
"scripts": {
6+
"appium": "appium",
67
"clean-modules": "rm -rf ./node_modules/react-native-permissions/{example,node_modules}",
78
"clean": "rm -rf ./node_modules ./ios/Pods",
89
"postinstall": "yarn clean-modules && yarn pod-update",
910
"pod-update": "cd ./ios && pod update && cd ..",
1011
"start": "react-native start",
11-
"reinstall": "yarn clean && yarn install"
12+
"reinstall": "yarn clean && yarn install",
13+
"test:windows": "yarn jest --setupFiles=./jest-setups/jest.setup.windows.js"
1214
},
1315
"dependencies": {
1416
"react": "16.11.0",
1517
"react-native": "0.62.2",
1618
"react-native-paper": "3.8.0",
1719
"react-native-permissions": "../",
18-
"react-native-vector-icons": "6.6.0"
20+
"react-native-vector-icons": "6.6.0",
21+
"react-native-windows": "^0.62.0-0"
1922
},
2023
"devDependencies": {
2124
"@babel/core": "7.9.0",
2225
"@babel/runtime": "7.9.2",
26+
"@react-native-community/eslint-config": "^1.0.0",
27+
"@types/jest": "^24.0.24",
2328
"@types/react": "16.9.34",
2429
"@types/react-native": "0.62.2",
30+
"@types/react-test-renderer": "16.9.2",
31+
"@typescript-eslint/parser": "^2.27.0",
32+
"appium": "1.18.2",
33+
"babel-jest": "^24.9.0",
34+
"eslint": "^6.5.1",
35+
"jest": "^24.9.0",
2536
"metro-react-native-babel-preset": "0.59.0",
37+
"prettier": "^2.0.4",
38+
"react-test-renderer": "16.11.0",
39+
"selenium-appium": "0.0.15",
40+
"selenium-webdriver": "4.0.0-alpha.7",
2641
"typescript": "3.8.3"
42+
},
43+
"jest": {
44+
"preset": "react-native",
45+
"moduleFileExtensions": [
46+
"ts",
47+
"tsx",
48+
"js",
49+
"jsx",
50+
"json",
51+
"node"
52+
]
2753
}
2854
}

0 commit comments

Comments
 (0)