expo-screen-orientation 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,21 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 4.1.0 — 2021-12-03
14
+
15
+ ### 💡 Others
16
+
17
+ - [plugin] Added SDK 43 tests for new AppDelegate template ([#14763](https://github.com/expo/expo/pull/14763) by [@EvanBacon](https://github.com/EvanBacon))
18
+ - The app delegate subscriber on iOS has been separated from the singleton module to hook into the new implementation of `ExpoAppDelegate`. ([#14867](https://github.com/expo/expo/pull/14867) by [@tsapeta](https://github.com/tsapeta))
19
+
20
+ ### ⚠️ Notices
21
+
22
+ - Extra setup on iOS bare projects is not necessary from the support of `ExpoReactDelegateHandler`. ([#15140](https://github.com/expo/expo/pull/15140) by [@kudo](https://github.com/kudo))
23
+
24
+ ## 4.0.1 — 2021-10-01
25
+
26
+ _This version does not introduce any user-facing changes._
27
+
13
28
  ## 4.0.0 — 2021-09-28
14
29
 
15
30
  ### 🛠 Breaking changes
package/README.md CHANGED
@@ -13,7 +13,7 @@ For managed [managed](https://docs.expo.io/versions/latest/introduction/managed-
13
13
 
14
14
  # Installation in bare React Native projects
15
15
 
16
- For bare React Native projects, you must ensure that you have [installed and configured the `react-native-unimodules` package](https://github.com/expo/expo/tree/master/packages/react-native-unimodules) before continuing.
16
+ For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
17
17
 
18
18
  ### Add the package to your npm dependencies
19
19
 
@@ -23,33 +23,14 @@ npm install expo-screen-orientation
23
23
 
24
24
  ### Configure for iOS
25
25
 
26
- 1. Run `npx pod-install` after installing the npm package.
27
- 2. Open the `AppDelegate.m` of your application.
28
- 3. Make sure your `AppDelegate` extends `UMAppDelegateWrapper` as shown [here](https://gist.github.com/lukmccall/d2b97b2dde0d1aa04a245a369ffdd153).
29
- 4. Import `<EXScreenOrientation/EXScreenOrientationViewController.h>`
30
- 5. In `-application:didFinishLaunchingWithOptions:launchOptions` change default `root view controller` to `EXScreenOrientationViewController`:
26
+ Run `npx pod-install` after installing the npm package.
31
27
 
32
- Replace
28
+ The default [UIInterfaceOrientationMask](https://developer.apple.com/documentation/uikit/uiinterfaceorientationmask?language=objc) mask is `UIInterfaceOrientationMaskPortrait`. You can optionally add `EXDefaultScreenOrientationMask` key in your `Info.plist` to change the default orientation mask, e.g.
33
29
 
34
- ```objc
35
- UIViewController *rootViewController = [UIViewController new];
36
- ```
37
-
38
- with:
39
-
40
- ```objc
41
- UIViewController *rootViewController = [[EXScreenOrientationViewController alloc] init]; // The default screen orientation will be set to `portrait`.
42
- ```
43
-
44
- or if you want to change the default screen orientation, with:
45
-
46
- ```objc
47
- UIViewController *rootViewController = [[EXScreenOrientationViewController alloc] initWithDefaultScreenOrientationMask:UIInterfaceOrientationMaskPortrait]; // through parameter you can specify your default orientation mask.
48
- ```
49
-
50
- For more information about available orientation masks, check out [UIInterfaceOrientationMask](https://developer.apple.com/documentation/uikit/uiinterfaceorientationmask?language=objc)
51
-
52
- > **Note** if you are using a custom view controller, the controller will need to extend the `EXScreenOrientationViewController`.
30
+ ```xml
31
+ <key>EXDefaultScreenOrientationMask</key>
32
+ <string>UIInterfaceOrientationMaskAllButUpsideDown</string>
33
+ ```
53
34
 
54
35
  ### Configure for Android
55
36
 
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
3
3
  apply plugin: 'maven'
4
4
 
5
5
  group = 'host.exp.exponent'
6
- version = '4.0.0'
6
+ version = '4.1.0'
7
7
 
8
8
  buildscript {
9
9
  // Simple helper that allows the root project to override versions declared by this library.
@@ -57,7 +57,7 @@ android {
57
57
  minSdkVersion safeExtGet("minSdkVersion", 21)
58
58
  targetSdkVersion safeExtGet("targetSdkVersion", 30)
59
59
  versionCode 7
60
- versionName '4.0.0'
60
+ versionName '4.1.0'
61
61
  }
62
62
  lintOptions {
63
63
  abortOnError false
@@ -103,17 +103,20 @@ export declare enum WebOrientation {
103
103
  }
104
104
  export declare type PlatformOrientationInfo = {
105
105
  /**
106
- * __Android Only.__ A constant to set using the Android native [API](https://developer.android.com/reference/android/R.attr.html#screenOrientation).
106
+ * A constant to set using the Android native [API](https://developer.android.com/reference/android/R.attr.html#screenOrientation).
107
107
  * For example, in order to set the lock policy to [unspecified](https://developer.android.com/reference/android/content/pm/ActivityInfo.html#SCREEN_ORIENTATION_UNSPECIFIED),
108
108
  * `-1` should be passed in.
109
+ * @platform android
109
110
  */
110
111
  screenOrientationConstantAndroid?: number;
111
112
  /**
112
- * __iOS Only.__ An array of orientations to allow on the iOS platform.
113
+ * An array of orientations to allow on the iOS platform.
114
+ * @platform ios
113
115
  */
114
116
  screenOrientationArrayIOS?: Orientation[];
115
117
  /**
116
- * __Web Only.__ A web orientation lock to apply in the browser.
118
+ * A web orientation lock to apply in the browser.
119
+ * @platform web
117
120
  */
118
121
  screenOrientationLockWeb?: WebOrientationLock;
119
122
  };
@@ -123,13 +126,15 @@ export declare type ScreenOrientationInfo = {
123
126
  */
124
127
  orientation: Orientation;
125
128
  /**
126
- * __iOS Only.__ The [vertical size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)
129
+ * The [vertical size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)
127
130
  * of the device.
131
+ * @platform ios
128
132
  */
129
133
  verticalSizeClass?: SizeClassIOS;
130
134
  /**
131
- * __iOS Only.__ The [horizontal size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)
135
+ * The [horizontal size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)
132
136
  * of the device.
137
+ * @platform ios
133
138
  */
134
139
  horizontalSizeClass?: SizeClassIOS;
135
140
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ScreenOrientation.types.js","sourceRoot":"","sources":["../src/ScreenOrientation.types.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,MAAM,CAAN,IAAY,WAqBX;AArBD,WAAY,WAAW;IACrB;;OAEG;IACH,mDAAW,CAAA;IACX;;OAEG;IACH,2DAAe,CAAA;IACf;;OAEG;IACH,+DAAiB,CAAA;IACjB;;OAEG;IACH,iEAAkB,CAAA;IAClB;;OAEG;IACH,mEAAmB,CAAA;AACrB,CAAC,EArBW,WAAW,KAAX,WAAW,QAqBtB;AAED,cAAc;AACd;;;;;GAKG;AACH,MAAM,CAAN,IAAY,eA0CX;AA1CD,WAAY,eAAe;IACzB;;;OAGG;IACH,2DAAW,CAAA;IACX;;OAEG;IACH,mDAAO,CAAA;IACP;;OAEG;IACH,6DAAY,CAAA;IACZ;;OAEG;IACH,mEAAe,CAAA;IACf;;OAEG;IACH,uEAAiB,CAAA;IACjB;;OAEG;IACH,+DAAa,CAAA;IACb;;OAEG;IACH,yEAAkB,CAAA;IAClB;;OAEG;IACH,2EAAmB,CAAA;IACnB;;OAEG;IACH,uDAAS,CAAA;IACT;;OAEG;IACH,2DAAW,CAAA;AACb,CAAC,EA1CW,eAAe,KAAf,eAAe,QA0C1B;AAED,cAAc;AACd;;;GAGG;AACH,MAAM,CAAN,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,qDAAW,CAAA;IACX,qDAAW,CAAA;IACX,qDAAW,CAAA;AACb,CAAC,EAJW,YAAY,KAAZ,YAAY,QAIvB;AAED,cAAc;AACd;;;;;GAKG;AACH,MAAM,CAAN,IAAY,kBAUX;AAVD,WAAY,kBAAkB;IAC5B,2DAAqC,CAAA;IACrC,+DAAyC,CAAA;IACzC,2CAAqB,CAAA;IACrB,6DAAuC,CAAA;IACvC,iEAA2C,CAAA;IAC3C,6CAAuB,CAAA;IACvB,iCAAW,CAAA;IACX,yCAAmB,CAAA;IACnB,yCAAmB,CAAA;AACrB,CAAC,EAVW,kBAAkB,KAAlB,kBAAkB,QAU7B;AAED,eAAe;AACf,MAAM,CAAN,IAAY,cAKX;AALD,WAAY,cAAc;IACxB,uDAAqC,CAAA;IACrC,2DAAyC,CAAA;IACzC,yDAAuC,CAAA;IACvC,6DAA2C,CAAA;AAC7C,CAAC,EALW,cAAc,KAAd,cAAc,QAKzB","sourcesContent":["// @needsAudit\nexport enum Orientation {\n /**\n * An unknown screen orientation. For example, the device is flat, perhaps on a table.\n */\n UNKNOWN = 0,\n /**\n * Right-side up portrait interface orientation.\n */\n PORTRAIT_UP = 1,\n /**\n * Upside down portrait interface orientation.\n */\n PORTRAIT_DOWN = 2,\n /**\n * Left landscape interface orientation.\n */\n LANDSCAPE_LEFT = 3,\n /**\n * Right landscape interface orientation.\n */\n LANDSCAPE_RIGHT = 4,\n}\n\n// @needsAudit\n/**\n * An enum whose values can be passed to the [`lockAsync`](#screenorientationlockasyncorientationlock)\n * method.\n * > __Note:__ `OrientationLock.ALL` and `OrientationLock.PORTRAIT` are invalid on devices which\n * don't support `OrientationLock.PORTRAIT_DOWN`.\n */\nexport enum OrientationLock {\n /**\n * The default orientation. On iOS, this will allow all orientations except `Orientation.PORTRAIT_DOWN`.\n * On Android, this lets the system decide the best orientation.\n */\n DEFAULT = 0,\n /**\n * All four possible orientations\n */\n ALL = 1,\n /**\n * Any portrait orientation.\n */\n PORTRAIT = 2,\n /**\n * Right-side up portrait only.\n */\n PORTRAIT_UP = 3,\n /**\n * Upside down portrait only.\n */\n PORTRAIT_DOWN = 4,\n /**\n * Any landscape orientation.\n */\n LANDSCAPE = 5,\n /**\n * Left landscape only.\n */\n LANDSCAPE_LEFT = 6,\n /**\n * Right landscape only.\n */\n LANDSCAPE_RIGHT = 7,\n /**\n * A platform specific orientation. This is not a valid policy that can be applied in [`lockAsync`](#screenorientationlockasyncorientationlock).\n */\n OTHER = 8,\n /**\n * An unknown screen orientation lock. This is not a valid policy that can be applied in [`lockAsync`](#screenorientationlockasyncorientationlock).\n */\n UNKNOWN = 9,\n}\n\n// @needsAudit\n/**\n * Each iOS device has a default set of [size classes](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)\n * that you can use as a guide when designing your interface.\n */\nexport enum SizeClassIOS {\n REGULAR = 0,\n COMPACT = 1,\n UNKNOWN = 2,\n}\n\n// @needsAudit\n/**\n * An enum representing the lock policies that can be applied on the web platform, modelled after\n * the [W3C specification](https://w3c.github.io/screen-orientation/#dom-orientationlocktype).\n * These values can be applied through the [`lockPlatformAsync`](#screenorientationlockplatformasyncplatforminfo)\n * method.\n */\nexport enum WebOrientationLock {\n PORTRAIT_PRIMARY = 'portrait-primary',\n PORTRAIT_SECONDARY = 'portrait-secondary',\n PORTRAIT = 'portrait',\n LANDSCAPE_PRIMARY = 'landscape-primary',\n LANDSCAPE_SECONDARY = 'landscape-secondary',\n LANDSCAPE = 'landscape',\n ANY = 'any',\n NATURAL = 'natural',\n UNKNOWN = 'unknown',\n}\n\n// @docsMissing\nexport enum WebOrientation {\n PORTRAIT_PRIMARY = 'portrait-primary',\n PORTRAIT_SECONDARY = 'portrait-secondary',\n LANDSCAPE_PRIMARY = 'landscape-primary',\n LANDSCAPE_SECONDARY = 'landscape-secondary',\n}\n\n// @needsAudit\nexport type PlatformOrientationInfo = {\n /**\n * __Android Only.__ A constant to set using the Android native [API](https://developer.android.com/reference/android/R.attr.html#screenOrientation).\n * For example, in order to set the lock policy to [unspecified](https://developer.android.com/reference/android/content/pm/ActivityInfo.html#SCREEN_ORIENTATION_UNSPECIFIED),\n * `-1` should be passed in.\n */\n screenOrientationConstantAndroid?: number;\n /**\n * __iOS Only.__ An array of orientations to allow on the iOS platform.\n */\n screenOrientationArrayIOS?: Orientation[];\n /**\n * __Web Only.__ A web orientation lock to apply in the browser.\n */\n screenOrientationLockWeb?: WebOrientationLock;\n};\n\n// @needsAudit\nexport type ScreenOrientationInfo = {\n /**\n * The current orientation of the device.\n */\n orientation: Orientation;\n /**\n * __iOS Only.__ The [vertical size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)\n * of the device.\n */\n verticalSizeClass?: SizeClassIOS;\n /**\n * __iOS Only.__ The [horizontal size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)\n * of the device.\n */\n horizontalSizeClass?: SizeClassIOS;\n};\n\nexport type OrientationChangeListener = (event: OrientationChangeEvent) => void;\n\n// @needsAudit\nexport type OrientationChangeEvent = {\n /**\n * The current `OrientationLock` of the device.\n */\n orientationLock: OrientationLock;\n /**\n * The current `ScreenOrientationInfo` of the device.\n */\n orientationInfo: ScreenOrientationInfo;\n};\n"]}
1
+ {"version":3,"file":"ScreenOrientation.types.js","sourceRoot":"","sources":["../src/ScreenOrientation.types.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,MAAM,CAAN,IAAY,WAqBX;AArBD,WAAY,WAAW;IACrB;;OAEG;IACH,mDAAW,CAAA;IACX;;OAEG;IACH,2DAAe,CAAA;IACf;;OAEG;IACH,+DAAiB,CAAA;IACjB;;OAEG;IACH,iEAAkB,CAAA;IAClB;;OAEG;IACH,mEAAmB,CAAA;AACrB,CAAC,EArBW,WAAW,KAAX,WAAW,QAqBtB;AAED,cAAc;AACd;;;;;GAKG;AACH,MAAM,CAAN,IAAY,eA0CX;AA1CD,WAAY,eAAe;IACzB;;;OAGG;IACH,2DAAW,CAAA;IACX;;OAEG;IACH,mDAAO,CAAA;IACP;;OAEG;IACH,6DAAY,CAAA;IACZ;;OAEG;IACH,mEAAe,CAAA;IACf;;OAEG;IACH,uEAAiB,CAAA;IACjB;;OAEG;IACH,+DAAa,CAAA;IACb;;OAEG;IACH,yEAAkB,CAAA;IAClB;;OAEG;IACH,2EAAmB,CAAA;IACnB;;OAEG;IACH,uDAAS,CAAA;IACT;;OAEG;IACH,2DAAW,CAAA;AACb,CAAC,EA1CW,eAAe,KAAf,eAAe,QA0C1B;AAED,cAAc;AACd;;;GAGG;AACH,MAAM,CAAN,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,qDAAW,CAAA;IACX,qDAAW,CAAA;IACX,qDAAW,CAAA;AACb,CAAC,EAJW,YAAY,KAAZ,YAAY,QAIvB;AAED,cAAc;AACd;;;;;GAKG;AACH,MAAM,CAAN,IAAY,kBAUX;AAVD,WAAY,kBAAkB;IAC5B,2DAAqC,CAAA;IACrC,+DAAyC,CAAA;IACzC,2CAAqB,CAAA;IACrB,6DAAuC,CAAA;IACvC,iEAA2C,CAAA;IAC3C,6CAAuB,CAAA;IACvB,iCAAW,CAAA;IACX,yCAAmB,CAAA;IACnB,yCAAmB,CAAA;AACrB,CAAC,EAVW,kBAAkB,KAAlB,kBAAkB,QAU7B;AAED,eAAe;AACf,MAAM,CAAN,IAAY,cAKX;AALD,WAAY,cAAc;IACxB,uDAAqC,CAAA;IACrC,2DAAyC,CAAA;IACzC,yDAAuC,CAAA;IACvC,6DAA2C,CAAA;AAC7C,CAAC,EALW,cAAc,KAAd,cAAc,QAKzB","sourcesContent":["// @needsAudit\nexport enum Orientation {\n /**\n * An unknown screen orientation. For example, the device is flat, perhaps on a table.\n */\n UNKNOWN = 0,\n /**\n * Right-side up portrait interface orientation.\n */\n PORTRAIT_UP = 1,\n /**\n * Upside down portrait interface orientation.\n */\n PORTRAIT_DOWN = 2,\n /**\n * Left landscape interface orientation.\n */\n LANDSCAPE_LEFT = 3,\n /**\n * Right landscape interface orientation.\n */\n LANDSCAPE_RIGHT = 4,\n}\n\n// @needsAudit\n/**\n * An enum whose values can be passed to the [`lockAsync`](#screenorientationlockasyncorientationlock)\n * method.\n * > __Note:__ `OrientationLock.ALL` and `OrientationLock.PORTRAIT` are invalid on devices which\n * don't support `OrientationLock.PORTRAIT_DOWN`.\n */\nexport enum OrientationLock {\n /**\n * The default orientation. On iOS, this will allow all orientations except `Orientation.PORTRAIT_DOWN`.\n * On Android, this lets the system decide the best orientation.\n */\n DEFAULT = 0,\n /**\n * All four possible orientations\n */\n ALL = 1,\n /**\n * Any portrait orientation.\n */\n PORTRAIT = 2,\n /**\n * Right-side up portrait only.\n */\n PORTRAIT_UP = 3,\n /**\n * Upside down portrait only.\n */\n PORTRAIT_DOWN = 4,\n /**\n * Any landscape orientation.\n */\n LANDSCAPE = 5,\n /**\n * Left landscape only.\n */\n LANDSCAPE_LEFT = 6,\n /**\n * Right landscape only.\n */\n LANDSCAPE_RIGHT = 7,\n /**\n * A platform specific orientation. This is not a valid policy that can be applied in [`lockAsync`](#screenorientationlockasyncorientationlock).\n */\n OTHER = 8,\n /**\n * An unknown screen orientation lock. This is not a valid policy that can be applied in [`lockAsync`](#screenorientationlockasyncorientationlock).\n */\n UNKNOWN = 9,\n}\n\n// @needsAudit\n/**\n * Each iOS device has a default set of [size classes](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)\n * that you can use as a guide when designing your interface.\n */\nexport enum SizeClassIOS {\n REGULAR = 0,\n COMPACT = 1,\n UNKNOWN = 2,\n}\n\n// @needsAudit\n/**\n * An enum representing the lock policies that can be applied on the web platform, modelled after\n * the [W3C specification](https://w3c.github.io/screen-orientation/#dom-orientationlocktype).\n * These values can be applied through the [`lockPlatformAsync`](#screenorientationlockplatformasyncplatforminfo)\n * method.\n */\nexport enum WebOrientationLock {\n PORTRAIT_PRIMARY = 'portrait-primary',\n PORTRAIT_SECONDARY = 'portrait-secondary',\n PORTRAIT = 'portrait',\n LANDSCAPE_PRIMARY = 'landscape-primary',\n LANDSCAPE_SECONDARY = 'landscape-secondary',\n LANDSCAPE = 'landscape',\n ANY = 'any',\n NATURAL = 'natural',\n UNKNOWN = 'unknown',\n}\n\n// @docsMissing\nexport enum WebOrientation {\n PORTRAIT_PRIMARY = 'portrait-primary',\n PORTRAIT_SECONDARY = 'portrait-secondary',\n LANDSCAPE_PRIMARY = 'landscape-primary',\n LANDSCAPE_SECONDARY = 'landscape-secondary',\n}\n\n// @needsAudit\nexport type PlatformOrientationInfo = {\n /**\n * A constant to set using the Android native [API](https://developer.android.com/reference/android/R.attr.html#screenOrientation).\n * For example, in order to set the lock policy to [unspecified](https://developer.android.com/reference/android/content/pm/ActivityInfo.html#SCREEN_ORIENTATION_UNSPECIFIED),\n * `-1` should be passed in.\n * @platform android\n */\n screenOrientationConstantAndroid?: number;\n /**\n * An array of orientations to allow on the iOS platform.\n * @platform ios\n */\n screenOrientationArrayIOS?: Orientation[];\n /**\n * A web orientation lock to apply in the browser.\n * @platform web\n */\n screenOrientationLockWeb?: WebOrientationLock;\n};\n\n// @needsAudit\nexport type ScreenOrientationInfo = {\n /**\n * The current orientation of the device.\n */\n orientation: Orientation;\n /**\n * The [vertical size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)\n * of the device.\n * @platform ios\n */\n verticalSizeClass?: SizeClassIOS;\n /**\n * The [horizontal size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)\n * of the device.\n * @platform ios\n */\n horizontalSizeClass?: SizeClassIOS;\n};\n\nexport type OrientationChangeListener = (event: OrientationChangeEvent) => void;\n\n// @needsAudit\nexport type OrientationChangeEvent = {\n /**\n * The current `OrientationLock` of the device.\n */\n orientationLock: OrientationLock;\n /**\n * The current `ScreenOrientationInfo` of the device.\n */\n orientationInfo: ScreenOrientationInfo;\n};\n"]}
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "expo-screen-orientation",
3
+ "platforms": ["ios", "android"],
4
+ "ios": {
5
+ "appDelegateSubscribers": ["ScreenOrientationAppDelegate"],
6
+ "reactDelegateHandlers": ["ScreenOrientationReactDelegateHandler"]
7
+ }
8
+ }
@@ -2,7 +2,7 @@
2
2
 
3
3
  #import <UIKit/UIKit.h>
4
4
  #import <Foundation/Foundation.h>
5
- #import <ExpoModulesCore/EXSingletonModule.h>
5
+ #import <ExpoModulesCore/ExpoModulesCore.h>
6
6
 
7
7
  NS_ASSUME_NONNULL_BEGIN
8
8
 
@@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN
35
35
 
36
36
  @interface EXScreenOrientationRegistry : EXSingletonModule <UIApplicationDelegate, EXScreenOrientationEventEmitter, EXScreenOrientationRegistry>
37
37
 
38
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions;
38
+ - (void)updateCurrentScreenOrientation;
39
39
 
40
40
  - (UIInterfaceOrientationMask)requiredOrientationMask;
41
41
  - (void)traitCollectionDidChangeTo:(UITraitCollection *)traitCollection;
@@ -42,9 +42,9 @@ EX_REGISTER_SINGLETON_MODULE(ScreenOrientationRegistry)
42
42
  return self;
43
43
  }
44
44
 
45
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions
45
+ - (void)updateCurrentScreenOrientation
46
46
  {
47
- // application:didFinishLaunchingWithOptions should be executed on the main thread.
47
+ // This should already be executed on the main thread.
48
48
  // However, it's safer to ensure that we are on a good thread.
49
49
  EX_WEAKIFY(self);
50
50
  [EXUtilities performSynchronouslyOnMainThread:^{
@@ -59,8 +59,6 @@ EX_REGISTER_SINGLETON_MODULE(ScreenOrientationRegistry)
59
59
  self.currentScreenOrientation = UIApplication.sharedApplication.statusBarOrientation;
60
60
  }
61
61
  }];
62
-
63
- return YES;
64
62
  }
65
63
 
66
64
  - (void)dealloc
@@ -9,4 +9,6 @@
9
9
 
10
10
  - (instancetype)initWithDefaultScreenOrientationMask:(UIInterfaceOrientationMask)defaultOrientationMask;
11
11
 
12
+ - (instancetype)initDefaultScreenOrientationFromPlist;
13
+
12
14
  @end
@@ -4,6 +4,9 @@
4
4
 
5
5
  #import <EXScreenOrientation/EXScreenOrientationViewController.h>
6
6
  #import <EXScreenOrientation/EXScreenOrientationRegistry.h>
7
+ #import <EXScreenOrientation/NSString+UIInterfaceOrientationMask.h>
8
+
9
+ NSString *const EXDefaultScreenOrientationMask = @"EXDefaultScreenOrientationMask";
7
10
 
8
11
  // copy of RNScreens protocol
9
12
  @protocol EXScreenOrientationRNSScreenWindowTraits
@@ -34,6 +37,20 @@
34
37
  return self;
35
38
  }
36
39
 
40
+ - (instancetype)initDefaultScreenOrientationFromPlist
41
+ {
42
+ NSString *plistValue = [NSBundle.mainBundle objectForInfoDictionaryKey:EXDefaultScreenOrientationMask];
43
+ if (plistValue != nil) {
44
+ @try {
45
+ UIInterfaceOrientationMask mask = [plistValue toUIInterfaceOrientationMask];
46
+ return [self initWithDefaultScreenOrientationMask:mask];
47
+ } @catch (NSException *exception) {
48
+ EXLogError(@"Invalid `%@` value in Info.plist, expected: one of `UIInterfaceOrientationMask` value, got: \"%@\".", EXDefaultScreenOrientationMask, plistValue);
49
+ }
50
+ }
51
+ return [self init];
52
+ }
53
+
37
54
  - (UIInterfaceOrientationMask)supportedInterfaceOrientations
38
55
  {
39
56
  if ([self shouldUseRNScreenOrientation]) {
@@ -0,0 +1,9 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <UIKit/UIKit.h>
4
+
5
+ @interface NSString (UIInterfaceOrientationMask)
6
+
7
+ - (UIInterfaceOrientationMask)toUIInterfaceOrientationMask;
8
+
9
+ @end
@@ -0,0 +1,21 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <EXScreenOrientation/NSString+UIInterfaceOrientationMask.h>
4
+
5
+ @implementation NSString (UIInterfaceOrientationMask)
6
+
7
+ - (UIInterfaceOrientationMask)toUIInterfaceOrientationMask
8
+ {
9
+ #define RETURN_VALUE_CHECKED(OPTION) if ([self isEqualToString:@#OPTION]) { return OPTION; }
10
+ RETURN_VALUE_CHECKED(UIInterfaceOrientationMaskPortrait)
11
+ RETURN_VALUE_CHECKED(UIInterfaceOrientationMaskLandscapeLeft)
12
+ RETURN_VALUE_CHECKED(UIInterfaceOrientationMaskLandscapeRight)
13
+ RETURN_VALUE_CHECKED(UIInterfaceOrientationMaskPortraitUpsideDown)
14
+ RETURN_VALUE_CHECKED(UIInterfaceOrientationMaskLandscape)
15
+ RETURN_VALUE_CHECKED(UIInterfaceOrientationMaskAll)
16
+ RETURN_VALUE_CHECKED(UIInterfaceOrientationMaskAllButUpsideDown)
17
+ #undef RETURN_VALUE_CHECKED
18
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Invalid UIInterfaceOrientationMask value" userInfo:nil];
19
+ }
20
+
21
+ @end
@@ -0,0 +1,12 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesCore
4
+
5
+ public class ScreenOrientationAppDelegate: ExpoAppDelegateSubscriber {
6
+ public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
7
+ if let screenOrientationRegistry = ModuleRegistryProvider.getSingletonModule(for: EXScreenOrientationRegistry.self) as? EXScreenOrientationRegistry {
8
+ screenOrientationRegistry.updateCurrentScreenOrientation()
9
+ }
10
+ return true
11
+ }
12
+ }
@@ -0,0 +1,9 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesCore
4
+
5
+ public class ScreenOrientationReactDelegateHandler: ExpoReactDelegateHandler {
6
+ public override func createRootViewController(reactDelegate: ExpoReactDelegate) -> UIViewController? {
7
+ return EXScreenOrientationViewController(defaultScreenOrientationFromPlist: ());
8
+ }
9
+ }
@@ -11,16 +11,22 @@ Pod::Spec.new do |s|
11
11
  s.author = package['author']
12
12
  s.homepage = package['homepage']
13
13
  s.platform = :ios, '12.0'
14
+ s.swift_version = '5.4'
14
15
  s.source = { git: 'https://github.com/expo/expo.git' }
15
16
  s.static_framework = true
16
17
 
17
18
  s.dependency 'ExpoModulesCore'
18
19
  s.dependency 'React-Core'
19
20
 
21
+ # Swift/Objective-C compatibility
22
+ s.pod_target_xcconfig = {
23
+ 'DEFINES_MODULE' => 'YES'
24
+ }
25
+
20
26
  if !$ExpoUseSources&.include?(package['name']) && ENV['EXPO_USE_SOURCE'].to_i == 0 && File.exist?("#{s.name}.xcframework") && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
21
27
  s.source_files = "#{s.name}/**/*.h"
22
28
  s.vendored_frameworks = "#{s.name}.xcframework"
23
29
  else
24
- s.source_files = "#{s.name}/**/*.{h,m}"
30
+ s.source_files = "#{s.name}/**/*.{h,m,swift}"
25
31
  end
26
32
  end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-screen-orientation",
3
- "version": "4.0.0",
3
+ "version": "4.1.0",
4
4
  "description": "Expo universal module for managing device's screen orientation",
5
5
  "main": "build/ScreenOrientation.js",
6
6
  "types": "build/ScreenOrientation.d.ts",
@@ -36,11 +36,13 @@
36
36
  "preset": "expo-module-scripts"
37
37
  },
38
38
  "dependencies": {
39
- "@expo/config-plugins": "^3.1.0",
40
- "expo-modules-core": "~0.4.0"
39
+ "@expo/config-plugins": "^4.0.2"
41
40
  },
42
41
  "devDependencies": {
43
42
  "expo-module-scripts": "^2.0.0"
44
43
  },
45
- "gitHead": "1fffde73411ee7a642b98f1506a8de921805d52b"
44
+ "peerDependencies": {
45
+ "expo": "*"
46
+ },
47
+ "gitHead": "2e5c6983b86d5ecfca028ba64002897d8adc2cc4"
46
48
  }
@@ -1,5 +1,22 @@
1
- import { ConfigPlugin } from '@expo/config-plugins';
2
- export declare function modifyObjcAppDelegate(contents: string, mask: string): string;
1
+ import { ConfigPlugin, InfoPlist } from '@expo/config-plugins';
2
+ import { ExpoConfig } from '@expo/config-types';
3
+ export declare const INITIAL_ORIENTATION_KEY = "EXDefaultScreenOrientationMask";
4
+ declare const OrientationLock: {
5
+ DEFAULT: string;
6
+ ALL: string;
7
+ PORTRAIT: string;
8
+ PORTRAIT_UP: string;
9
+ PORTRAIT_DOWN: string;
10
+ LANDSCAPE: string;
11
+ LANDSCAPE_LEFT: string;
12
+ LANDSCAPE_RIGHT: string;
13
+ };
14
+ declare type OrientationMasks = keyof typeof OrientationLock;
15
+ interface ExpoConfigWithInitialOrientation extends ExpoConfig {
16
+ initialOrientation?: OrientationMasks;
17
+ }
18
+ export declare function getInitialOrientation(config: Pick<ExpoConfigWithInitialOrientation, 'initialOrientation'>): OrientationMasks;
19
+ export declare function setInitialOrientation(config: Pick<ExpoConfigWithInitialOrientation, 'initialOrientation'>, infoPlist: InfoPlist): InfoPlist;
3
20
  declare const _default: ConfigPlugin<void | {
4
21
  initialOrientation?: "DEFAULT" | "ALL" | "PORTRAIT" | "PORTRAIT_UP" | "PORTRAIT_DOWN" | "LANDSCAPE" | "LANDSCAPE_LEFT" | "LANDSCAPE_RIGHT" | undefined;
5
22
  }>;
@@ -3,11 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.modifyObjcAppDelegate = void 0;
6
+ exports.setInitialOrientation = exports.getInitialOrientation = exports.INITIAL_ORIENTATION_KEY = void 0;
7
7
  const config_plugins_1 = require("@expo/config-plugins");
8
8
  const assert_1 = __importDefault(require("assert"));
9
- const fs_1 = __importDefault(require("fs"));
10
9
  const pkg = require('expo-screen-orientation/package.json');
10
+ // This value must match the `EXDefaultScreenOrientationMask` string used in `expo-screen-orientation/ios/EXScreenOrientation/EXScreenOrientationViewController.m` (do not change).
11
+ exports.INITIAL_ORIENTATION_KEY = 'EXDefaultScreenOrientationMask';
11
12
  const OrientationLock = {
12
13
  DEFAULT: 'UIInterfaceOrientationMaskAllButUpsideDown',
13
14
  ALL: 'UIInterfaceOrientationMaskAll',
@@ -18,36 +19,32 @@ const OrientationLock = {
18
19
  LANDSCAPE_LEFT: 'UIInterfaceOrientationMaskLandscapeLeft',
19
20
  LANDSCAPE_RIGHT: 'UIInterfaceOrientationMaskLandscapeRight',
20
21
  };
21
- function modifyObjcAppDelegate(contents, mask) {
22
- // Add import
23
- if (!contents.includes('#import <EXScreenOrientation/EXScreenOrientationViewController.h>')) {
24
- contents = contents.replace(/#import "AppDelegate.h"/g, `#import "AppDelegate.h"
25
- #import <EXScreenOrientation/EXScreenOrientationViewController.h>`);
22
+ const withScreenOrientationViewController = (config, { initialOrientation = 'DEFAULT' } = {}) => {
23
+ config = (0, config_plugins_1.withInfoPlist)(config, (config) => {
24
+ const extendedConfig = {
25
+ ...config,
26
+ initialOrientation,
27
+ };
28
+ config.modResults = setInitialOrientation(extendedConfig, config.modResults);
29
+ return config;
30
+ });
31
+ return config;
32
+ };
33
+ function getInitialOrientation(config) {
34
+ var _a;
35
+ return (_a = config.initialOrientation) !== null && _a !== void 0 ? _a : 'DEFAULT';
36
+ }
37
+ exports.getInitialOrientation = getInitialOrientation;
38
+ function setInitialOrientation(config, infoPlist) {
39
+ const initialOrientation = getInitialOrientation(config);
40
+ (0, assert_1.default)(initialOrientation in OrientationLock, `Invalid initial orientation "${initialOrientation}" expected one of: ${Object.keys(OrientationLock).join(', ')}`);
41
+ if (initialOrientation === 'DEFAULT') {
42
+ delete infoPlist[exports.INITIAL_ORIENTATION_KEY];
26
43
  }
27
- // Change View Controller
28
- if (!contents.includes('[EXScreenOrientationViewController alloc]')) {
29
- contents = contents.replace(/UIViewController\s?\*\s?rootViewController\s?=\s?\[UIViewController new\];/g, `UIViewController *rootViewController = [[EXScreenOrientationViewController alloc] initWithDefaultScreenOrientationMask:${mask}];`);
44
+ else {
45
+ infoPlist[exports.INITIAL_ORIENTATION_KEY] = OrientationLock[initialOrientation];
30
46
  }
31
- return contents;
47
+ return infoPlist;
32
48
  }
33
- exports.modifyObjcAppDelegate = modifyObjcAppDelegate;
34
- const withScreenOrientationViewController = (config, { initialOrientation = 'DEFAULT' } = {}) => {
35
- assert_1.default(initialOrientation in OrientationLock, `Invalid initial orientation "${initialOrientation}" expected one of: ${Object.keys(OrientationLock).join(', ')}`);
36
- return config_plugins_1.withDangerousMod(config, [
37
- 'ios',
38
- async (config) => {
39
- const fileInfo = config_plugins_1.IOSConfig.Paths.getAppDelegate(config.modRequest.projectRoot);
40
- let contents = fs_1.default.readFileSync(fileInfo.path, { encoding: 'utf-8' });
41
- if (fileInfo.language === 'objc') {
42
- contents = modifyObjcAppDelegate(contents, OrientationLock[initialOrientation]);
43
- }
44
- else {
45
- // TODO: Support Swift
46
- throw new Error(`Cannot append screen orientation view controller to AppDelegate of language "${fileInfo.language}"`);
47
- }
48
- fs_1.default.writeFileSync(fileInfo.path, contents);
49
- return config;
50
- },
51
- ]);
52
- };
53
- exports.default = config_plugins_1.createRunOncePlugin(withScreenOrientationViewController, pkg.name, pkg.version);
49
+ exports.setInitialOrientation = setInitialOrientation;
50
+ exports.default = (0, config_plugins_1.createRunOncePlugin)(withScreenOrientationViewController, pkg.name, pkg.version);
@@ -1,14 +1,12 @@
1
- import {
2
- ConfigPlugin,
3
- createRunOncePlugin,
4
- IOSConfig,
5
- withDangerousMod,
6
- } from '@expo/config-plugins';
1
+ import { ConfigPlugin, createRunOncePlugin, InfoPlist, withInfoPlist } from '@expo/config-plugins';
2
+ import { ExpoConfig } from '@expo/config-types';
7
3
  import assert from 'assert';
8
- import fs from 'fs';
9
4
 
10
5
  const pkg = require('expo-screen-orientation/package.json');
11
6
 
7
+ // This value must match the `EXDefaultScreenOrientationMask` string used in `expo-screen-orientation/ios/EXScreenOrientation/EXScreenOrientationViewController.m` (do not change).
8
+ export const INITIAL_ORIENTATION_KEY = 'EXDefaultScreenOrientationMask';
9
+
12
10
  const OrientationLock = {
13
11
  DEFAULT: 'UIInterfaceOrientationMaskAllButUpsideDown',
14
12
  ALL: 'UIInterfaceOrientationMaskAll',
@@ -20,29 +18,39 @@ const OrientationLock = {
20
18
  LANDSCAPE_RIGHT: 'UIInterfaceOrientationMaskLandscapeRight',
21
19
  };
22
20
 
23
- export function modifyObjcAppDelegate(contents: string, mask: string): string {
24
- // Add import
25
- if (!contents.includes('#import <EXScreenOrientation/EXScreenOrientationViewController.h>')) {
26
- contents = contents.replace(
27
- /#import "AppDelegate.h"/g,
28
- `#import "AppDelegate.h"
29
- #import <EXScreenOrientation/EXScreenOrientationViewController.h>`
30
- );
31
- }
21
+ type OrientationMasks = keyof typeof OrientationLock;
32
22
 
33
- // Change View Controller
34
- if (!contents.includes('[EXScreenOrientationViewController alloc]')) {
35
- contents = contents.replace(
36
- /UIViewController\s?\*\s?rootViewController\s?=\s?\[UIViewController new\];/g,
37
- `UIViewController *rootViewController = [[EXScreenOrientationViewController alloc] initWithDefaultScreenOrientationMask:${mask}];`
38
- );
39
- }
40
- return contents;
23
+ // `initialOrientation` is not public in expo config yet, we just use it as an internal type.
24
+ interface ExpoConfigWithInitialOrientation extends ExpoConfig {
25
+ initialOrientation?: OrientationMasks;
41
26
  }
42
27
 
43
28
  const withScreenOrientationViewController: ConfigPlugin<{
44
29
  initialOrientation?: keyof typeof OrientationLock;
45
30
  } | void> = (config, { initialOrientation = 'DEFAULT' } = {}) => {
31
+ config = withInfoPlist(config, (config) => {
32
+ const extendedConfig = {
33
+ ...config,
34
+ initialOrientation,
35
+ };
36
+ config.modResults = setInitialOrientation(extendedConfig, config.modResults);
37
+ return config;
38
+ });
39
+ return config;
40
+ };
41
+
42
+ export function getInitialOrientation(
43
+ config: Pick<ExpoConfigWithInitialOrientation, 'initialOrientation'>
44
+ ): OrientationMasks {
45
+ return config.initialOrientation ?? 'DEFAULT';
46
+ }
47
+
48
+ export function setInitialOrientation(
49
+ config: Pick<ExpoConfigWithInitialOrientation, 'initialOrientation'>,
50
+ infoPlist: InfoPlist
51
+ ): InfoPlist {
52
+ const initialOrientation = getInitialOrientation(config);
53
+
46
54
  assert(
47
55
  initialOrientation in OrientationLock,
48
56
  `Invalid initial orientation "${initialOrientation}" expected one of: ${Object.keys(
@@ -50,24 +58,12 @@ const withScreenOrientationViewController: ConfigPlugin<{
50
58
  ).join(', ')}`
51
59
  );
52
60
 
53
- return withDangerousMod(config, [
54
- 'ios',
55
- async (config) => {
56
- const fileInfo = IOSConfig.Paths.getAppDelegate(config.modRequest.projectRoot);
57
- let contents = fs.readFileSync(fileInfo.path, { encoding: 'utf-8' });
58
- if (fileInfo.language === 'objc') {
59
- contents = modifyObjcAppDelegate(contents, OrientationLock[initialOrientation]);
60
- } else {
61
- // TODO: Support Swift
62
- throw new Error(
63
- `Cannot append screen orientation view controller to AppDelegate of language "${fileInfo.language}"`
64
- );
65
- }
66
- fs.writeFileSync(fileInfo.path, contents);
67
-
68
- return config;
69
- },
70
- ]);
71
- };
61
+ if (initialOrientation === 'DEFAULT') {
62
+ delete infoPlist[INITIAL_ORIENTATION_KEY];
63
+ } else {
64
+ infoPlist[INITIAL_ORIENTATION_KEY] = OrientationLock[initialOrientation];
65
+ }
66
+ return infoPlist;
67
+ }
72
68
 
73
69
  export default createRunOncePlugin(withScreenOrientationViewController, pkg.name, pkg.version);
@@ -114,17 +114,20 @@ export enum WebOrientation {
114
114
  // @needsAudit
115
115
  export type PlatformOrientationInfo = {
116
116
  /**
117
- * __Android Only.__ A constant to set using the Android native [API](https://developer.android.com/reference/android/R.attr.html#screenOrientation).
117
+ * A constant to set using the Android native [API](https://developer.android.com/reference/android/R.attr.html#screenOrientation).
118
118
  * For example, in order to set the lock policy to [unspecified](https://developer.android.com/reference/android/content/pm/ActivityInfo.html#SCREEN_ORIENTATION_UNSPECIFIED),
119
119
  * `-1` should be passed in.
120
+ * @platform android
120
121
  */
121
122
  screenOrientationConstantAndroid?: number;
122
123
  /**
123
- * __iOS Only.__ An array of orientations to allow on the iOS platform.
124
+ * An array of orientations to allow on the iOS platform.
125
+ * @platform ios
124
126
  */
125
127
  screenOrientationArrayIOS?: Orientation[];
126
128
  /**
127
- * __Web Only.__ A web orientation lock to apply in the browser.
129
+ * A web orientation lock to apply in the browser.
130
+ * @platform web
128
131
  */
129
132
  screenOrientationLockWeb?: WebOrientationLock;
130
133
  };
@@ -136,13 +139,15 @@ export type ScreenOrientationInfo = {
136
139
  */
137
140
  orientation: Orientation;
138
141
  /**
139
- * __iOS Only.__ The [vertical size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)
142
+ * The [vertical size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)
140
143
  * of the device.
144
+ * @platform ios
141
145
  */
142
146
  verticalSizeClass?: SizeClassIOS;
143
147
  /**
144
- * __iOS Only.__ The [horizontal size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)
148
+ * The [horizontal size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html)
145
149
  * of the device.
150
+ * @platform ios
146
151
  */
147
152
  horizontalSizeClass?: SizeClassIOS;
148
153
  };
package/unimodule.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "name": "expo-screen-orientation",
3
- "platforms": ["ios", "android"]
4
- }