1import assert from 'assert'; 2import { ExpoConfig } from 'expo/config'; 3import { ConfigPlugin, createRunOncePlugin, InfoPlist, withInfoPlist } from 'expo/config-plugins'; 4 5const pkg = require('expo-screen-orientation/package.json'); 6 7// This value must match the `EXDefaultScreenOrientationMask` string used in `expo-screen-orientation/ios/EXScreenOrientation/EXScreenOrientationViewController.m` (do not change). 8export const INITIAL_ORIENTATION_KEY = 'EXDefaultScreenOrientationMask'; 9 10const OrientationLock = { 11 DEFAULT: 'UIInterfaceOrientationMaskAllButUpsideDown', 12 ALL: 'UIInterfaceOrientationMaskAll', 13 PORTRAIT: 'UIInterfaceOrientationMaskPortrait', 14 PORTRAIT_UP: 'UIInterfaceOrientationMaskPortrait', 15 PORTRAIT_DOWN: 'UIInterfaceOrientationMaskPortraitUpsideDown', 16 LANDSCAPE: 'UIInterfaceOrientationMaskLandscape', 17 LANDSCAPE_LEFT: 'UIInterfaceOrientationMaskLandscapeLeft', 18 LANDSCAPE_RIGHT: 'UIInterfaceOrientationMaskLandscapeRight', 19}; 20 21type OrientationMasks = keyof typeof OrientationLock; 22 23// `initialOrientation` is not public in expo config yet, we just use it as an internal type. 24interface ExpoConfigWithInitialOrientation extends ExpoConfig { 25 initialOrientation?: OrientationMasks; 26} 27 28const withScreenOrientationViewController: ConfigPlugin< 29 { 30 initialOrientation?: keyof typeof OrientationLock; 31 } | void 32> = (config, { initialOrientation } = {}) => { 33 config = withInfoPlist(config, (config) => { 34 const extendedConfig = { 35 ...config, 36 initialOrientation, 37 }; 38 config.modResults = setInitialOrientation(extendedConfig, config.modResults); 39 return config; 40 }); 41 return config; 42}; 43 44export function setInitialOrientation( 45 config: Pick<ExpoConfigWithInitialOrientation, 'initialOrientation'>, 46 infoPlist: InfoPlist 47): InfoPlist { 48 const initialOrientation = config.initialOrientation; 49 50 if (!initialOrientation) { 51 delete infoPlist[INITIAL_ORIENTATION_KEY]; 52 return infoPlist; 53 } 54 55 assert( 56 initialOrientation in OrientationLock, 57 `Invalid initial orientation "${initialOrientation}" expected one of: ${Object.keys( 58 OrientationLock 59 ).join(', ')}` 60 ); 61 62 infoPlist[INITIAL_ORIENTATION_KEY] = OrientationLock[initialOrientation]; 63 64 return infoPlist; 65} 66 67export default createRunOncePlugin(withScreenOrientationViewController, pkg.name, pkg.version); 68