UNPKG

8.31 kBJavaScriptView Raw
1import { EventEmitter, Platform, UnavailabilityError } from '@unimodules/core';
2import ExpoScreenOrientation from './ExpoScreenOrientation';
3import { Orientation, OrientationLock, SizeClassIOS, WebOrientationLock, } from './ScreenOrientation.types';
4export { Orientation, OrientationLock, SizeClassIOS, WebOrientationLock, };
5const _orientationChangeEmitter = new EventEmitter(ExpoScreenOrientation);
6let _orientationChangeSubscribers = [];
7let _lastOrientationLock = OrientationLock.UNKNOWN;
8export function allow(orientationLock) {
9 console.warn("'ScreenOrientation.allow' is deprecated in favour of 'ScreenOrientation.lockAsync' and will be removed in SDK 35 or later");
10 lockAsync(orientationLock);
11}
12export async function allowAsync(orientationLock) {
13 console.warn("'ScreenOrientation.allowAsync' is deprecated in favour of 'ScreenOrientation.lockAsync'");
14 await lockAsync(orientationLock);
15}
16export async function lockAsync(orientationLock) {
17 if (!ExpoScreenOrientation.lockAsync) {
18 throw new UnavailabilityError('ScreenOrientation', 'lockAsync');
19 }
20 const orientationLocks = Object.values(OrientationLock);
21 if (!orientationLocks.includes(orientationLock)) {
22 throw new TypeError(`Invalid Orientation Lock: ${orientationLock}`);
23 }
24 if (orientationLock === OrientationLock.OTHER) {
25 return;
26 }
27 await ExpoScreenOrientation.lockAsync(orientationLock);
28 _lastOrientationLock = orientationLock;
29}
30export async function lockPlatformAsync(options) {
31 if (!ExpoScreenOrientation.lockPlatformAsync) {
32 throw new UnavailabilityError('ScreenOrientation', 'lockPlatformAsync');
33 }
34 const { screenOrientationConstantAndroid, screenOrientationArrayIOS, screenOrientationLockWeb, } = options;
35 let platformOrientationParam;
36 if (Platform.OS === 'android' && screenOrientationConstantAndroid) {
37 if (isNaN(screenOrientationConstantAndroid)) {
38 throw new TypeError(`lockPlatformAsync Android platform: screenOrientationConstantAndroid cannot be called with ${screenOrientationConstantAndroid}`);
39 }
40 platformOrientationParam = screenOrientationConstantAndroid;
41 }
42 else if (Platform.OS === 'ios' && screenOrientationArrayIOS) {
43 if (!Array.isArray(screenOrientationArrayIOS)) {
44 throw new TypeError(`lockPlatformAsync iOS platform: screenOrientationArrayIOS cannot be called with ${screenOrientationArrayIOS}`);
45 }
46 const orientations = Object.values(Orientation);
47 for (let orientation of screenOrientationArrayIOS) {
48 if (!orientations.includes(orientation)) {
49 throw new TypeError(`lockPlatformAsync iOS platform: ${orientation} is not a valid Orientation`);
50 }
51 }
52 platformOrientationParam = screenOrientationArrayIOS;
53 }
54 else if (Platform.OS === 'web' && screenOrientationLockWeb) {
55 const webOrientationLocks = Object.values(WebOrientationLock);
56 if (!webOrientationLocks.includes(screenOrientationLockWeb)) {
57 throw new TypeError(`Invalid Web Orientation Lock: ${screenOrientationLockWeb}`);
58 }
59 platformOrientationParam = screenOrientationLockWeb;
60 }
61 if (!platformOrientationParam) {
62 throw new TypeError('lockPlatformAsync cannot be called with undefined option properties');
63 }
64 await ExpoScreenOrientation.lockPlatformAsync(platformOrientationParam);
65 _lastOrientationLock = OrientationLock.OTHER;
66}
67export async function unlockAsync() {
68 if (!ExpoScreenOrientation.unlockAsync) {
69 throw new UnavailabilityError('ScreenOrientation', 'unlockAsync');
70 }
71 await ExpoScreenOrientation.unlockAsync();
72}
73export async function getOrientationAsync() {
74 if (!ExpoScreenOrientation.getOrientationAsync) {
75 throw new UnavailabilityError('ScreenOrientation', 'getOrientationAsync');
76 }
77 return await ExpoScreenOrientation.getOrientationAsync();
78}
79export async function getOrientationLockAsync() {
80 if (!ExpoScreenOrientation.getOrientationLockAsync) {
81 return _lastOrientationLock;
82 }
83 return await ExpoScreenOrientation.getOrientationLockAsync();
84}
85export async function getPlatformOrientationLockAsync() {
86 const platformOrientationLock = await ExpoScreenOrientation.getPlatformOrientationLockAsync();
87 if (Platform.OS === 'android') {
88 return {
89 screenOrientationConstantAndroid: platformOrientationLock,
90 };
91 }
92 else if (Platform.OS === 'ios') {
93 return {
94 screenOrientationArrayIOS: platformOrientationLock,
95 };
96 }
97 else if (Platform.OS === 'web') {
98 return {
99 screenOrientationLockWeb: platformOrientationLock,
100 };
101 }
102 else {
103 return {};
104 }
105}
106export async function supportsOrientationLockAsync(orientationLock) {
107 if (!ExpoScreenOrientation.supportsOrientationLockAsync) {
108 throw new UnavailabilityError('ScreenOrientation', 'supportsOrientationLockAsync');
109 }
110 const orientationLocks = Object.values(OrientationLock);
111 if (!orientationLocks.includes(orientationLock)) {
112 throw new TypeError(`Invalid Orientation Lock: ${orientationLock}`);
113 }
114 return await ExpoScreenOrientation.supportsOrientationLockAsync(orientationLock);
115}
116export async function doesSupportAsync(orientationLock) {
117 console.warn("'ScreenOrientation.doesSupportAsync' is deprecated in favour of 'ScreenOrientation.supportsOrientationLockAsync'");
118 return await supportsOrientationLockAsync(orientationLock);
119}
120// Determine the event name lazily so Jest can set up mocks in advance
121function getEventName() {
122 return Platform.OS === 'ios' || Platform.OS === 'web'
123 ? 'expoDidUpdateDimensions'
124 : 'didUpdateDimensions';
125}
126// We rely on RN to emit `didUpdateDimensions`
127// If this method no longer works, it's possible that the underlying RN implementation has changed
128// see https://github.com/facebook/react-native/blob/c31f79fe478b882540d7fd31ee37b53ddbd60a17/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java#L90
129export function addOrientationChangeListener(listener) {
130 if (typeof listener !== 'function') {
131 throw new TypeError(`addOrientationChangeListener cannot be called with ${listener}`);
132 }
133 const subscription = _orientationChangeEmitter.addListener(getEventName(), async (update) => {
134 let orientationInfo, orientationLock;
135 if (Platform.OS === 'ios' || Platform.OS === 'web') {
136 // For iOS, RN relies on statusBarOrientation (deprecated) to emit `didUpdateDimensions` event, so we emit our own `expoDidUpdateDimensions` event instead
137 orientationLock = update.orientationLock;
138 orientationInfo = update.orientationInfo;
139 }
140 else {
141 // We rely on the RN Dimensions to emit the `didUpdateDimensions` event on Android
142 [orientationLock, orientationInfo] = await Promise.all([
143 getOrientationLockAsync(),
144 getOrientationAsync(),
145 ]);
146 }
147 listener({ orientationInfo, orientationLock });
148 });
149 _orientationChangeSubscribers.push(subscription);
150 return subscription;
151}
152// We need to keep track of our own subscribers because EventEmitter uses a shared subscriber
153// from NativeEventEmitter that is registered to the same eventTypes as us. Directly calling
154// removeAllListeners(eventName) will remove other module's subscribers.
155export function removeOrientationChangeListeners() {
156 // Remove listener by subscription instead of eventType to avoid clobbering Dimension module's subscription of didUpdateDimensions
157 let i = _orientationChangeSubscribers.length;
158 while (i--) {
159 const subscriber = _orientationChangeSubscribers[i];
160 subscriber.remove();
161 // remove after a successful unsubscribe
162 _orientationChangeSubscribers.pop();
163 }
164}
165export function removeOrientationChangeListener(subscription) {
166 if (!subscription || !subscription.remove) {
167 throw new TypeError(`Must pass in a valid subscription`);
168 }
169 subscription.remove();
170 _orientationChangeSubscribers = _orientationChangeSubscribers.filter(sub => sub !== subscription);
171}
172//# sourceMappingURL=ScreenOrientation.js.map
\No newline at end of file