diff --git a/.flowconfig b/.flowconfig index 7e73a16a3d1..81c191a8e78 100644 --- a/.flowconfig +++ b/.flowconfig @@ -54,6 +54,7 @@ flow-typed/@sentry/react-native_v1.x.x.js flow-typed/@react-native-community/async-storage_v1.x.x.js flow-typed/react-native-webview_v7.x.x.js flow-typed/react-native-url-polyfill_vx.x.x.js +flow-typed/expo-screen-orientation_vx.x.x.js [strict] diff --git a/android/app/src/main/java/com/zulipmobile/generated/BasePackageList.java b/android/app/src/main/java/com/zulipmobile/generated/BasePackageList.java index 57656636426..029defc71d1 100644 --- a/android/app/src/main/java/com/zulipmobile/generated/BasePackageList.java +++ b/android/app/src/main/java/com/zulipmobile/generated/BasePackageList.java @@ -10,7 +10,8 @@ public List getPackageList() { new expo.modules.application.ApplicationPackage(), new expo.modules.constants.ConstantsPackage(), new expo.modules.filesystem.FileSystemPackage(), - new expo.modules.permissions.PermissionsPackage() + new expo.modules.permissions.PermissionsPackage(), + new expo.modules.screenorientation.ScreenOrientationPackage() ); } } diff --git a/flow-typed/expo-screen-orientation_vx.x.x.js b/flow-typed/expo-screen-orientation_vx.x.x.js new file mode 100644 index 00000000000..c60059519af --- /dev/null +++ b/flow-typed/expo-screen-orientation_vx.x.x.js @@ -0,0 +1,117 @@ +// Assembled with help from Flowgen v1.10.0. +// +// The modules 'expo-screen-orientation/build/ScreenOrientation' and +// 'expo-screen-orientation/build/ScreenOrientation.types' are the +// result of passing those files in node_modules through Flowgen and +// doing some minor syntactic tweaks. + +declare module 'expo-screen-orientation/build/ScreenOrientation' { + // We can't import Subscription; see + // https://github.com/flow-typed/flow-typed/blob/master/CONTRIBUTING.md#dont-import-types-from-other-libdefs + // + // So, copy it here (it's small). + // https://github.com/expo/expo/blob/master/packages/%40unimodules/react-native-adapter/src/EventEmitter.ts#L13-L15 + declare type Subscription = { + remove: () => void, + }; + + import typeof { + Orientation, + OrientationLock, + SizeClassIOS, + WebOrientation, + WebOrientationLock, + } from 'expo-screen-orientation/build/ScreenOrientation.types'; + import type { + OrientationChangeEvent, + OrientationChangeListener, + PlatformOrientationInfo, + ScreenOrientationInfo, + } from 'expo-screen-orientation/build/ScreenOrientation.types'; + + declare export function lockAsync(orientationLock: OrientationLock): Promise; + declare export function lockPlatformAsync(options: PlatformOrientationInfo): Promise; + declare export function unlockAsync(): Promise; + declare export function getOrientationAsync(): Promise; + declare export function getOrientationLockAsync(): Promise; + declare export function getPlatformOrientationLockAsync(): Promise; + declare export function supportsOrientationLockAsync( + orientationLock: OrientationLock, + ): Promise; + declare export function addOrientationChangeListener( + listener: OrientationChangeListener, + ): Subscription; + declare export function removeOrientationChangeListeners(): void; + declare export function removeOrientationChangeListener(subscription: Subscription): void; +} + +declare module 'expo-screen-orientation/build/ScreenOrientation.types' { + declare export var Orientation: {| + +UNKNOWN: 0, // 0 + +PORTRAIT_UP: 1, // 1 + +PORTRAIT_DOWN: 2, // 2 + +LANDSCAPE_LEFT: 3, // 3 + +LANDSCAPE_RIGHT: 4, // 4 + |}; + + declare export var OrientationLock: {| + +DEFAULT: 0, // 0 + +ALL: 1, // 1 + +PORTRAIT: 2, // 2 + +PORTRAIT_UP: 3, // 3 + +PORTRAIT_DOWN: 4, // 4 + +LANDSCAPE: 5, // 5 + +LANDSCAPE_LEFT: 6, // 6 + +LANDSCAPE_RIGHT: 7, // 7 + +OTHER: 8, // 8 + +UNKNOWN: 9, // 9 + |}; + + declare export var SizeClassIOS: {| + +REGULAR: 0, // 0 + +COMPACT: 1, // 1 + +UNKNOWN: 2, // 2 + |}; + + declare export var WebOrientationLock: {| + +PORTRAIT_PRIMARY: 'portrait-primary', // "portrait-primary" + +PORTRAIT_SECONDARY: 'portrait-secondary', // "portrait-secondary" + +PORTRAIT: 'portrait', // "portrait" + +LANDSCAPE_PRIMARY: 'landscape-primary', // "landscape-primary" + +LANDSCAPE_SECONDARY: 'landscape-secondary', // "landscape-secondary" + +LANDSCAPE: 'landscape', // "landscape" + +ANY: 'any', // "any" + +NATURAL: 'natural', // "natural" + +UNKNOWN: 'unknown', // "unknown" + |}; + + declare export var WebOrientation: {| + +PORTRAIT_PRIMARY: 'portrait-primary', // "portrait-primary" + +PORTRAIT_SECONDARY: 'portrait-secondary', // "portrait-secondary" + +LANDSCAPE_PRIMARY: 'landscape-primary', // "landscape-primary" + +LANDSCAPE_SECONDARY: 'landscape-secondary', // "landscape-secondary" + |}; + declare export type PlatformOrientationInfo = { + screenOrientationConstantAndroid?: number, + screenOrientationArrayIOS?: $Values[], + screenOrientationLockWeb?: $Values, + ... + }; + declare export type ScreenOrientationInfo = { + orientation: $Values, + verticalSizeClass?: $Values, + horizontalSizeClass?: $Values, + ... + }; + declare export type OrientationChangeListener = (event: OrientationChangeEvent) => void; + declare export type OrientationChangeEvent = { + orientationLock: $Values, + orientationInfo: ScreenOrientationInfo, + ... + }; +} + +declare module 'expo-screen-orientation' { + declare export * from 'expo-screen-orientation/build/ScreenOrientation' + declare export * from 'expo-screen-orientation/build/ScreenOrientation.types' +} diff --git a/flow-typed/npm/react-native-orientation_v3.x.x.js b/flow-typed/npm/react-native-orientation_v3.x.x.js deleted file mode 100644 index e04b677d931..00000000000 --- a/flow-typed/npm/react-native-orientation_v3.x.x.js +++ /dev/null @@ -1,38 +0,0 @@ -// flow-typed signature: f052bc3c508312d9a9f76d42d122cc0e -// flow-typed version: c6154227d1/react-native-orientation_v3.x.x/flow_>=v0.68.0 <=v0.103.x - -declare module "react-native-orientation" { - declare export type Orientations = - | "LANDSCAPE" - | "PORTRAIT" - | "PORTRAITUPSIDEDOWN" - | "UNKNOWN"; - - declare export type SpecificOrientations = - | "LANDSCAPE-LEFT" - | "LANDSCAPE-RIGHT" - | "PORTRAIT" - | "PORTRAITUPSIDEDOWN" - | "UNKNOWN"; - - declare module.exports: { - getInitialOrientation(): ?Orientations, - getOrientation((error: ?Error, payload?: Orientations) => void): void, - getSpecificOrientation( - (error: ?Error, payload?: SpecificOrientations) => void - ): void, - lockToPortrait(): void, - lockToLandscape(): void, - lockToLandscapeRight(): void, - lockToLandscapeLeft(): void, - unlockAllOrientations(): void, - addOrientationListener((payload?: Orientations) => void): void, - removeOrientationListener((payload?: Orientations) => void): void, - addSpecificOrientationListener( - (payload?: SpecificOrientations) => void - ): void, - removeSpecificOrientationListener( - (payload?: SpecificOrientations) => void - ): void - }; -} diff --git a/ios/Podfile.lock b/ios/Podfile.lock index a6ccce92032..285932a816a 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -13,6 +13,9 @@ PODS: - EXPermissions (7.0.0): - UMCore - UMPermissionsInterface + - EXScreenOrientation (1.0.0): + - React-Core + - UMCore - Folly (2018.10.22.00): - boost-for-react-native - DoubleConversion @@ -74,8 +77,6 @@ PODS: - React - react-native-notifications (1.5.0): - React - - react-native-orientation (3.1.3): - - React - react-native-photo-view (1.5.2): - React - react-native-safari-view (1.0.0): @@ -112,7 +113,7 @@ PODS: - React-Core (= 0.60.6) - React-RCTWebSocket (0.60.6): - React-Core (= 0.60.6) - - rn-fetch-blob (0.10.16): + - rn-fetch-blob (0.11.2): - React-Core - RNCAsyncStorage (1.6.3): - React @@ -156,6 +157,7 @@ DEPENDENCIES: - EXConstants (from `../node_modules/expo-constants/ios`) - EXFileSystem (from `../node_modules/expo-file-system/ios`) - EXPermissions (from `../node_modules/expo-permissions/ios`) + - EXScreenOrientation (from `../node_modules/expo-screen-orientation/ios`) - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - React (from `../node_modules/react-native/`) @@ -168,7 +170,6 @@ DEPENDENCIES: - react-native-image-picker (from `../node_modules/react-native-image-picker`) - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-notifications (from `../node_modules/react-native-notifications`) - - react-native-orientation (from `../node_modules/react-native-orientation`) - react-native-photo-view (from `../node_modules/react-native-photo-view`) - react-native-safari-view (from `../node_modules/react-native-safari-view`) - react-native-safe-area (from `../node_modules/react-native-safe-area`) @@ -229,6 +230,9 @@ EXTERNAL SOURCES: EXPermissions: :path: !ruby/object:Pathname path: "../node_modules/expo-permissions/ios" + EXScreenOrientation: + :path: !ruby/object:Pathname + path: "../node_modules/expo-screen-orientation/ios" Folly: :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec" glog: @@ -253,8 +257,6 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/netinfo" react-native-notifications: :path: "../node_modules/react-native-notifications" - react-native-orientation: - :path: "../node_modules/react-native-orientation" react-native-photo-view: :path: "../node_modules/react-native-photo-view" react-native-safari-view: @@ -346,6 +348,7 @@ SPEC CHECKSUMS: EXConstants: 857aa7b1c84e2878f8402d712061860bca16a697 EXFileSystem: 7e53a2c30a2eb6987ba6d5158ab908f947523228 EXPermissions: df10ad83df2f6b647aec304619354f8ab48d5f63 + EXScreenOrientation: 44d3cd3a99a86b9cb681e742697bc2c057d7fbd2 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 React: 68e7f8dfc27729eade18423072a143120f2f32ab @@ -358,7 +361,6 @@ SPEC CHECKSUMS: react-native-image-picker: 3693786b3d5958c8f71deed66ec068b323565e0d react-native-netinfo: 0da34082d2cec3100c9b5073bb217e35f1142bdd react-native-notifications: ce37363008fe2d6a226da4e721eace23b6ae3ad9 - react-native-orientation: f1caf84d65f1a4fd4511a18f2b924e634ad7a628 react-native-photo-view: 63e9e61da873531f931008b545d8d10c5373ddf8 react-native-safari-view: 955d7160d159241b8e9395d12d10ea0ef863dcdd react-native-safe-area: 5fce5242419932bc05656f31bc5f0716e30be0f6 @@ -375,7 +377,7 @@ SPEC CHECKSUMS: React-RCTText: d91537e29e38dc69cf09cbca0875cf5dc7402da6 React-RCTVibration: 7655d72dfb919dd6d8e135ca108a5a2bd9fcd7b4 React-RCTWebSocket: 7cd2c8d0f8ddd680dc76404defba7ab1f56b83af - rn-fetch-blob: 651b8d076b43d0d7aa294a3d9ec16c00aab8bef9 + rn-fetch-blob: f525a73a78df9ed5d35e67ea65e79d53c15255bc RNCAsyncStorage: 3c304d1adfaea02ec732ac218801cb13897aa8c0 RNDeviceInfo: e7c5fcde13d40e161d8a27f6c5dc69c638936002 RNSentry: 2803ba8c8129dcf26b79e9b4d8c80168be6e4390 diff --git a/ios/ZulipMobile/AppDelegate.m b/ios/ZulipMobile/AppDelegate.m index e5d08382f92..1c393feaf6f 100644 --- a/ios/ZulipMobile/AppDelegate.m +++ b/ios/ZulipMobile/AppDelegate.m @@ -20,6 +20,7 @@ #import #import #import +#import @implementation AppDelegate @@ -36,7 +37,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [UIViewController new]; + UIViewController *rootViewController = [[EXScreenOrientationViewController alloc] initWithDefaultScreenOrientationMask:UIInterfaceOrientationMaskAll]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; diff --git a/package.json b/package.json index 3eadd9dcc81..b72ae0afcf2 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "color": "^3.0.0", "date-fns": "^1.29.0", "expo-application": "^2.1.1", + "expo-screen-orientation": "^1.0.0", "immutable": "^4.0.0-rc.12", "json-stringify-safe": "^5.0.1", "katex": "^0.11.1", @@ -59,7 +60,6 @@ "react-native-document-picker": "^3.2.4", "react-native-image-picker": "^0.26.10", "react-native-notifications": "^1.2.0", - "react-native-orientation": "^3.1.3", "react-native-photo-view": "alwx/react-native-photo-view#c58fd6b30", "react-native-safari-view": "2.0.0", "react-native-safe-area": "^0.4.1", @@ -82,7 +82,7 @@ "redux-thunk": "^2.1.0", "remotedev-serialize": "zulip/remotedev-serialize#5f9f759a4", "reselect": "^3.0.1", - "rn-fetch-blob": "^0.10.16", + "rn-fetch-blob": "^0.11.0", "string.fromcodepoint": "^0.2.1", "timezone": "^1.0.13", "url-parse": "^1.4.0", diff --git a/src/boot/AppEventHandlers.js b/src/boot/AppEventHandlers.js index 87575c0a6aa..ef4230a764a 100644 --- a/src/boot/AppEventHandlers.js +++ b/src/boot/AppEventHandlers.js @@ -4,7 +4,7 @@ import React, { PureComponent } from 'react'; import { AppState, View, StyleSheet, Platform, NativeModules } from 'react-native'; import NetInfo from '@react-native-community/netinfo'; import SafeArea from 'react-native-safe-area'; -import Orientation from 'react-native-orientation'; +import * as ScreenOrientation from 'expo-screen-orientation'; import type { Node as React$Node } from 'react'; import type { Dispatch, Orientation as OrientationT } from '../types'; @@ -69,13 +69,28 @@ type Props = $ReadOnly<{| unreadCount: number, |}>; +type OrientationLookup = {| + [expoKey: $Values]: OrientationT, +|}; + +const orientationLookup: OrientationLookup = { + [ScreenOrientation.Orientation.UNKNOWN]: 'PORTRAIT', + [ScreenOrientation.Orientation.PORTRAIT_UP]: 'PORTRAIT', + [ScreenOrientation.Orientation.PORTRAIT_DOWN]: 'PORTRAIT', + [ScreenOrientation.Orientation.LANDSCAPE_LEFT]: 'LANDSCAPE', + [ScreenOrientation.Orientation.LANDSCAPE_RIGHT]: 'LANDSCAPE', +}; + class AppEventHandlers extends PureComponent { /** NetInfo disconnection callback. */ netInfoDisconnectCallback: (() => void) | null = null; - handleOrientationChange = (orientation: OrientationT) => { + handleOrientationChange = (event: ScreenOrientation.OrientationChangeEvent) => { const { dispatch } = this.props; - dispatch(appOrientation(orientation)); + + const { orientation } = event.orientationInfo; + + dispatch(appOrientation(orientationLookup[orientation])); }; // https://github.com/react-native-community/react-native-netinfo/tree/v3.2.1 @@ -113,8 +128,7 @@ class AppEventHandlers extends PureComponent { SafeArea.getSafeAreaInsetsForRootView().then(params => dispatch(initSafeAreaInsets(params.safeAreaInsets)), ); - // $FlowFixMe: libdef wrongly says callback's parameter is optional - Orientation.addOrientationListener(this.handleOrientationChange); + ScreenOrientation.addOrientationChangeListener(this.handleOrientationChange); this.notificationListener.start(); } @@ -125,8 +139,7 @@ class AppEventHandlers extends PureComponent { } AppState.removeEventListener('change', this.handleAppStateChange); AppState.removeEventListener('memoryWarning', this.handleMemoryWarning); - // $FlowFixMe: libdef wrongly says callback's parameter is optional - Orientation.removeOrientationListener(this.handleOrientationChange); + ScreenOrientation.removeOrientationChangeListeners(); this.notificationListener.stop(); } diff --git a/yarn.lock b/yarn.lock index 82941e16cf9..cce3023a5b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3737,6 +3737,11 @@ expo-permissions@~7.0.0: resolved "https://registry.yarnpkg.com/expo-permissions/-/expo-permissions-7.0.0.tgz#f4135c3cf8e49c673a9a714459a1eb2b40fe2092" integrity sha512-C+qyVz+pdZO4YpVR2HSC3gsBZg0Qb8brCFgzmDmWcAtgrOiHClaLPdhI2XtQuGh8ubXcKPUGZp++UCEGiG0Jxg== +expo-screen-orientation@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/expo-screen-orientation/-/expo-screen-orientation-1.0.0.tgz#a168b7493e7a7b45da2c80b1b0d4e89e1f8e7698" + integrity sha512-McYHWSA3KVgh3IeztKg0oxkHtSRzDfqGRSHg6GgIici5C93LOF4tGzO38tLNVGXIjbu8EdvBRB7pslKS73AXGg== + extend-shallow@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" @@ -7956,11 +7961,6 @@ react-native-notifications@^1.2.0: core-js "^1.0.0" uuid "^2.0.3" -react-native-orientation@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/react-native-orientation/-/react-native-orientation-3.1.3.tgz#d45803841fe94b6cce9acbe904fd5ca191a3711e" - integrity sha512-A0h0E+2f95X4avmhaBG1ZT8WDxBACA/q//JN2eF1E7kq8AJVxt5XDiavv+aSBkBlqFsfF3bIS+T/DB5mXmnxuA== - react-native-photo-view@alwx/react-native-photo-view#c58fd6b30: version "1.5.2" resolved "https://codeload.github.com/alwx/react-native-photo-view/tar.gz/c58fd6b30d627fa23e39520d4fc3325ade8b0a51" @@ -8600,10 +8600,10 @@ rimraf@~2.2.6: resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" integrity sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI= -rn-fetch-blob@^0.10.16: - version "0.10.16" - resolved "https://registry.yarnpkg.com/rn-fetch-blob/-/rn-fetch-blob-0.10.16.tgz#bd54f66c94f7a8e06c213077483646478ae8d230" - integrity sha512-hZV+nF0HK4CWmspXGMw7/G8Q8qugpS/wbKiNLsFpdBZR8XYzjFZNvBWgGyC0F5JWQn3sjmK2w/FJjBlwdQWNQg== +rn-fetch-blob@^0.11.0: + version "0.11.2" + resolved "https://registry.yarnpkg.com/rn-fetch-blob/-/rn-fetch-blob-0.11.2.tgz#bdc483bf1b0c3810d457983494a11fbada446679" + integrity sha512-oKszdNtA7vZ56d0Rfr+RDEUexwlZxu/HOqwULa36PRHhQsTO5ia7uKk+va3WzuwYxzhF9e0bY8n3k+GC6Df14A== dependencies: base-64 "0.1.0" glob "7.0.6"