UNPKG

3.6 kBPlain TextView Raw
1import { PermissionResponse, PermissionStatus, UnavailabilityError } from 'expo-modules-core';
2
3function getUserMedia(constraints: MediaStreamConstraints): Promise<MediaStream> {
4 if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
5 return navigator.mediaDevices.getUserMedia(constraints);
6 }
7
8 // Some browsers partially implement mediaDevices. We can't just assign an object
9 // with getUserMedia as it would overwrite existing properties.
10 // Here, we will just add the getUserMedia property if it's missing.
11
12 // First get ahold of the legacy getUserMedia, if present
13 const getUserMedia =
14 // TODO: this method is deprecated, migrate to https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
15 navigator.getUserMedia ||
16 navigator.webkitGetUserMedia ||
17 navigator.mozGetUserMedia ||
18 function () {
19 const error: any = new Error('Permission unimplemented');
20 error.code = 0;
21 error.name = 'NotAllowedError';
22 throw error;
23 };
24
25 return new Promise((resolve, reject) => {
26 getUserMedia.call(navigator, constraints, resolve, reject);
27 });
28}
29
30function handleGetUserMediaError({ message }: { message: string }): PermissionResponse {
31 // name: NotAllowedError
32 // code: 0
33 if (message === 'Permission dismissed') {
34 return {
35 status: PermissionStatus.UNDETERMINED,
36 expires: 'never',
37 canAskAgain: true,
38 granted: false,
39 };
40 } else {
41 return {
42 status: PermissionStatus.DENIED,
43 expires: 'never',
44 canAskAgain: true,
45 granted: false,
46 };
47 }
48}
49
50async function handleRequestPermissionsAsync(): Promise<PermissionResponse> {
51 try {
52 await getUserMedia({
53 video: true,
54 });
55 return {
56 status: PermissionStatus.GRANTED,
57 expires: 'never',
58 canAskAgain: true,
59 granted: true,
60 };
61 } catch ({ message }) {
62 return handleGetUserMediaError({ message });
63 }
64}
65
66async function handlePermissionsQueryAsync(): Promise<PermissionResponse> {
67 if (!navigator?.permissions?.query) {
68 throw new UnavailabilityError(
69 'expo-barcode-scanner',
70 'navigator.permissions API is not available'
71 );
72 }
73
74 const { state } = await navigator.permissions.query({ name: 'camera' });
75 switch (state) {
76 case 'prompt':
77 return {
78 status: PermissionStatus.UNDETERMINED,
79 expires: 'never',
80 canAskAgain: true,
81 granted: false,
82 };
83 case 'granted':
84 return {
85 status: PermissionStatus.GRANTED,
86 expires: 'never',
87 canAskAgain: true,
88 granted: true,
89 };
90 case 'denied':
91 return {
92 status: PermissionStatus.DENIED,
93 expires: 'never',
94 canAskAgain: true,
95 granted: false,
96 };
97 }
98}
99
100export default {
101 get name(): string {
102 return 'ExpoBarCodeScannerModule';
103 },
104 get BarCodeType() {
105 return {
106 code39mod43: 'code39mod43',
107 code138: 'code138',
108 interleaved2of5: 'interleaved2of5',
109 aztec: 'aztec',
110 ean13: 'ean13',
111 ean8: 'ean8',
112 qr: 'qr',
113 pdf417: 'pdf417',
114 upc_e: 'upc_e',
115 datamatrix: 'datamatrix',
116 code39: 'code39',
117 code93: 'code93',
118 itf14: 'itf14',
119 codabar: 'codabar',
120 code128: 'code128',
121 upc_a: 'upc_a',
122 };
123 },
124 get Type() {
125 return { front: 'front', back: 'back' };
126 },
127 async requestPermissionsAsync(): Promise<PermissionResponse> {
128 return handleRequestPermissionsAsync();
129 },
130 async getPermissionsAsync(): Promise<PermissionResponse> {
131 return handlePermissionsQueryAsync();
132 },
133};